Lisp-1 和 Lisp-2 有什么区别?
我试图理解 Lisp-1 和 Lisp-2 之间的区别以及它与 Clojure 的关系,但我仍然没有正确理解。谁能启发我吗?
I have tried to understand the difference between Lisp-1 and Lisp-2 and how this relates to Clojure but I still do not understand properly. Can anyone enlighten me?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
您可能想阅读 Richard Gabriel 撰写的这篇论文。它总结了 Lisp 社区在 Lisp1 与 Lisp2 中讨论的问题。前几节内容有点密集且进展缓慢,但当你读完第 5 节时,阅读起来就容易多了。
基本上,Lisp1 有一个将符号映射到值的环境,这些值可以是“常规”值或函数。 Lisp2 有(至少)两个命名空间(符号有一个用于函数值的槽和一个用于常规值的槽)。因此,在 Lisp2 中,您可以拥有一个名为 foo 的函数和一个名为 foo 的值,而在 Lisp1 中,名称 foo 只能引用单个值(函数或其他值)。
两者之间存在一些权衡和品味差异,但请阅读论文了解详细信息。 Christian Queinnec 的书《Lisp in Small Pieces》也对文本中的差异进行了讨论。
You might like to read this paper by Richard Gabriel. It is a summary of the issues that the Lisp community were discussing in Lisp1 vs Lisp2. It's a bit dense and slow moving in the first few sections, but is much easier to read by the time you get past section 5.
Basically, Lisp1 has a single environment that maps symbols to values, and those values can be either "regular" or functions. Lisp2 has (at least) two namespaces (symbols have a slot for their a function value and one for a regular value). So, in Lisp2, you can have a function named foo and a value named foo, whereas in Lisp1, the name foo can refer only to a single value (function or otherwise).
There are several tradeoffs and differences of taste between the two, but read the paper for the details. Christian Queinnec's book, "Lisp in Small Pieces" also has discussion of the differences woven through the text.
根据维基百科:
它基本上是关于变量和函数是否可以具有相同的名称而不发生冲突。 Clojure 是 Lisp-1,这意味着它不允许函数和变量同时使用相同的名称。
According to wikipedia:
It's basically about whether variables and functions can have the same name without clashing. Clojure is a Lisp-1 meaning that it does not allow the same name to be used for a function and a variable simultaneously.
在 Lisp-1 中,符号只能有 1 个值。在 Lisp-2 中,符号可以有两个值:1)符号被解释为函数时的值,2)符号被解释为值时的值。
在 Lisp-1 的实现中,包含与符号关联的值的结构只有一个用于指向数据和类型的指针的槽。在 Lisp-2 中,有两个指针,一个是函数值,另一个是变量值。
在 Common Lisp(Lisp-2)中,您可以调用 (symbol-function 'a)
(符号值'a)
分别获取函数和值。
如果 'a 被定义为 add 函数并且 (setq a 3)then
(AAA 1)
将返回 7。
在 lisp 1 中你不能这样做,因为 a 只能是一件事,并且上下文不会改变含义。
在 Common Lisp 中,#' 是符号函数的缩写。
(setf (符号函数 'a) #'+ )
会将 a 设置为函数和。
如果您愿意,您可以创建一个函数 a,将 a 设置为调用 a 最后返回的值,也许 a 的计算成本很高。
在 Lisp-2 中,如果您将一个函数分配给一个符号,那么要调用该函数,您可以使用 funcall 运算符。
In a Lisp-1 a symbol can only have 1 value. In a Lisp-2 a symbol can have two values which are 1) the value when the symbol is interpreted as a function and 2) when the symbol is interpreted as a value.
Down in the implementation in a Lisp-1 the structure that contains the value associated with a symbol has just one slot for a pointer to the data and type. In a Lisp-2 there are two pointers, one the function value, the other the variable value.
In Common Lisp, a Lisp-2, you can call (symbol-function ‘a)
(symbol-value ‘a)
to get the function and value separately.
If ‘a is defined as the add function and (setq a 3)then
(a a a 1)
would return 7.
In a lisp 1 you couldn’t do that because a could only be one thing, and the context does not change the meaning.
In Common Lisp #’ is an abbreviation for symbol-function.
(setf (symbol-function ‘a) #’+ )
would set a to be the function sum.
If you wanted, you could create a function a that would set a to the value last returned by a call to a, perhaps if a was expensive to compute.
In a Lisp-2 if you assigned a function to a symbol then to call that function you use the funcall operator.