This section is probably only useful for JavaScript programmers and those who want to write code with lots of asynchronous calls. Others should skip this section.

There can be trouble when the following conditions are met:

you produce anonymous functions in a loop

the functions are called after the loop finishes

the functions use non-local variables that are loop variables, i.e., the functions close over loop variables.

This code produces two buttons with labels egg and chicken.

( cl-loop for word in ( list "egg" "chicken" ) do ( insert-button word 'action ( lambda ( arg ) ( message "la %s" word ) ) ) ( insert " " ) )

Clicking on the egg button results in the message “la chicken”, not “la egg”. That is because cl-loop is implemented in a way that the loop establishes a local binding of word just once. It makes just one binding, not several. What I mean is that the loop does something like the following:

;; Example P ( let ( word ) ( setq word "egg" ) ( insert-button word 'action ( lambda ( arg ) ( message "la %s" word ) ) ) ( insert " " ) ( setq word "chicken" ) ( insert-button word 'action ( lambda ( arg ) ( message "la %s" word ) ) ) ( insert " " ) )

Like that, just one binding of word is established. By the time the button is clicked, word in that one binding refers to “la chicken”. On the other hand, the following code establishes two bindings of word :

;;; Example Q ( let ( ( word "egg" ) ) ( insert-button word 'action ( lambda ( arg ) ( message "la %s" word ) ) ) ( insert " " ) ) ( let ( ( word "chicken" ) ) ( insert-button word 'action ( lambda ( arg ) ( message "la %s" word ) ) ) ( insert " " ) )

With above code, the egg button will echo “la egg”, and the chicken button will echo “la chicken”. In this case, by the time any button is clicked, there are two bindings of word , the name word refers to different strings in two bindings. A single name, in this case word , referring to different things in different bindings at the same time is not some unique strange side of Emacs Lisp. If you have written recursive functions or worked with threads or closures in other languages, you are already familiar with the phenomena of one name referring to many things at the same time. Non-programmers are familiar with this phenomena as well: the name Bob refers to different persons in different bindings. The name “President” refers to different persons in different bindings. As of this writing (2013), the name President refers to the guy on the right (Barack Obama) in this picture in the American binding, while the same name refers to the woman on the left (Park Geun-Hye) in the South Korean binding. Let me relate this analogy to Example P and Example Q above.

Example P is like this: an American was born when George Bush was the President of the United States, and then another American was born while Barack Obama is the President. Now if we ask them “who’s president now?”, they will both answer Barack Obama. The two American babies are sharing one binding of President.

Example Q is like this: a Korean was born while Park is the President of South Korea, and then an American was born while Obama is the US president. Now if we ask them “who’s president now?”, one will answer “Park”, and another “Obama”. The two babies are using different bindings of President.

With the following code, the two buttons echo different messages as intended. Difference from the first cl-loop example is that now the non-local variable, which is msg this time, is not a loop variable and that the loop establishes two bindings of msg simply because the loop enters the let form twice.

( cl-loop for word in ( list "egg" "chicken" ) do ( let ( ( msg ( message "la %s" word ) ) ) ( insert-button word 'action ( lambda ( arg ) ( message msg ) ) ) ( insert " " ) ) )

Following code works as intended too, which is simply a variation of the above:

( cl-loop for word in ( list "egg" "chicken" ) do ( let ( ( word word ) ) ( insert-button word 'action ( lambda ( arg ) ( message "la %s" word ) ) ) ( insert " " ) ) )

That code actually creates three bindings of word : one outer binding and two inner bindings. The two buttons use two inner bindings.

That was the most general workaround. There are other workarounds like: