;;; See https://nullprogram.com/blog/2014/01/04/ and ;;; https://nullprogram.com/blog/2013/12/30/ for more examples ;;; Looking at eLisp's mytracker example: (setq mytracker (let ((cnt 1)) (lambda () (setq cnt (1+ cnt))))) (closure ((cnt . 1) t) nil (setq cnt (1+ cnt))) (funcall mytracker) 2 (funcall mytracker) 3 (funcall mytracker) 4 (disassemble-internal mytracker 2 nil) args: nil ; [] 0 constant (4) ; [->(cons 4 nil)] 1 dup ; [->(cons 4 nil) [->(cons 4 nil)] 2 car-safe ; [4 ->(cons 4 nil)] 3 add1 ; [5 ->(cons 4 nil)] 4 setcar ; [5] 5 return nil mytracker (closure ((cnt . 4) t) nil (setq cnt (1+ cnt))) (funcall mytracker) 5 mytracker (closure ((cnt . 5) t) nil (setq cnt (1+ cnt))) (funcall mytracker) 2 (funcall mytracker) 3 (dis mytracker) args: nil 0 constant (3) ; [->(3 nil)] 1 dup ; [->(3 nil) ->(3 nil)] 2 car-safe ; [3 ->(3 nil)] 3 add1 ; [4 ->(3 nil)] 4 setcar ; [4 ->(4 nil)] 5 return nil ;; Lets look at a byte-compiled function packaged with Emacs. (require 'rot13) ;; silly "encryption", but sometimes useful rot13 (rot13 "abcd") "nopq" (rot13 "nopq") "abcd" ;; Find the elements discussed in https://nullprogram.com/blog/2014/01/04/ (byte-compile 'rot13) #[769 "\300!\203rq\210\301\")\207\302!\207" [bufferp rot13-region rot13-string] 6 ("/opt/homebrew/Cellar/emacs/28.2/share/emacs/28.2/lisp/rot13.elc" . 648)] (aref (symbol-function #'rot13) 0) ; <<-- arguments descriptor, bit-encoded as an integer 769 (aref (symbol-function #'rot13) 1) ; <<-- compiled bytecode "\300!\203rq\210\301\")\207\302!\207" (aref (symbol-function #'rot13) 2) ; <<-- constants vector [bufferp rot13-region rot13-string] ;; find the other elements and look at the file (on your system, it'll likely be different) ;;;; ------ another example, we'll hand-make a closure this time -------- (setq y+ (let ((y 1)) (lambda (x) (+ x y)))) (closure ((y . 1) t) (x) (+ x y)) (funcall y+ 100) 101 (disassemble-internal y+ 2 nil) doc: ... args: (arg1) 0 dup 1 constant 1 2 plus 3 return nil (setq y+ (let ((y 10)) (make-closure (byte-compile (lambda (x) (setq y (1+ y)) (+ x y)))))) #[257 "\300\211\242T\240\210\211\300\242\\\207" [(10)] 3 " ^^^^-----note that this is a cons cell with car 10 (fn X)"] (funcall y+ 100) 111 (funcall y+ 100) 112 (disassemble-internal y+ 2 nil) doc: ... args: (arg1) ; [arg1] 0 constant (12) ; [->(12 nil) arg1] 1 dup ; [->(12 nil) ->(12 nil) arg1] 2 car-safe ; [12 ->(12 nil) arg1] 3 add1 ; [13 ->(12 nil) arg1] 4 setcar ; [13 arg1] <<-- car value of the cons cell is changed! 5 discard ; [arg1] 6 dup ; [arg1 arg1] 7 constant (12) ; [->(13 nil) arg1 arg1] 8 car-safe ; [13 arg1 arg1] 9 plus ; [(arg1+13) arg1] 10 return nil (funcall y+ 100) 113 (disassemble-internal y+ 2 nil) doc: ... args: (arg1) 0 constant (13) ; <<--- observe the change in the cons cell's car (the cons reference remains the same, being a part of the constants vector 1 dup 2 car-safe 3 add1 4 setcar 5 discard 6 dup 7 constant (13) 8 car-safe 9 plus 10 return nil