Sunday, August 29, 2021

Elisp: Lambda functions in a lexical environment

;; Enable lexical bindings
(setq lexical-binding t)

;; In a lexically scoped environment lambda functions evaluates to
;; closures objects. Closures are functions that capture the lexical
;; environment where they are defined. The lexical environment is
;; captured in an alist terminated by 't'. See below.

;; Let's define an high order functions that returns a lambda (a
;; closure). Every time the lambda is funcall-ed it returns an
;; incremented integer (remembering the previous value):

(defun incrementer (x)
  (lambda ()
    (setq x
          (1+ x))) ; The lambda evaluate to a closure => (closure (t) nil (setq x (1+ x)))
  )


;; Let's create an incrementer starting from 1
(setq inc-from-1 (incrementer 0)) ; => (closure ((x . 0) t) nil (setq x (1+ x)))


(funcall inc-from-1) ; => 1
(funcall inc-from-1) ; => 2

;; Thanks to the homiconicity of Lisp, a closure object can be
;; manipulated as a regular list during runtime and the captured
;; environment can be modified:

;; Let's modify the closure and jump the incrementer to 100 directly:
(setf (caadr inc-from-1) '(x . 100))

(funcall inc-from-1) ; => 101

Author: Davide Restivo

Created: 2021-08-29 Sun 18:52

Validate

Friday, January 1, 2021

Enable ERC notifications on macOS

1 Enable ERC notifications on macOS

A quick post on how to enable ERC notification on macOS via Notification Center using AppleScript:

;; Send notification using Apple Script on macOS
(defun galactic-emacs-erc-ns-notify (nick msg &optional PRIVP)
  "Notify that NICK send a MSG using Apple Notification Center"
  (ns-do-applescript (concat "display notification \"" nick
                             " wrote: " msg "\"" "with title"
                             "\"ERC Notification\"")))
;; Desktop notifications
(require 'erc-desktop-notifications)
(erc-notifications-enable)
;; Use Notification Center on macOS
(when (string= system-type "darwin")
  (advice-add 'erc-notifications-notify :after #'galactic-emacs-erc-ns-notify))

Sunday, November 8, 2020

Multi-Arity Multi-Methods

Q: Is it possible to overload Clojure multi-methods on arity?
A: Yes. Below a code example

(def u1 {:name "bob"  :company "Facebook" :salary 100000})
(def u2 {:name "jane" :company "Google"   :salary 150000})
(def u3 {:name "mike" :company "Other"    :salary 160000})

(defmulti tm (fn [user & etc] (:company user)))

(defmethod tm "Google"   [user] "Google user")
(defmethod tm "Facebook" [user] "Facebook user")

(defmethod tm "Other"
  ([user]             "Other user with one argument")
  ([user y]           "Other user with two argument")
  ([user y & etc] "Other user with many arguments"))

;; (tm u1)
;; "Facebook user"

;; (tm u2)
;; "Google user"

;; (tm u3)
;; "Other user with one argument"

;; (tm u3 1)
;; "Other user with two argument"

;; (tm u3 1 3)
;; "Other user with many arguments"

Sunday, December 15, 2019

Midnight Commander Cheat Sheet

Midnight Commander Cheat Sheet

1 General

On modern keyboards instead of [META] both [ALT] and [ESC] can be used.

Shortcut Description
TAB Jump from one panel to the other
C-u Swap panels
C-r Refresh current pane
C-l Redraw current pane
C-\ Show the directory Hotlist
C-SPACE Show current directory size
M-i Make the other panel show the same directory as the active panel
M-c Quick cd dialog
M-? Search dialog
M-. Toggle "Show Hidden Files" feature
M-, Switch MC layout from left-right to top-bottom
M-t Change panel listing mode: standard, brief, full
M-o Load the directory under the cursor on the other
  panel and move the selection to the next one in the current panel
M-SHIFT-h Show the directory history
M-y Move to the previous directory in the directory history
M-u Move to the next directory in the directory history
SHIFT-F4 Create new file

2 Command Prompt

Shortcut Description
C-o Drop to the console
M-TAB Command prompt auto-completion
M-Enter Copy file/directory name to the prompt
M-a Copy file/directory name to the prompt (full path included)
M-h Show command prompt history
M-p Returns the previous command prompt
M-n Returns the next command prompt
C-x t Copy all your selected files to the prompt
C-x C-t Copy all your selected files to the prompt for the opposing panel
C-x p Copy the current path to the prompt
C-x C-p Copy the current path to the prompt for the opposite panel

3 Files Selection

Shortcut Description
Insert or C-t Select/deselect file
* Invert selection on files
+ Specify file selection options
- Specify file de-selection options

4 File View mode

Shortcut Description
C-f View the next file
C-b View the previous file

Saturday, December 14, 2019

Lisp Expressions vs. Lisp Forms

Lisp Expressions vs. Lisp Forms

1 Lisp Expressions vs. Lisp Forms

1.1 General

During my Lisp studies (Emacs Lisp and Clojure), I often encountered the terms: Lisp "Expression" and Lisp "Form" and I started wondering what is the difference since most literature seems to use both terms interchangeable.

An excerpt from: “Living Clojure” - Carin Meier

"An expression is [Lisp] code that can be evaluated for a result, and a form is a valid expression that can be evaluated"

In other words an expression is a valid input for the LISP `READ` (REPL) while a form is a valid input for both the `READ` and the `EVAL` part of the (REPL).

1.2 Examples

The below is a valid form (valid both for the `READ` and the `EVAL`)

(+ 1 2)

;; => 3

The below (assuming the 'foo' function is not defined) is a valid expression but not a valid form, it can be read but not evaluated since 'foo' is not defined:

(foo 1 2)

;; => Syntax error compiling at (REPL:1:1). Unable to resolve symbol: foo in this context