This is documented behaviour. The (much improved) explanation in the Emacs 25.1 elisp manual is as follows:
Note that unlike dynamic variables which are tied to the symbol
object itself, the relationship between lexical variables and symbols is
only present in the interpreter (or compiler). Therefore, functions
which take a symbol argument (like ‘...
Yes, this behavior is explained by differences in Variable Scoping between Emacs Lisp and Common Lisp.
In Common Lisp (a lexically scoped lisp) a lambda returned by complement you defined is turned into a closure, i.e. it captures the lexical environment that existed when it was created.
Here's what I get from SBCL:
(defun my-complement (f)
No, it shouldn't, if you use dynamic binding. Here are two choices (alternatives) that can help:
Use lexical binding. Set variable lexical-binding for the file.
Use dynamic binding (what you are doing now, no doubt), but also substitute the value of the variable cmd for the variable cmd in the lambda body. You can do this only if the function body of the ...
The kind of scoping active for the (let ((some-variable ..)) ...) in your example, is the one active at the site of the macro call (i.e. the one that applies to some-function).
A macro can know which kind of scoping will be used for the code it returns by checking the value of the lexical-binding variable.
What @Constantine said about lexical and dynamic scoping is true, and it explains the difference from Common Lisp behavior.
However, there is something misleading in your question. This really has nothing to do with macros. Here is a definition using defun instead of defmacro. Note that you need a quote mark (') before the use of ,function: ',function, ...
In short — dynamic binding is very slow. Lexical binding is extremely fast at runtime. The fundamental reason is that lexical binding can be resolved at compile time, while dynamic binding cannot.
Consider the following code:
(let ((x 42))
(message "%d" x))
When its compiling the let, the compiler cannot know whether foo will acess the (...
Why the two are treated differently is mostly "because that's what we needed". More specifically, the single-argument form of defvar appeared a long time ago, but later than the other and was basically a "hack" to silence compiler warnings: at execution time it had no effect at all, so as an "accident" it meant that the silencing behavior of (defvar FOO) ...
The byte-compiler's way to decide whether a function will be defined or not is very "naive" and gets fooled even in your "obvious" case.
But you can write it in a way that lets the compiler understand what happens:
(let ((count 0))
(setq count (1+ count))
(message "Count is: %d" ...
Will be useful to write/build literal closures?
Should it be a good practice? any example?
Why the closure is not a real type instead of cons?
All three questions are answered with the following quote of the elisp manual:
However, the fact that the internal structure of a closure is exposed to
the rest of the Lisp world is ...
To suppress the byte-compiler warning, try adding this before your code, starting in column 0 (leftmost):
(declare-function increase-count "your-file-name.el")
C-h f declare-function tells you:
declare-function is a Lisp macro in subr.el.
(declare-function FN FILE &optional ARGLIST FILEONLY)
Tell the byte-compiler that function FN is ...
lexical-let is defined in cl.el. You can (eval-when-compile (require 'cl)) to fix the problem. This is mostly equivalent to (require 'cl) but is more efficient when you byte-compile your code (see Drew's comment below).
You can achieve this locally by using cl.el's lexical-let:
(eval-when-compile '(require 'cl))
(defun my-test-caller (func)
(lexical-let ((ext-func func))
(lambda (status) (funcall ext-func)))))
(my-test-caller #'(lambda() (message "called")))
To be explicit as the help says:
Like `let', but ...
Simply require library cl at compile time, to get the use of its macros (and not get any runtime load). That is where macro lexical-let is defined.
So all you need is this, to use lexical-let:
(eval-when-compile (require 'cl)) ;; lexical-let
(I put the stuff I use from the library in a comment like that, just to let me know what I'm using from it.)
cl and cl-lib are not "either or". The former requires the latter and defines lexical-let.
If you want lexical bindings, you can turn them on using the variable lexical-binding.
You can also set it on a per-file basis using file variables.
You're tripping over dynamic binding (as opposed to lexical binding).
Your current-buffer-name is unbound at the point that your (lambda) function is executed. The let expression only binds it during the function's definition -- there's no closure to capture that value for subsequent evaluation.
One simple workaround is to use backquoting like so:
There's a few pitfalls here:
Using eval with lexical-binding will fail unless you pass it an alist environment argument holding the bindings in question (see F1 f eval)
Looking up symbol slots only behaves correctly with dynamic scoping, if you attempt it despite this, you'll get the global value (see F1 f symbol-value)
FWIW, this is what I'd call the ...
You're trying here to access the lexical variable x from outside its lexical scope, which obviously can't work. What you can do is pass a lexical environment to eval:
LEXICAL can also be an actual lexical environment, in the form of an
alist mapping symbols to their value.
;;; -*- lexical-binding: t; -*-
(defun include (quoted-lambda)
Based on experimentation, I believe the issue is that (defvar VAR) with no init value only has an effect on the library(s) it appears in.
When I added (defvar my-dynamic-var) to the *scratch* buffer, the error no longer occurred.
I originally thought this was on account of evaluating that form, but I then noticed firstly that simply visiting the file with ...
You can add not only action but any other attributes to a text-button, that can be referred later with button-get function. So saving the (reference to the) current buffer, together with action, seems a good idea here.
'action (lambda (b)
(with-current-buffer (button-get b '...
I believe placing the definition in question within eval-and-compile would also superficially achieve the same result as in Stefan's correct answer:
(let ((count 0))
(defun increase-count ()
(setq count (1+ count))
(message "Count is: %d" count))))
I am, however, barely familiar with the subtleties of ...
This comment does not suggest that lexical binding is either faster or slower than dynamic binding. Rather, it suggests that those different forms have different performance characteristics under lexical and dynamic binding, eg, one of them is preferable under one binding discipline, and the other preferable in the other.
So is lexical scope faster than ...
Your example is likely not representative of the actual code you're using, but a good solution might be to create the closure in the macro and return the closure, instead of returning code which may or may not turn into a closure depending on lexical-binding:
(defmacro repro ()
(let* ((kmap-sym (gensym "kmap-")))
`(let ((,kmap-sym (make-sparse-keymap))...
Use cl-labels to define local functions (cl-flet works, but recursive function reports error), and in the beginning of the .el file enable the lexical scoping:
;; -*- lexical-binding: t -*-
(defun make-account ()
(cl-labels ((withdraw (amount)
(print "in withdraw")))
(lambda () #'withdraw)))
Remember the # before the quoting ...
You seem to be using dynamic binding which means that str would be evaluated once your lambda function is executed at which time the variable str is no longer in scope.
You should turn on lexical binding to have your hook function converted into a closure during the invocation of my-eww-url so that once your hook function will be invoked str will be bound ...
Your problem is that the timer runs the function when the loop has finished.
The lexically bound variables index and value have for all calls the values after the last iteration.
One solution is to evaluate the variables at iteration time and pass just the values as arguments to the function.
(let ((my-list '(a b c)))
(cl-loop for index below (length my-...