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

No comments:

Post a Comment