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

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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