Skip to content

Instantly share code, notes, and snippets.

@hidsh
Last active December 12, 2020 22:06
Show Gist options
  • Save hidsh/e271382b8ac38b941b159165cf4f9cc6 to your computer and use it in GitHub Desktop.
Save hidsh/e271382b8ac38b941b159165cf4f9cc6 to your computer and use it in GitHub Desktop.
elisp example: let と lexical-let の違い (emacs 26.3)
;; let の場合
(let (val)
(defun init () (setq val 100))
(defun print () (message "val: %d" val)))
(init) ;; => 100
(let ((val 200))
(print)) ;; => "val: 200" <---!!!
;; lexical-let の場合
(lexical-let (val)
(defun init () (setq val 100))
(defun print () (message "val: %d" val)))
(init) ;; => 100
(let ((val 200))
(print)) ;; => "val: 100" <---!!!
;; まとめ
;;
;; `let'で囲んだ場合:
;; 実行時に値が変更されると、その値が効く (ダイナミックスコープ)
;; `defun'したときに外側にあるvalの値は使わない
;;
;; `lexical-let'で囲んだ場合:
;; 実行時に値が変更されても、その値は効かない (レキシカルスコープ)
;; `defun'したときに外側にあるvalの値を使う
;;
;; これ見ると、ふるまい的にはダイナミックスコープ = グローバル変数 のように見える
;; ということは`defun'するときに`let'で囲んでも、変数名を短縮する以上の意味はないということか。
;;
;; ちなみに `lexical-binding'というバッファローカル変数を実行時にtにすれば、`let'でもレキシカルスコープな動きになる
;; https://ayatakesi.github.io/lispref/25.1/elisp-ja-html/Using-Lexical-Binding.html
;;
;; ちなみにちなみに、common lisp では当然レキシカルスコープ
;; 参考:common lisp (gnu clisp 2.49.60)
(let (val)
(defun init-val () (setq val 100))
(defun print-val () (prin1 (format nil "val: ~d" val))))
(init-val)
(let ((val 200))
(print-val)) ;; => "val: 100" <---!!!
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment