Одним из простых способов начать программирование является изучение некоторых типичных взаимодействий с интерпретатором диалекта Scheme языка Lisp. Представьте, что вы сидите за компьютерным терминалом. Вы вводите выражение, а интерпретатор отвечает, отображая результат вычисления этого выражения.

Одним из видов примитивного выражения, которое вы можете ввести, является число. (Точнее, выражение, которое вы набираете, состоит из цифр, представляющих число по основанию 10.) Если вы представляете Lisp число: 486

интерпретатор ответит, напечатав

486

Выражения, представляющие числа, могут быть объединены с выражением, представляющим примитивную процедуру (например, + или *), чтобы сформировать составное выражение, представляющее применение процедуры к этим числам. Например:

: (+ 137 349)
: 486
: (- 1000 334)
: 666
: (* 5 99)
: 495
: (/ 10 5)
: 2
: (+ 2.7 10)
: 12.7

Выражения, подобные этим, образованные путем ограничения списка выражений в круглых скобках для обозначения применения процедуры, называются комбинациями. Крайний левый элемент в списке называется =operator=, а остальные элементы называются =operands==. Значение комбинации получается путем применения процедуры, указанной оператором, к аргументам, являющимся значениями операндов.

Соглашение о размещении оператора слева от операнда известно как ~префиксная нотация~,

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

#+begin_src emacs-lisp :results output
(+ 21 35 12 7)
(* 25 4 12)
#+end_src

~Никакой двусмысленности не может возникнуть~,

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

Второе преимущество префиксной нотации заключается в том, что она расширяется прямым способом, позволяя вкладывать комбинации, то есть иметь комбинации, элементы которых сами являются комбинациями:

(+ (* 3 5) (- 10 6))
19

Нет ограничений (в принципе) на глубину такой вложенности и на общую сложность выражений, которые интерпретатор Лиспа может вычислить. Это нас, людей, сбивают с толку все еще относительно простые выражения, такие как

(+ (* 3 (+ (* 2 4) (+ 3 5))) (+ (- 10 7) 6))

которое интерпретатор с готовностью оценил бы равным 57. Мы можем помочь себе, написав такое выражение в форме

#+begin_src emacs-lisp :tangle yes
(+ (* 3
 (+ (* 2 4)
 (+ 3 5)))
 (+ (- 10 7)
 6))
#+end_src

следуя соглашению о форматировании, известному как *красивая печать*, в котором каждая длинная комбинация записывается так, чтобы операнды были выровнены по вертикали. Полученные отступы четко отображают структуру выражения.

Даже со сложными выражениями интерпретатор всегда работает в одном и том же базовом цикле: он считывает выражение с терминала, вычисляет выражение и печатает результат. Этот режим работы часто выражается в том, что интерпретатор работает в цикле *чтение-оценка-печать*. Заметьте, в частности, что нет необходимости явно указывать интерпретатору напечатать значение выражения.