Перейти к основному содержимому

5.16. Первая программа

Разработчику Архитектору Инженеру

Первая программа

Lisp — один из самых влиятельных языков программирования в истории вычислительной техники. Он был создан в конце 1950-х годов Джоном Маккарти как инструмент для символических вычислений и исследования искусственного интеллекта. С самого начала Lisp задумывался не просто как средство записи инструкций для машины, а как язык, способный описывать сам себя. Эта рефлексивность, или способность программы манипулировать собственным кодом как данными, стала одной из ключевых черт Lisp-семейства.

Сегодня Lisp существует во множестве диалектов: Common Lisp, Scheme, Clojure, Racket и другие. Каждый из них сохраняет фундаментальные идеи оригинала, но адаптирует их под современные задачи — от веб-разработки до системного программирования и научных вычислений. Несмотря на возраст, Lisp остаётся живым, гибким и мощным инструментом, особенно в тех областях, где важна выразительность, метапрограммирование и интерактивная разработка.

Написание первой программы на Lisp — это не просто технический ритуал. Это знакомство с иной парадигмой мышления: здесь нет жёсткого разделения между данными и кодом, между программой и её окружением. Программа на Lisp — это живой процесс, который можно наблюдать, изменять и расширять в реальном времени.

Почему начинать с Common Lisp?

Из всех диалектов Lisp наиболее подходящим для первого знакомства считается Common Lisp. Это стандартизированный, зрелый и универсальный язык, поддерживающий как функциональное, так и императивное программирование. У него богатая стандартная библиотека, мощная система макросов и развитая экосистема. Common Lisp работает на всех основных платформах, включая Windows, macOS и Linux, и имеет несколько высококачественных реализаций.

Для новичка особенно важно, что Common Lisp предоставляет интерактивную среду разработки — REPL (Read-Eval-Print Loop). Это цикл «чтение–вычисление–вывод», позволяющий немедленно видеть результат любого выражения, экспериментировать с кодом и постепенно строить программу шаг за шагом. Такой подход кардинально отличается от традиционного компиляции-запуска и делает обучение более наглядным и естественным.

Подготовка среды на Windows

Windows полностью поддерживает разработку на Common Lisp. Для этого потребуется установить реализацию языка, текстовый редактор или интегрированную среду разработки, а также, при желании, дополнительные инструменты для удобства работы.

Шаг 1: Выбор реализации Common Lisp

Наиболее популярные и стабильные реализации Common Lisp:

  • SBCL (Steel Bank Common Lisp) — высокопроизводительная, оптимизированная реализация с открытым исходным кодом. Работает на Windows через MinGW или WSL, но требует немного больше усилий при настройке.
  • CLISP — портируемая, простая в установке реализация, которая отлично подходит для обучения. Поддерживает Unicode и работает нативно на Windows.
  • CCL (Clozure Common Lisp) — быстрая и надёжная реализация с отличной поддержкой многопоточности и отладки. Имеет версию для Windows.
  • Allegro CL и LispWorks — коммерческие реализации с продвинутыми IDE, но они менее подходят для первого знакомства из-за лицензионных ограничений.

Для старта рекомендуется CLISP или CCL, так как они проще всего устанавливаются на чистую Windows-систему без дополнительных зависимостей.

Шаг 2: Установка CLISP на Windows

  1. Перейдите на официальный сайт CLISP: https://clisp.sourceforge.io/
  2. В разделе Download найдите последнюю версию для Windows. Обычно это архив в формате .zip или установщик .exe.
  3. Скачайте файл, например clisp-2.49.zip.
  4. Распакуйте архив в удобную папку, например C:\clisp\.
  5. Добавьте путь к исполняемому файлу в переменную среды PATH:
    • Откройте «Панель управления» → «Система» → «Дополнительные параметры системы».
    • Нажмите «Переменные среды».
    • В разделе «Системные переменные» найдите Path, нажмите «Изменить».
    • Добавьте новый путь: C:\clisp\ (или тот, куда вы распаковали).
  6. Перезапустите командную строку (cmd) или PowerShell.
  7. Проверьте установку, выполнив в терминале:
    clisp --version
    Если вывод показывает версию CLISP, установка прошла успешно.

Альтернативно, можно использовать CCL:

  1. Перейдите на https://ccl.clozure.com/
  2. Скачайте Windows-версию (обычно .zip-архив).
  3. Распакуйте, например, в C:\ccl\.
  4. Добавьте C:\ccl\ в PATH.
  5. Запустите wx86cl.exe (графическая версия) или wx86cl.exe -b (консольная).

Шаг 3: Выбор редактора или IDE

Common Lisp не требует специальной IDE, но использование редактора с поддержкой Lisp значительно упрощает работу. Наиболее подходящие варианты для Windows:

  • Emacs + SLIME — классическая связка для Lisp-разработчиков. SLIME (Superior Lisp Interaction Mode for Emacs) превращает Emacs в полноценную среду разработки с REPL, отладчиком и автодополнением. Установка требует настройки, но даёт максимальную гибкость.
  • VS Code + Calva или Language Support for Common Lisp — современный подход. Visual Studio Code с соответствующими расширениями обеспечивает подсветку синтаксиса, навигацию по коду и интеграцию с REPL.
  • LispIDE — лёгкая нативная IDE для Windows, работающая с CLISP и CCL.
  • Notepad++ — минималистичный вариант с подсветкой синтаксиса, если требуется только редактирование файлов.

Для первого знакомства подойдёт VS Code благодаря простоте установки и интуитивному интерфейсу.

Установка VS Code и настройка для Common Lisp:

  1. Скачайте и установите VS Code: https://code.visualstudio.com/
  2. Откройте VS Code, перейдите в раздел расширений (Extensions).
  3. Найдите и установите расширение “Language Support for Common Lisp” от Masataro Kurauchi.
  4. Перезапустите VS Code.
  5. Создайте новый файл с расширением .lisp, например hello.lisp.

Теперь редактор будет распознавать синтаксис Lisp и подсвечивать ключевые слова.

Шаг 4: Запуск REPL

REPL — сердце Lisp-разработки. Это интерактивная консоль, где можно вводить выражения и сразу видеть результат.

Чтобы запустить REPL:

  • Откройте командную строку (cmd) или PowerShell.
  • Введите:
    clisp
    или
    wx86cl -b
    в зависимости от выбранной реализации.

Вы увидите приглашение вроде:

[1]>

Это означает, что REPL готов принимать команды. Теперь можно вводить любые выражения на Lisp и наблюдать за их вычислением.

Например, попробуйте:

(+ 2 3)

Нажмите Enter. REPL выведет:

5

Это демонстрирует базовый принцип: каждое выражение в Lisp — это вызов функции, записанный в префиксной форме. Оператор + применяется к аргументам 2 и 3, и результат возвращается немедленно.


Написание первой программы: «Hello, World!»

В большинстве языков программирования первая программа выводит фразу «Hello, World!» на экран. В Lisp эта задача решается с помощью функции print, которая принимает значение и выводит его в стандартный поток вывода, обычно сопровождая его символом новой строки и возвращая то же значение.

Создадим файл hello.lisp. Откройте выбранный редактор (например, VS Code) и введите следующее:

(print "Hello, World!")

Это полная программа. Она состоит из одного выражения — вызова функции print с аргументом "Hello, World!". Строки в Lisp заключаются в двойные кавычки, как и во многих других языках.

Сохраните файл, например, в папке C:\lisp-projects\hello.lisp.

Запуск программы из командной строки

Common Lisp позволяет выполнять скрипты напрямую из терминала. Для этого используется флаг -x (в CLISP) или аналогичные механизмы в других реализациях.

Откройте командную строку и перейдите в папку с файлом:

cd C:\lisp-projects

Затем выполните:

clisp -x "(load \"hello.lisp\")"

Обратите внимание на экранирование кавычек внутри команды. Альтернативный и более простой способ — использовать флаг -i, который загружает файл и запускает REPL:

clisp hello.lisp

В этом случае CLISP загрузит содержимое файла и сразу выведет результат выражения:

"Hello, World!"

Функция print выводит строку в кавычках, потому что она предназначена для отладки и представления данных в читаемой форме, включая синтаксис Lisp. Если требуется вывести текст без кавычек, используется функция write-line:

(write-line "Hello, World!")

Теперь при запуске:

clisp hello.lisp

Результат будет:

Hello, World!

Без кавычек, как ожидается от традиционного «Hello, World!».

Запуск через REPL

Другой способ — интерактивный. Запустите REPL:

clisp

Затем загрузите файл вручную:

(load "C:/lisp-projects/hello.lisp")

Lisp воспримет путь как строку. Обратите внимание: в Windows можно использовать прямые слэши / вместо обратных \, что упрощает запись и избегает необходимости экранирования.

После выполнения load программа запустится, и вы увидите вывод в REPL. Преимущество этого подхода — возможность продолжить работу в той же сессии: определить новые функции, вызвать их, исследовать состояние программы.

Понимание структуры программы

Программа на Lisp строится из S-выражений (symbolic expressions). Каждое S-выражение — это либо атом (число, строка, символ), либо список, заключённый в круглые скобки. Список всегда начинается с функции или макроса, за которым следуют аргументы.

Выражение (write-line "Hello, World!") — это список из двух элементов:

  • первый — символ write-line, обозначающий функцию;
  • второй — строка "Hello, World!", передаваемая как аргумент.

Такая форма называется префиксной нотацией: оператор стоит перед операндами. Это обеспечивает однозначность синтаксиса и упрощает парсинг.

Важно: в Lisp нет специального синтаксиса для управляющих конструкций, таких как if, while или defun. Все они реализованы как специальные формы или макросы, которые выглядят точно так же, как обычные вызовы функций, но обрабатываются компилятором особым образом. Это делает язык единообразным и расширяемым.

Создание исполняемого скрипта (опционально)

Хотя Common Lisp не предназначен в первую очередь для создания standalone-исполняемых файлов, некоторые реализации позволяют это сделать. Например, SBCL может скомпилировать программу в бинарник. В CLISP и CCL также есть механизмы сохранения образа системы.

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

Если вы хотите упростить запуск, создайте пакетный файл run-hello.bat в той же папке:

@echo off
clisp hello.lisp
pause

Теперь двойной клик по run-hello.bat запустит программу в отдельном окне командной строки и дождётся нажатия клавиши перед закрытием — удобно для пользователей Windows.

Что происходит при выполнении программы?

Когда вы запускаете clisp hello.lisp, происходит следующее:

  1. Интерпретатор CLISP запускается.
  2. Он читает содержимое файла hello.lisp.
  3. Каждое выражение в файле последовательно оценивается (evaluated).
  4. Выражение (write-line "Hello, World!") передаётся в функцию write-line.
  5. Функция отправляет строку в стандартный поток вывода (stdout).
  6. Программа завершается, и управление возвращается операционной системе.

В отличие от языков с явной точкой входа (например, main() в C), в Lisp программа — это просто последовательность выражений, выполняемых сверху вниз. Это упрощает написание скриптов и экспериментальных фрагментов кода.

Расширение программы: добавление взаимодействия

Чтобы продемонстрировать интерактивность Lisp, можно модифицировать программу, чтобы она спрашивала имя пользователя и приветствовала его персонально:

(write-line "What is your name?")
(let ((name (read-line)))
(write-line (concatenate 'string "Hello, " name "!")))

Здесь:

  • read-line считывает строку из стандартного ввода.
  • let создаёт локальную переменную name.
  • concatenate объединяет строки.

Сохраните изменения и запустите программу. Теперь она будет ждать ввода и реагировать на него — пример простого диалога.