Function: lexical-let

lexical-let is a macro defined in cl.el.gz.

Signature

(lexical-let BINDINGS BODY)

Documentation

Like let, but lexically scoped.

The main visible difference is that lambdas inside BODY will create lexical closures as in Common Lisp.

View in manual

Probably introduced at or before Emacs version 24.3.

Source Code

;; Defined in /usr/src/emacs/lisp/obsolete/cl.el.gz
(defmacro lexical-let (bindings &rest body)
  "Like `let', but lexically scoped.
The main visible difference is that lambdas inside BODY will create
lexical closures as in Common Lisp.
\n(fn BINDINGS BODY)"
  (declare (indent 1) (debug let))
  (let* ((cl-closure-vars cl-closure-vars)
	 (vars (mapcar (function
			(lambda (x)
			  (or (consp x) (setq x (list x)))
			  (push (make-symbol (format "--cl-%s--" (car x)))
				cl-closure-vars)
			  (set (car cl-closure-vars) [bad-lexical-ref])
			  (list (car x) (cadr x) (car cl-closure-vars))))
		       bindings))
	 (ebody
	  (macroexpand-all
           `(cl-symbol-macrolet
                ,(mapcar (lambda (x)
                           `(,(car x) (symbol-value ,(nth 2 x))))
                         vars)
              ,@body)
	   (cons (cons 'function #'cl--function-convert)
                 macroexpand-all-environment))))
    (if (not (get (car (last cl-closure-vars)) 'used))
        ;; Turn (let ((foo (gensym)))
        ;;        (set foo <val>) ...(symbol-value foo)...)
        ;; into (let ((foo <val>)) ...(symbol-value 'foo)...).
        ;; This is good because it's more efficient but it only works with
        ;; dynamic scoping, since with lexical scoping we'd need
        ;; (let ((foo <val>)) ...foo...).
	`(progn
           ,@(mapcar (lambda (x) `(defvar ,(nth 2 x))) vars)
           (let ,(mapcar (lambda (x) (list (nth 2 x) (nth 1 x))) vars)
           ,(cl-sublis (mapcar (lambda (x)
                              (cons (nth 2 x)
                                    `',(nth 2 x)))
                            vars)
                    ebody)))
      `(let ,(mapcar (lambda (x)
                       (list (nth 2 x)
                             `(make-symbol ,(format "--%s--" (car x)))))
                     vars)
         (setf ,@(apply #'append
                        (mapcar (lambda (x)
                                  (list `(symbol-value ,(nth 2 x)) (nth 1 x)))
                                vars)))
         ,ebody))))