2015-01-24 8 views
3

Я анализирующих LISP, я не эксперт, но что-то беспокоит меня:QUOTE с несколькими аргументами

Некоторые примитивы, как 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) то есть цитата с несколькими Params, просто игнорирует другие аргументы?

Что произойдет, если (quote 1 2 3) оценивается в (1 2 3), то есть в специальном случае, когда предоставляется более одного аргумента?

Я понимаю, что это особый случай является излишним, но мой вопрос к LISP хакеров:

добавления такой частный случай, чтобы quote сломает все? нарушит ли REPL? будет ли он прерывать макросы?

Примечание: проверено на http://repl.it/ и http://clojurescript.net/

ответ

5

Обратите внимание, что Lisp не один язык, но большой семье несколько подобных языков. Кажется, вы пробовали Scheme (repl.it работает BiwaScheme) и ClojureScript.

Scheme spec определяет только один аргумент для quote, поэтому BiwaScheme кажется неправильным в этом отношении. (quote 1 2 3) должно быть ошибкой в ​​схеме. Например, Racket, другой диалект Scheme, не принимает их:

$ 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, другой популярный язык Лисп, also only accepts a single argument к 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) 

Обратите внимание, что в общем, для любого Лиспе quote редко продуманы. Это просто специальная форма, которая является расширением '. В ' формы, это даже не возможно дать quote дополнительных аргументов:

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

Я не сразу видит проблем с расширением определения quote «s в любом данном языке, в случае нескольких аргументов , оценивайте их как список, но я, конечно же, не вижу смысла использовать эту функцию.

1

В большинстве lisps quote ошибка будет передана с несколькими аргументами. Такое поведение кажется особенностью Clojure (или ClojureScript?).

Разрешить несколько аргументов quote, чтобы стать списком, не очень приятный дизайн. Если у вас есть операция по созданию списка, вы должны четко использовать его для создания списка отдельных элементов, но измененный quote не позволяет этого.

(я тестировал SBCL, Emacs Lisp и scheme48, все из которых придраться цитаты с несколькими аргументами.)

2

Оригинальная идея QUOTE является для обозначения постоянной, особенно для символов и списков:

(quote sin) 

(quote (sin 10)) 

Для получения некорректных данных мы вызываем SECOND или CADR.

(defun unquote (expression) 
    (second expression)) 

Например, мы могли бы назвать:

(unquote '(quote (sin 10))) 

Если знать позволяют идею, что (quote sin 10) такое же, как (quote (sin 10)), то мы должны были бы переписать нашу функцию Unquote для двух случаев:

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

Добавив этот специальный случай, мы не получим никаких новых возможностей, но это усложнит код, который должен иметь дело с такими выражениями ...

Смежные вопросы