Variables 区分有界变量和无界变量

Variables 区分有界变量和无界变量,variables,macros,common-lisp,Variables,Macros,Common Lisp,我正在尝试编写一个名为different的宏,以测试两个用户提供的参数是否是临时的eq,其中的参数可能是绑定的,也可能是未绑定的。但我正在迷失在可能性(也许还有逻辑)中。以下似乎有效,但需要增强(包括避免变量捕获和多重评估): 基本思想是寻找任何未绑定的变量,引用它,然后查看它是否与另一个变量的值相等。(目标是使最终用户不必决定何时引用参数,因为绑定变量是以其他方式标记的。) 所以现在: if x is unbound and y is bound to 'x, or y is unbou

我正在尝试编写一个名为
different
的宏,以测试两个用户提供的参数是否是临时的
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语句带到backquote之外?

只有六种情况需要处理

以下是将要执行的操作的映射:

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

希望这能帮助您组织分支逻辑。当我遇到这样的爆炸时,我喜欢拉一些纸,通过分支工作。通常情况下,可以使用谓词演算来减少它,或者提出另一种分支较少的表示法。

注意,BOUNDP仅适用于特殊变量,而不适用于词汇变量。EQ和EQUALP之间的关系是什么?EQ比较对象标识。EQUALP通过值、内容和EQ比较了一些相同类型的对象。我认为,如果您运行类似的东西,您将创建一种方法来迷惑任何使用它的人。我的意思是,Perl已经够令人困惑的了,它只是在数字和字符串之间进行转换。现在,您希望根据某些隐式全局状态,在符号和它们命名的变量值之间进行转换。只是说说而已。@Svante。我明白了。但它只限于一个宏。我现在看到的更大的问题(根据上面的Rainer Joswig)是绑定变量总是词法的,所以boundp不起作用。对我来说,这仍然是一个值得/简化的用户界面,但我可以探索其他替代方案(或者只需要lisp代码)。感谢您分析Spenser。在查看了您的列表之后,似乎可以进一步简化。(但如果知道这是对一些基本lisp概念的误解,我会很感激。)也许传递到宏中的参数可以分为绑定符号(也称为变量)和其他所有对象,它们是任意的lisp对象(非变量)。非变量可以分为对自身求值的变量(数字、字符、向量、函数、哈希表等)和不求值的变量(例如,x,'x,(abc),'(abc),等等)。因此,如果对宏参数求值产生错误,则它是非变量。如果它对自身进行评估,那么它也是一个不可变的。但如果它的计算结果不是它自己,它就是一个绑定变量。这有意义吗?值得尝试编写代码吗?
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