带有多个参数的QUOTE

时间:2015-01-24 05:29:16

标签: lisp

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

list的一些原语接受多个参数。 e.g:

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

另一方面,quote似乎只接受一个参数。 e.g:

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

上进行了测试

3 个答案:

答案 0 :(得分:5)

请注意,Lisp不是单一语言,而是一个有点类似语言的大家族。你似乎已经尝试过Scheme(repl.it运行BiwaScheme)和ClojureScript。

Scheme spec只为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只是忽略了任何函数的额外参数,因此行为可能来自那里。

ClojureScript可能会继承JavaScript或Clojure的方式。 Clojure's documentation明确声明具有多个参数的quote仅评估其中的第一个。

Common Lisp,另一种流行的Lisp语言,also only accepts a single argumentquote

$ 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定义的问题,如果有多个参数,则将它们评估为列表,但我当然看不到该功能的用途,要么。

答案 1 :(得分:2)

QUOTE的最初想法是表示常量,尤其是符号和列表:

(quote sin)

(quote (sin 10))

要获取未加引号的数据,我们会调用SECONDCADR

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

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

答案 2 :(得分:1)

在大多数lisps quote中,如果给出多个参数,则会出错。这种行为似乎是Clojure(或ClojureScript?)的特性。

允许quote的多个参数成为列表并不是一个非常好的设计。如果您有一个列表操作,您应该可以清楚地使用它来构建单个元素列表,但修改后的quote不允许这样做。

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