引用多个参数

问题描述 投票:0回答:3

我正在分析 LISP,我不是专家,但有些事情困扰着我:

一些原语如

list
接受多个参数。例如:

(list 1 2 3)
=> (1 2 3)

另一方面,

quote
似乎只接受一个参数。例如:

(quote (1 2 3))
=> (1 2 3)
(quote x)
=> 'x
(quote 1 2 3)
=> 1  ???

有没有理由为什么

(quote 1 2 3)
即带有多个参数的引用,只是忽略其他参数?

如果

(quote 1 2 3)
计算为
(1 2 3)
(即提供多个参数时的特殊情况)会发生什么?

我确实知道这种特殊情况是多余的,但我对 LISP 黑客的问题是:

将这种特殊情况添加到

quote
会破坏一切吗?它会破坏 REPL 吗?它会破坏宏吗?

注意:在 http://repl.it/http://clojurescript.net/

进行测试
lisp
3个回答
7
投票

请注意,Lisp 不是一种单一语言,而是一个由有些相似的语言组成的大家族。您似乎已经尝试过Scheme(repl.it运行BiwaScheme)和ClojureScript。

Scheme 规范仅定义了

quote
的一个参数,因此 BiwaScheme 在这方面似乎是错误的。
(quote 1 2 3)
应该是Scheme中的一个错误。例如,Scheme的另一种方言Racket不接受它们:

$ racket
Welcome to Racket v5.3.6.
> (quote 1)
1
> (quote 1 2 3)
stdin::10: quote: wrong number of parts
  in: (quote 1 2 3)
  context...:
   /usr/share/racket/collects/racket/private/misc.rkt:87:7

BiwaScheme 是用 JavaScript 编写的,JavaScript 只是忽略 any 函数的额外参数,因此行为可能来自那里。

ClojureScript 可能从 JavaScript 或 Clojure 继承其方式。 Clojure 的文档 明确指出,具有多个参数的

quote
仅计算其中第一个参数。

Common Lisp,另一种流行的 Lisp 语言,也只接受单个参数

quote

$ sbcl
* (quote 1 2 3)
debugger invoked on a SIMPLE-ERROR in thread
#<THREAD "main thread" RUNNING {1002B2AE83}>:
  wrong number of args to QUOTE:
 (QUOTE 1 2 3)

请注意,一般来说,对于任何 Lisp,

quote
很少被拼写出来。它只是一种特殊形式,是
'
的扩展。在
'
形式中,甚至不可能给出
quote
额外的参数:

'(1 2 3) ≡ (quote (1 2 3))
'x       ≡ (quote x)
'???     ≡ (quote 1 2 3)

我不会立即发现在任何给定语言中扩展

quote
的定义有问题,在有多个参数的情况下,将它们作为列表进行评估,但我当然也没有看到该功能的用途。


3
投票

QUOTE
的最初想法是表示一个常量,特别是对于符号和列表:

(quote sin)

(quote (sin 10))

要获取未引用的数据,我们调用

SECOND
CADR

(defun unquote (expression)
  (second expression))

例如我们可以调用:

(unquote '(quote (sin 10)))

如果我们现在允许

(quote sin 10)
(quote (sin 10))
相同,那么我们需要针对这两种情况重写我们的取消引用函数:

(defun unquote (expression)
  (if (consp (cddr expression))
    (cdr expression)
    (cadr expression)))

通过添加这种特殊情况,我们不会获得任何新功能,但它会使必须处理此类表达式的代码变得复杂......


1
投票

在大多数 Lisp 中,如果给出多个参数,

quote
将会出错。这种行为似乎是 Clojure(或 ClojureScript?)的一个特性。

允许

quote
的多个参数成为列表并不是一个很好的设计。如果您有一个创建列表的操作,那么您显然应该能够使用它来构造单个元素列表,但修改后的
quote
不允许这样做。

(我测试了 SBCL、Emacs Lisp 和 schema48,所有这些都抱怨带有多个参数的引用。)

© www.soinside.com 2019 - 2024. All rights reserved.