0

考虑这个问题。这里的基本问题是代码:

(progv '(op arg) '(1+ 1)
 (eval '(op arg)))

这里的问题是将progv绑定到变量作为变量的not 。但是,这很明显,因为我们没有明确建议哪些值是函数。symbol-valuesymbol-function


计划

因此,为了解决这个问题,我想到了手动将变量动态绑定到基于值的类型的值。如果值是,fboundp那么它们应该绑定到symbol-function变量的。一个限制,就是match-if不能是macro. 它必须是 a function,因为它是由 a 调用的funcall

宏:functioner :

(defmacro functioner (var val)
  `(if (and (symbolp ',val)
            (fboundp ',val))
       (setf (symbol-function ',var) #',val)
       (setf ,var ,val)))

功能match-if::

(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))))

在这里,该let部分以词法方式(假设)声明了所有变量。然后declare声明它们special。然后functioner适当地绑定变量及其值。然后评估模式中的代码。如果代码部分为真,则仅pat-match调用模式匹配器函数。


问题

问题是在函数中,它的所有参数都被评估了。因此bindingsletanddeclare部分将被替换为 :
((v1 . val1)(v2 . val2)(v3 . val3))
not
'((v1 . val1)(v2 . val2)(v3 . val3))
所以,它被视为代码,而不是列表。
所以,我被困在这里。宏不会帮助我解决这个问题。
任何帮助表示赞赏。

4

1 回答 1

2

不是您要找的答案,而是PROGV一个特殊的运算符;它被授予在运行时修改变量的动态绑定的能力;AFAIK,你不能简单地破解它来操作“动态函数绑定”。的要点progv是使用符号列表和被评估的值,这意味着您可以在运行时生成符号并将它们动态绑定到相应的值。

您可能可以找到解决方案,eval但请注意,如果您将宏展开为(eval ...),那么您会失去周围的词法上下文,这通常不是您想要的(“eval”在空词法环境中运行)。我推测您还可以有一个自定义代码walker,它适用于顶级表单,但在找到您的特殊运算符时重新组织它们,以将上下文带回,生成类似(eval '(let (...) ...)).

于 2017-06-23T21:08:43.000 回答