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

shynur
  • 4,065
  • 1
  • 3
  • 23
  • 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'. – dalanicolai Mar 14 '23 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 '23 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 '23 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 '23 at 19:38
  • @Arktik Probably you did not activate the [lexical-binding](https://www.gnu.org/software/emacs/manual/html_node/elisp/Lexical-Binding.html). 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... – dalanicolai Mar 15 '23 at 11:29

0 Answers0