Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Elisp: Symbol's value as variable is void with let* and (lambda)

Disclaimer: I started to hack around with elisp today.

I am really wondering what I am getting the following error:

Symbol's value as variable is void: response

with the following code:

(let* ((response (cons 'dict nil)))
  (nrepl-request:eval
   code 
   (lambda (resp) 
      (print resp (get-buffer "*sub-process*"))
      (nrepl--merge response resp))
   (cider-current-connection) 
   (cider-current-session)))

My understanding is that response is in the scope of the let* clause when called from the lambda function... but apparently that it is not.

This also seem to be working in this code

So I am a bit lost about why I am getting this error and what I should do about it.

like image 859
Neoasimov Avatar asked Dec 24 '22 07:12

Neoasimov


1 Answers

You need to specify lexical binding, by setting global variable lexical-binding as a file-local variable in your source file. Put a line like this as the first line of the file:

;;;  -*- lexical-binding: t -*-

Either do that or use lexical-let* instead of let*.

Alternatively, if you do not need variable response as a variable when the anonymous function is invoked, that is, if you need only its value at the time the function was defined, then you can use this:

(let* ((response (cons 'dict nil)))
  (nrepl-request:eval
   code 
   `(lambda (resp) 
      (print resp (get-buffer "*sub-process*"))
      (nrepl--merge ',response resp)) ; <===== Substitute value for variable
   (cider-current-connection) 
   (cider-current-session)))

With the lexical variable, the lambda form gets compiled when you byte-compile the file. Without the variable (i.e., with just its value), the lambda form is not compiled -- it is just a list (with car lambda etc.).

like image 190
Drew Avatar answered Dec 27 '22 11:12

Drew