3

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)
  some-symbol)
;; ==> f

(f 0)
;; ==> 0

some-symbol
;; ==> 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?


Update

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)
         some-symbol)
0 (#o0, #x0, ?\C-@)
ELISP> (let ((some-symbol 0))
         (defconst some-symbol 1412)
         some-symbol)
1412 (#o2604, #x584)
ELISP> 

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

5
  • 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 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 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 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 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 at 11:29

0

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Browse other questions tagged or ask your own question.