1

Here's a simple test:

(let ((func (lambda (i)
              (when (> i 0)
                (print i)
                (funcall func (1- i))))))
  (funcall func 3))

It says (void-variable func), but why? When (funcall func 3) is called then func already has a value. Why doesn't the inside of the lambda see the dynamically bound variable?

1
  • My crystal ball says this is a duplicate question. Hope someone has the time to track down the duplicate and close, if so.
    – Drew
    Apr 17, 2020 at 17:19

1 Answer 1

2

Why doesn't the inside of the lambda see the dynamically bound variable?

Because it isn't actually dynamically bound.

Check the value of lexical-binding in the buffer where this form is located. While it is t evaluating this form raises this error. Once you have set it to nil it will work.

It would be better to stick to lexical bindings instead of doing that by letting the the lambda capture the lexically bound func like so:

(let (func)
  (setq func (lambda (i)
               (when (> i 0)
                 (print i)
                 (funcall func (1- i))))))
  (funcall func 3))
3
  • Thanks, yes, lexical-binding was on.Tricky.
    – Tom
    Apr 17, 2020 at 16:30
  • 2
    The letrec form should allow for this case directly.
    – wasamasa
    Apr 17, 2020 at 19:25
  • In fact, letrec is a macro and expands to the code in the answer.
    – wasamasa
    Apr 18, 2020 at 9:29

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.