Проблема
Проблема, которую я здесь вижу, заключается в том, что по коду мы не можем определить, должно ли значение быть сохранено как symbol-value
или symbol-function
переменной. Таким образом, когда вы помещаете +
в качестве значения некоторой соответствующей переменной, скажем v
, тогда оно всегда будет сохраняться как symbol-value
из var
, а не как symbol-function
.
Поэтому, когда вы попытаетесь использовать его как, скажем, (v 1 2)
, это не сработает. Поскольку в пространстве имен функций нет функции с именем v
(см. this).
Так что делать?
Вероятным решением может быть явная проверка значения, которое должно быть привязано к переменной. Если значение является функцией, то оно должно быть привязано к значению функции переменной. Эту проверку можно выполнить через fboundp
.
Итак, мы можем сделать макрос functioner
и модифицированную версию match-if
. functioner
проверяет, является ли значение функцией, и правильно ее устанавливает. match-if
выполняет динамические локальные привязки и разрешает другой код в области связанных переменных.
(defmacro functioner (var val)
`(if (and (symbolp ',val)
(fboundp ',val))
(setf (symbol-function ',var) #',val)
(setf ,var ,val)))
(defun match-if (pattern input bindings)
(eval `(and (let ,(mapcar #'(lambda (x) (list (car x))) bindings)
(declare (special ,@ (mapcar #'car bindings)))
(loop for i in ',bindings
do (eval `(functioner ,(first i) ,(rest i))))
(eval (second (first ',pattern))))
(pat-match (rest ',pattern) ',input ',bindings))))
person
Mooncrater
schedule
22.06.2017