2017-01-29 2 views
1

Я только начинаю изучать lisp и немного озадачен тем, почему компилятор не оценивает простое целое число, заключенное в круглые скобки, в значение этого целого.Lisp: разница между 2 и (2)

В РЕПЛ, когда я (+ 3 2) я получаю 5, но когда я делаю (+ 3 (2)) я получаю сообщение об ошибке, в то время как я думаю, что значение выражения (2) также должно быть 2. Ясно, что здесь есть что-то важное, что я не могу наложить пальцем - в чем разница между 2 и (2)? Любая помощь была бы наиболее оценена, так как это кажется основополагающим для того, как работает lisp.

+0

Это, к сожалению, не имеет никакого смысла, поскольку Lisp не ведет и не должен вести себя так, как вы описываете. –

+0

Да, ты прав. Я ошибся в части вопроса: первая часть [где я писал о (2) возвращении 2] была в другом листе. Я ошибочно полагал, что поведение второй части [(+ 3 (2)), отличное от (+ 3 2)], было согласованным между обоими листами, поведение первой части также должно быть одинаковым. Извинения за путаницу. Теперь я удалил первую часть. Тем не менее, суть вопроса остается (то же самое). – Yogesch

+1

'Я думаю, что значение выражения (2) также должно быть 2' - почему вы так думаете? Почему бы не прочитать введение Лиспа, чтобы получить основы? Это хорошее начинающее введение, которое я бы рекомендовал: https://www.cs.cmu.edu/~dst/LispBook/. Бесплатная версия книги доступна на этой странице. –

ответ

3

Поддерживаемый Common Lisp синтаксис для форм списка указан здесь: CLHS Раздел 3.1.2.1.2 Conses as Forms.

Есть четыре поддерживаемых типа списков как формы:

  1. специальные формы, такие как (quote foo)
  2. макро формы, как (defun foo (a1 a1) (+ a1 a2))
  3. функциональных форм, таких как (+ 1 2)
  4. лямбда-формы, такие как ((lambda (a) (+ a 1)) 2)

Вот и все. Другие списки не могут быть оценены в Common Lisp.

1

Следует также отметить, что существует разница между списком, и формой. Все формы (+ 1 2) - это списки, но не все списки (2) являются формами.

Когда вы вводите что-то в строке запроса, это должна быть форма . Первая часть формы почти всегда должна быть своего рода оператором.

Если у вас есть REPL приглашение, и вы наберете в следующем, вы получите сообщение об ошибке, потому что это просто список, а не форма:

(2) 

Что будет работы является то, что говорит в REPL для построения списка:

'(2) 
'(aardvark) 

... которое действительно просто сокращение для:

(quote (2)) 
(quote (aardvark)) 

Это означает, что на самом деле это список, начинающийся с оператора, и поэтому является формой.

Следующие примеры возвращают результаты:

(+ 1 2) 
(+ 1 (+ 2 3)) 

В принципе, способ думать об этом является то, что каждый элемент (кроме первого) в списке оценивается, то первый элемент выполнен на элементах , Таким образом, (+ 1 (+ 2 3)) сначала оценивается как 1, результатом которого является 1, а затем (+ 2 3), который сначала сначала оценивает аргументы перед выполнением оператора, что означает, что 2 и 3 подаются на +, что приводит к 5, а затем 1 и 5 подается до +.

ли вы сказать (+ 1 (2)), он пытается оценить каждый элемент после первого, идя 1 оценивает в 1, но (2) имеет значение ... ничего, потому что первый элемент не является оператором.

Кстати, я считаю полезным рассмотреть несколько книг и источников, потому что, если кто-то утверждает что-то таким образом, что я не понимаю, я всегда могу проконсультироваться с другим, чтобы узнать, имеет ли он смысл.Я предлагаю это:

Надежда, что помогает!

+0

1) '' (aardvark) 'является сокращением для' (quote (aardvark)) ', который обозначает литеральные данные. Было бы необычно использовать backquote для данных. Обратный кадр будет использоваться только для шаблона данных. 2) Lisp не использует слово * command *, это * оператор *. –

+0

Даже с backquote '\' (aardvark) 'не является сокращением для' (list 'aardvark) ', так как последний всегда будет создавать новый список. –

+0

Ах, спасибо @RainerJoswig. Я все еще чувствую разницу между тиками и обратными окнами. –

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