LINUX.ORG.RU

Получить значение символа в локальном окружении

 


0

2

Если символ объявлен глобально, то его значение можно получить с помощью eval, но если локально, то это уже не работает.

> (setf a 5)
> (eval 'a)
5
> (let ((b 4)) (eval 'b))
>> ошибка
Как получить значение символа объявленного локально?

★★★★★

как в одном из тредов мне объяснили — стандартно никак.
В sbcl, например, есть sb-int:eval-in-lexenv.

(let ((b 4)) (eval 'b))

можно попробовать как-то так: (let ((b 4)) (eval `(eval ,b)))

Bad_ptr ★★★★★
()
(let ((b 4)) (declare (special b)) (eval 'b))

Или лучше сначала для b сделать bound (через defvar, например). Но лучше такое вообще не делать.

mv ★★★★★
()
Ответ на: комментарий от dave

тогда не подскажите, как обойти этот момент в макросе:

(defstruct lazy-t calculated func args)

(defmacro lazy(&rest expr)
 (labels ((lazy* (a)
            (if (atom a)
              (if (symbolp a)
                 (eval a) ; вот тут этот косяк
                 a)
              (make-lazy-t :func (eval `(function ,(car a))) :args (mapcar #'lazy* (cdr a))))))
    (lazy* expr)))

Aswed ★★★★★
() автор топика
Ответ на: комментарий от Aswed

Я упрощаю примерно до такого (если это ленивые вычисления):

(defun memo (function)
  "Memoize the specified function."
  ..)

(defmacro delay (exp)
  "Delay the expression."
  `(memo (lambda () ,exp)))

(defun force (delayed-exp)
  "Force to return the value of the delayed expression."
  (funcall delayed-exp))

По вкусу добавить поддержку многопоточности как в System.Lazy<T> из .NET. А, вообще, можно взять QuickLisp :)

dave ★★★★★
()

(setf z 111)

==> 111

(let ((a z)) (print a))

111

(let ((x (eval 'z))) (print x))

111

eval работает в глобальном контексте, что отражено в описании.

А что значит получить значение символа, объявленного локально? Ставь его в нужное место - и все...

(let ((x 555)) `(x = ,x))

==> (X = 555)

CatsTail
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.