As in the code below, I define a function to create a closure that accepts one argument, the value of which is expected to be a symbol referring to a variable bound in the context of this closure. In the body of the closure, I use symbol-value
to get the symbol's value, but it prompts an error saying Symbol's value as variable is void
, I expect evaluating this snippet to show 123
.
So here I have two questions:
- Why
symbol-value
doesn't work ? - How do I correct this snippet to get the desired result ?
(defun make-closure ()
(lexical-let ((var1 123))
(lambda (name)
;; How can I get the value cell of the symbol
;; specified by the argument "name" ?
;; This doesn't work.
(message-box (format "%s" (symbol-value name))))))
(let ((closure (make-closure)))
(funcall closure 'var1))
Updated:
Actually, I got this question when I was writing some toy code to imitate "Object Oriented". At first it was something like this (which is similar to the second code of Stefan's answer):
(defun new-person (initial-name)
(lexical-let* ((name initial-name)
(say-hi (lambda ()
(message-box (format "Hi, I'm %s" name))))
(change-name (lambda (new-name)
(setq name new-name))))
(lambda (selector &rest args)
(cond
((equal 'say-hi selector) (apply say-hi args))
((equal 'change-name selector) (apply change-name args))
(t (message-box "Message not understood"))))))
(let ((tony (new-person "Tony")))
(funcall tony 'say-hi)
(funcall tony 'change-name "John")
(funcall tony 'say-hi))
But I felt the clauses of "cond" kinda "boilerplate" and I thought it might be possible to use the symbol passed from the argument, so I modified it to the following, which no longer works, but I couldn't figure out why:
(defun new-person (initial-name)
(lexical-let* ((name initial-name)
(say-hi (lambda ()
(message-box (format "Hi, I'm %s" name))))
(change-name (lambda (new-name)
(setq name new-name))))
(lambda (selector &rest args)
(apply (symbol-value selector) args))))
So is that to say that we shouldn't use a symbol to reference a lexically-bound variable in a closure like the above, since the names of them at evaluation aren't guranteed to be the same as they're written in the source ?