The GNU Emacs Lisp Reference Manual, 12.5 Defining Global Variables:

If you use a defconst or defvar special form while the variable has a local binding (made with let, or a function argument), it sets the local binding rather than the global binding.

But when I tried it in *scratch*:

(defun f (some-symbol)
  (defconst some-symbol 1412)
;; ==> f

(f 0)
;; ==> 0

;; ==> 1412

It seems that (defconst some-symbol 1412) didn't set the local value of some-symbol (so that (f 0) evaluates to 0), instead it made the some-symbol at top level evaluate to 1412.

Do I misunderstand the definitions of local binding and global binding?


Another example that seems to work fine for @dalanicolai:

Although defconst does work as documented when using it with let: (let ((some-symbol 0)) (defconst some-symbol 1412) some-symbol) returns 1412.

but behaves weirdly in my Emacs:

*** Welcome to IELM ***  Type (describe-mode) for help.
ELISP> (let ((some-symbol 0))
         (defconst some-symbol 1412)
0 (#o0, #x0, ?\C-@)
ELISP> (let ((some-symbol 0))
         (defconst some-symbol 1412)
1412 (#o2604, #x584)

emacs-version: 28.2
system-configuration: x86_64-w64-mingw32

  • 1
    Indeed, it behaves the same on Emacs 30. Although defconst does work as documented when using it with let: (let ((some-symbol 0)) (defconst some-symbol 1412) some-symbol) returns 1412. Then again defvar does not work as documented when using it with let. To me it looks like you've encountered a 'documentation bug'. Mar 14, 2023 at 16:13
  • I am on Emacs 28.2 on Linux, works fine for me. I get 1412 from f and error on evaluating some-symbol. Same with let.
    – Arktik
    Mar 14, 2023 at 16:47
  • @dalanicolai: Thanks for your example. I will add it to my question description, because the first time my Emacs evaluates it, the result is 0!
    – shynur
    Mar 14, 2023 at 16:58
  • 2
    The defvar doc in the upstream repo says: If SYMBOL is let-bound, then this form does not affect the local let binding but the toplevel default binding instead, like ‘set-toplevel-default-binding‘. (‘defcustom’ behaves similarly in this respect.). I think it is likely that some of these behaviors might be "fluid", as bugs are found and fixed. I suspect that they will be cleaned up as time goes on, but you should probably report what you find perplexing, particularly if it contradicts the documentation.
    – NickD
    Mar 14, 2023 at 19:38
  • @Arktik Probably you did not activate the lexical-binding. To get lexical binding in *scratch*, be sure to use lisp-interaction-mode (the default for vanilla Emacs, but not on e.g. Spacemacs) and NOT emacs-lisp-mode. Of course, anyway thanks for the feedback... Mar 15, 2023 at 11:29


Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Browse other questions tagged or ask your own question.