Как начинался компьютер
Компьютерная революция
Двоичный код
Разработки военных лет
Интегральные микросхемы
Микрокомпьютер
Персоны
Сеть
Язык компьютера
Развитие ПО
Гибкие системы
Средства разработки
Информатика
Вычислительная наука
Операционные системы
Искусственный интеллект
Предыстория
Поиск
Знания и рассуждения
Логика
Робототехника
 

 
Язык Лисп Печать
 
Вы можете сделать шаг к настоящей программе, напечатав код, который в качестве побочного эффекта выведет на стандартный вывод строку «Здравствуй, мир». Common Lisp предоставляет несколько путей для вывода данных, но самый гибкий - это функция FORMAT. FORMAT получает переменное количество параметров, но только два из них обязательны: указание, куда осуществлять вывод, и строка для вывода. В следующей главе Вы увидите, как строка может содержать встроенные директивы, которые позволяют вставлять в строку последующие параметры функции, а-ля printf или строку-% из Python. До тех пор, пока строка не содержит символа ~, она будет выводиться как есть. Если вы передадите t в качестве первого параметра, функция FORMAT направит свой вывод на стандартный вывод. Итак, выражение FORMAT для печати «Здравствуй, мир» выглядит примерно так:
 
CL-USER> (format t "Здравствуй, мир")
Здравствуй, мир
NIL
 
Стоит заметить, что результатом выражения FORMAT является NIL в строке после вывода «Здравствуй, мир». Этот NIL является результатом вычисления выражения FORMAT, напечатанного REPL. (NIL – это Lisp-версия false и/или null. Подробнее об этом рассказывается в главе 4.) В отличие от других выражений, рассмотренных ранее, нас больше интересует побочный эффект выражения FORMAT (в данном случае, печать на стандартный вывод), чем возвращаемое им значение. Но каждое выражение в Lisp вычисляется в некоторый результат.

Однако, до сих пор остается спорным, написали ли мы настоящую программу. Но вы ведь здесь. Вы видите восходящий стиль программирования, поддерживаемый REPL: вы можете можете экспериментировать с различными подходами и строить решения из уже протестированных частей. Теперь, когда у вас есть простое выражение, которое делает то, что вы хотите, нужно просто упаковать его в функцию. Функции являются одним из основных строительных материаллов в Lisp и могут быть определены с помощью выражения DEFUN подобным образом: 
 
CL-USER> (defun hello-world () (format t "hello, world"))
HELLO-WORLD
 
Выражение hello-world, следующее за DEFUN является именем функции. В главе 4 мы рассмотрим, какие именно символы могут использоваться в именах, но сейчас будет достаточно сказать, что многие символы, такие как «-», которые нелегальны в именах в других языках абсолютно легальны в Common Lisp. Это стандартный стиль «Lisp – not to mention more in line with normal English typography» – формирование составных имен с помощью дефисов, как в hello-world, вместо использования знаков подчеркивания, как в hello_world, или использованием заглавных букв внутри имени, как helloWorld. Скобки () после имени отделяют список параметров, который в данном случае пуст, так как функция не принимает аргументов. Остальное - это тело функции.

На одном уровне это выражение, подобно всем другим, которые вы видели, всего лишь еще одно выражение для чтения, вычисления и печати, осуществляемых REPL. Возвращаемое значение в этом случае - это имя только что определенной функции. Но, подобно выражению FORMAT, это выражение более интересно своими побочными эффектами, нежели возвращаемым значением. Однако, в отличие от выражения FORMAT, побочные эффекты невидимы: после вычисления этого выражения создается новая функция, не принимающая аргументов, с телом (format t «hello, world») и ей дается имя HELLO-WORLD.

Теперь, после определения функции, вы можете вызвать ее следующим образом: 
 
CL-USER> (hello-world)
hello, world
NIL
 
Вы можете видеть, что вывод в точности такой же, как при вычислении выражения FORMAT напрямую, включая значение NIL, напечатанное REPL. Функции в Common Lisp автоматически возвращают значение последнего вычисленного выражения.
 
Сохранение вашей работы

Вы могли бы утверждать, что это готовая программа «hello, world». Однако, остаётся одна проблема. Если вы выйдете из Lisp и перезапустите его, определение функции исчезнет. Имея такую изящную функцию, вы захотите сохранить вашу работу.

Это достаточно просто. вы просто должны создать файл, в котором сохраните определение. В Emacs вы можете создать новый файл, набрав C-x C-f и затем, когда Emacs выведет подсказку, введя имя файла, который вы хотите создать. Не особенно важно, где будет находиться этот файл. Обычно исходные файлы Common Lisp именуются с расширением .lisp, хотя некоторые люди предпочитают .cl вместо него.

Открыв файл, вы можете набирать определение функции, введённое ранее в области REPL. Обратите внимание, что после набора открывающей скобки и слова DEFUN, в нижней части окна Emacs SLIME подскажет вам предполагаемые аргументы. Точная форма зависит от используемой вами реализации Common Lisp, но вы вероятно увидите что-то вроде этого: 
 
(defun name varlist &rest body)
 
Сообщение будет исчезать, когда вы будете начинать печатать каждый новый элемент, и снова появляться после ввода пробела. При вводе определения в файл вы можете захотеть разбить определение после списка параметров так, чтобы оно занимало две строки. Если вы нажмете Enter, а затем Tab, SLIME автоматически выровняет вторую строку соответствующим образом:
 
(defun hello-world ()
(format t "hello, world"))
 
SLIME также поможет вам в согласовании скобок – как только вы наберете закрывающую скобку, SLIME подсветит соответствующую открывающую скобку. Или вы можете просто набрать C-c C-q для вызова команды slime-close-parens-at-point, которая вставит столько закрывающих скобок, сколько нужно для согласования со всем открытыми скобками.