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. Commented 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. Commented Apr 17, 2020 at 16:30
  • 2
    The letrec form should allow for this case directly. Commented Apr 17, 2020 at 19:25
  • In fact, letrec is a macro and expands to the code in the answer. Commented Apr 18, 2020 at 9:29

Your Answer

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

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.