区分绑定变量和未绑定变量

时间:2019-09-01 20:55:37

标签: variables macros common-lisp

我正在尝试编写一个名为different的宏,以测试两个用户提供的自变量是否临时eq,其中自变量可以是绑定的,也可以是未绑定的。但是我迷失了这种可能性(也许是逻辑)。以下内容似乎可行,但需要增强(包括避免捕获变量和进行多次评估):

(defmacro different (item1 item2)
  `(not (eq (if (boundp ',item1) ,item1 ',item1)
            (if (boundp ',item2) ,item2 ',item2))))

基本思想是查找任何未绑定的变量,将其引用,然后查看该变量是否为另一个变量的值eq。 (目标是使最终用户不必决定何时引用参数,因为绑定变量会另外标记出来。)

所以现在:

if x is unbound and y is bound to 'x, or
   y is unbound and x is bound to 'y
(different x y) => NIL 

if x is unbound and y is bound to 'z, or
   y is unbound and x is bound to 'z
(different x y) => T

主要问题是item1或item2可以用作任意Lisp对象的指定符(在这种情况下,equalp将代替eq)。例如:

(defparameter x 3)
(different x 3) => NIL (since they are equalp)

(defparameter x '(a b c))
(different x (c b a)) => T  (where (c b a) gets quoted)

这是否可以分解为宏,是否可以将if语句带到反引号之外?

1 个答案:

答案 0 :(得分:1)

只有六种情况要处理

这是要做的事情的映射:

For b ≡ bound symbol
For u ≡ unbound symbol
For e ≡ any other value
b b -> eq
b u -> equalp
u u -> equalp
e e -> equalp
e u -> ERROR (makes no sense)
e b -> equalp

希望这可以帮助您组织分支逻辑。当我发生爆炸时,我喜欢拉一些纸并通过分支工作。通常,可以使用谓词演算来减少它,或者提出另一个分支较少的表示形式。