Как писать программу на lisp

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

Восемь характеристик [1] [2] , которые отличают Лисп от других языков [3] :

  1. Встроенная поддержка списков;
  2. Автоматическое управление памятью;
  3. Динамическая типизация;
  4. Функции первого класса (first class functions);
  5. Единообразный синтаксис;
  6. Интерактивная среда;
  7. Расширяемость;
  8. История.

Диалекты LISP

У Лиспа есть два основных диалекта:

  • Common LISP — более навороченный (Будда большой, весёлый, с волосатыми подмышками);
  • Scheme — более ясный и простой (Будда маленький, аккуратный и улыбается);

Три важных признака, отличающих Scheme от CL:

Язык LISP для студентов и инженеров. Первая программа

  • наличие функции call-with-current-continuation, которая позволяет сделать переход в коде, а потом вернуться назад, с восстановлением сохранённого состояния;
  • хвостовая рекурсия;
  • гигиеничные макросы.

Кроме этого, есть ещё один, сравнительно недавно появившийся и ставший особенно популярным в последнее время, диалект:

  • Clojure, LISP-диалект с поддержкой макросов, ориентированный на использование с JVM.

Примеры кода

Самая простая программа:

#!/usr/bin/clisp (print «Hello, world»)

Вычисление факториала (использование рекурсии):

#!/usr/bin/clisp (defun fact (x) (cond ((eq x 1) 1) (t (* x (fact (- x 1)))))) (print (fact 5))

Юмор

По музыкальной классификации языков [4] Лисп можно сравнить с прогметаллом (я бы даже сказал — с прогроком).

Дополнительная информация

Идеологическая база

Что можно почитать, если вы хотите убедиться, что Lisp стоит выучить:

  • Beating the Averages (англ.) ­— статья Пола Грехема (Paul Graham), который рассказывает почему Лисп стоит использовать в стартапах; и как с его помощью вы сразу начнёте обгонять конкурентов
  • The Nature of Lisp (англ.) — объяснение на примере современных технологий и инструментов, показывающее что Лисп очень мощный и интересный язык
  • Why Lisp macros are cool, a Perl perspective (англ.) — почему макросы в Лиспе это круто, от автора книги High-Order Perl

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

  • On the Relationship Between Python and Lisp (англ.) — рассказ о том, что Python совсем не пытается догнать и перегнать Lisp, а идёт своей дорогой
  • How I lost my Faith (англ.) — история Эранна Гата (Erann Gat), в которой он рассказывает, как он понял, что Lisp — не самый крутой язык на свете
  • Lisping at JPL (англ.) — опять Эранн Гат (Erann Gat); история успеха и падения Лиспа в JPL (Jet Propulsion Labs); как писали на лиспе код для марсоходов и удалённо правили ошибки на станции Deep Space 1, летевшей на расстоянии 100 миллионов миль от Земли; и потом как всё это печально кончилось, что Лисп в JPL оказался никому не нужным. «I can’t even say the word Lisp without cementing my reputation as a crazy lunatic who thinks Lisp is the Answer to Everything. So I keep my mouth shut (mostly) and watch helplessly as millions of tax dollars get wasted.»

Микрообзоры и заметки

  • Before you start learning Lisp (англ.) — несколько маленьких фактов, которые желательно иметь в виду, перед тем как начинать пробовать играться с Лиспом
  • A Quickstart to Common Lisp (англ.) — маленькое введение в Lisp, рассмотрено несколько простейших конструкций, приведён небольшой список инструментов, с которых можно начать

Руководства по использованию

  • The Revised6 Report on the Algorithmic Language Scheme (англ.) — стандарт языка Scheme
  • Basic Scheme (англ.) — простейшее введение в Scheme, рассчитанное на тех, кто собирается писать модули расширения для GIMP; подойдёт любому начинающему разбираться с Scheme; рассмотрены только самые простейшие вещи
  • Common Lisp the Language (англ.) , Guy L. Steele Jr.

Форматирование и оформление кода

Q: How can you tell when you’ve reached Lisp Enlightenment?

Читайте также:
Программа для занижения авто на Андроид

Пример простой программы на LISP

A: The parentheses disappear.

  • Riastradh’s Lisp Style Rules, Taylor R. Campbell (англ.) — правила по форматированию и оформлению кода на Лиспе; общепринятый и собственные правила и рекомендации автора
  • 4. Syntax and Semantics (англ.) — глава книги Practical Common Lisp

Среды разработки

  • limp (англ.) — модуль расширения к Vim, с помощью которого можно писать и отлаживать программы на Лиспе; что-то типа SLIME, но для Vim (не забудьте filetype plugin on)

Книги по Лиспу

  • On Lisp, Paul Graham
  • ANSI Common Lisp, Paul Graham
  • Practical Common Lisp
  • Practical Common Lisp (англ.) , видео
  • Structure and Interpretation of Computer Programs (англ.) , видео

Сравнение Lisp и Scheme между собой и с другими языками

  • Python vs. Scheme (англ.)
  • Differences between Scheme and Common Lisp (англ.)

Lisp как средство для изучения программирования

  • mal — Make a Lisp, очень интересный проект: интерпретатор Lisp на множестве языков

Примечания

  1. ↑ по мнению Питера Норвига, изложенному в труде Paradigms of Artificial Intelligence Programming: Case Studies in Common Lisp
  2. ↑ И девять других (хотя и не совсем других) по мнению Пола Грехема
  3. ↑ но не от всех, конечно же; например в Perl из этих восьми отличий остаётся только одно
  4. ↑http://piranha.org.ua/blog/2008/05/10/musical-languages/

Источник: xgu.ru

Как начать писать код на Lisp?

Часто приходится видеть, как новички пробуют Common Lisp и потом жалуются, что с ним невозможно нормально работать. Как правило, это происходит из-за того, что они не понимают как настроить себе процесс, обеспечивающий тот самый «быстрый отклик» от среды разработки, когда ты поменял функцию, скомпилировал её и изменения тут же начали использоваться внутри уже «бегущей» прогрммы без её перезапуска.

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

Сегодня я хочу показать, как настроить себе dev окружение для такой разработки. В 2018 году это стало совсем просто, благодаря постоянно улучшающемуся тулингу.

Заранее прошу прощения за то, что следующие ролики записаны в Asciinema, а Habrahabr его не поддерживает. Кликайте на скриншоты консоли, чтобы посмотреть ролики.

Для начала, надо установить SBCL, Roswell и Emacs. Рассказывать я буду на примере установки всего в OSX, и буду рад если в комментариях вы поделитесь своим опытом на Windows и Linux. Тогда я смогу дополнить статью примерами для всех трех платформ.

SBCL это одна из многочисленных реализаций Common Lisp. Из опенсорсных — самая быстрая. При желании, на SBCL можно запускать код по скорости сопоставимый с кодом на C++, но при этом имея все плюшки от быстрой интерактивной разработки.

Roswell, это утилита, для установки и запуска Common Lisp программ. В том числе она умеет запускать преднастроенный Emacs, а так же собирать программы в бинарники.

Emacs вы наверняка знаете — такая операционная система, в которой есть и редактор кода. Можно писать на Common Lisp и в любом другом редакторе, но на сегодняшний день у Emacs лучшая интеграция и поддержка смантического редактирования кода. С ним вам не придётся считать скобочки, он всё делает за вас.

Итак, если вы используете OSX, то нужно сделать

brew install roswell emacs

После того, как brew пошуршит диском и поставит всё нужное, просто запустите в терминале:

ros run

Эта команда автоматически поставит вам последнюю версию SBCL и стартует Lisp repl, куда можно вводить код:

Но это не дело, разрабатываться так нелья. Поэтому давайте настроим Emacs для полноценной разработки:

ros emacs

Команда запустит Emacs в консоли и настроит Quicklisp — пакетный менеджер для Common Lisp.
Но прежде чем мы продолжим, давайте настроим терминал, emacs и OSX так, чтобы они хорошо работали вместе.

Сначала надо в OSX и iTerm поменять некоторые настройки

Делаем так, чтобы CapsLock работал как Control. В Emacs без этого — никуда:

Затем отключить в шоткатах MissionControl все комбинации, связанные с использованием Control и стрелок:

Затем поставить iTerm2 и переключить в настройках профиля поведение Alt с Normal на Esc+:

После чего, создать файлик с минимальным конфигом для Emacs, ~/.emacs.d/init.el :

(package-initialize) (require ‘package) (add-to-list ‘package-archives ‘(«MELPA» . «http://melpa.milkbox.net/packages/») t) (defun install-package (package) (unless (package-installed-p package) (package-refresh-contents) (package-install package))) (install-package ‘paredit) (install-package ‘expand-region) (defun setup-lisp-mode () (require ‘paredit) (paredit-mode) (define-key paredit-mode-map (kbd «C-w») ‘paredit-backward-kill-word)) (add-hook ‘lisp-mode-hook ‘setup-lisp-mode) (add-hook ’emacs-lisp-mode-hook ‘setup-lisp-mode) ;; используем C-w для удаления слова с опечаткой и последующего набора его заново ;; вместо kill-region (global-set-key (kbd «C-w») ‘backward-kill-word) ;; вместо кучи команд начинающихся с kmacro- (global-set-key (kbd «C-x C-k») ‘kill-region) ;; вместо indent-new-comment-line (global-set-key (kbd «M-j») (lambda () (interactive) (join-line -1))) ;; поиск и замена (global-set-key (kbd «C-c r s») ‘replace-string) (global-set-key (kbd «C-c r r») ‘replace-regexp) ;; по этому сочетанию emacs начинает выделять формы ;; и дальше можно просто нажимать =, чтобы расширить ;; выделение на родительскую форму. (global-set-key (kbd «C-c =») ‘er/expand-region) ;; это сочетание удобно использовать с предыдущим, ;; чтобы быстро выделить и закомментировать кусок кода (global-set-key (kbd «C-c c») ‘comment-or-uncomment-region) (global-set-key (kbd «C-c C-\») ‘goto-last-change) (setq custom-file «~/.emacs.d/customizations.el») (when (file-exists-p custom-file) (load custom-file))

Читайте также:
Можно ли вернуть деньги за лицензию на программу

После чего, снова запускаем ros emacs, жмём Alt-X и вводим команду slime . В результате получаем командную строку для ввода лисповых команд:

Теперь можно уже кодить

Но мы не будем вводить команды в репл, лучше сразу приступим к разработки микросервиса. Если нужно только API, то проще всего использовать Ningle. Если нужен более продвинутый фреймворк, типа джанги, то можно попробовать Radiance или Caveman2. Но сейчас не будем делать ничего сложного, а замутим простую HTTP апишечку.

Откройте в Emacs файл server.lisp ( C-x C-f server.lisp ) и начинайте писать код. Примерно так:

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

Вот весь код, для ленивых:

;; Micro-framework for building API (ql:quickload :ningle) ;; Now ningle is installed and we need to install a clack which is analog of WSGI ;; stack from Python ;; I’ve pressed C-c C-c to eval this form (ql:quickload :clack) ;; To parse json: (ql:quickload :jonathan) (defvar *app* (make-instance ‘ningle:)) (setf (ningle:route *app* «/») ;; in case, if you need to parse or serialize JSON, ;; use Jonthan library. (jonathan:to-json ‘(:foo 100500))) (defvar *server* nil «This variable will store currently running server instance.») (defun start () (if *server* (format t «Server already started») (setf *server* (clack:clackup *app*)))) (defun stop () (if *server* (clack:stop *server*) (format t «Server is not running»)))

В Лиспе конструкции, которые внутри скобочек, называются “формами”. Формы, которые на верхнем и не вложены ни в какие другие, называются top-level. Такие формы можно компилировать нажав сочетание C-c C-c , когда курсор находится внутри такой формы. Если вы перебиндили CapsLock на Сontrol , то это сочетание очень удобно нажимать.

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

Если вам интересны ещё какие-то темы, пишите в комментариях, постараюсь сделать посты и про них.

Источник: habr.com

Как писать программу на lisp

Библиотека сайта rus-linux.net

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

Префиксная нотация Lisp-а более удобна для программистов. Например, если вы хотите сложить вместе пять чисел, то в обычной нотации (и обычном языке программирования) вы должны использовать оператор + четыре раза:

1 + 2 + 3 + 4 + 5

. тогда как в Lisp-е, вы просто еще добавляете аргументы:

> (+ 1 2 3 4 5) 15

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

S-выражения состоят из списков и атомов. Списки ограничиваются скобками и могут содержать любое количество элементов, разделенных пробелами. Все остальное — атомы. Элементы списков сами могут быть s-выражениями (иными словами, атомами или вложенными списками). Подробнее о списках и атомах будет рассказано в следующей статье.

Комментарии, которые, с технической точки зрения, не являются s-выражениями, начанаются с точки с запятой и продолжаются до конца строки и, по существу, трактуются как пробелы.

Читайте также:
Как нужно оформить программу чтобы люди захотели в ней участвовать

> ;demo of multiplication operator (* 3 7) 21

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

Предположим, вы хотите вычислить значение ((4*5)/(2+3)) , тогда эквивалентное s-выражение в Lisp-е будет следующим:

> (/ (* 4 5) (+ 2 3)) 4

Вычисление

Lisp вычисляет все. Он даже вычисляет собственные аргументы. В Lisp вычисляются даже сами числа, то есть, в любое время Lisp пытается вычислить 1, ответ всегда равен 1.

> 1 1 > 2 2

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

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

Если какие-нибудь из аргументов сами являются вызовами функций, то они вычисляются по тем же самым правилам. Так что, когда вычисляется (/ (* 4 5) (+ 2 3)) , то происходит следующее:

  1. Lisp вычисляет (* 4 5) : 4 вычисляется как 4, а 5 вычисляется как 5. Эти значения передаются функции *, которая возвращает 20.
  2. Lisp вычисляет (+ 2 3) : 2 вычисляется как 2, а 3 вычисляется как 3. Эти значения передаются функции +, которая возвращает 5.
  3. Значения 20 и 5 направляются в функцию /, которая возвращает 4.

Не все операторы в Common Lisp являются функциями, но большая их часть является. И вызовы функции всегда вычисляются таким образом. Аргументы вычисляются слева направо, а их значения передаются в функцию, которая возвращает общее значение выражения. Это в Common Lisp называется правилом вычисления.

Lisp является несколько необычным в том, что практически все, что делается, выполняется с помощью функций. На самом деле, в Lisp действительно нет ничего другого. Вся сложность Lisp-а определяется отдельными функциями, которые присутствуют в Lisp, а также деталями того, как различные типы функций обрабатываются интерпретатором.

Обращайтесь за помощью!

Если вы наберете что-нибудь, что Lisp не сможет понять, то появится сообщение об ошибке, и вы перейдете в программу, которая называется отладчиком.

В обычном отладчике Lisp-а есть возможность приостановить вычисление. Когда вычисление приостановлено (состояние, обычно известное, как разрыв цикла), вы можете изучить содержимое стека времени исполнения, проверить значения локальных или глобальных переменных или изменить эти значения.

То, как работает отладчик, не определяется самим Common Lisp, как таковой. Это больше то, что осталось от создания различных реализаций Common Lisp. Например, нет единого стандарта Common Lisp, который бы указывал, что должно изображаться в строке-приглашении после возникновения ошибки. Нет стандартизации команд, которые должен понимать отладчик. В некоторых реализациях, пользователь обычно вообще не набирает никаких команд; для этой цели просто зарезервированы специальные клавиши.

В CLISP для того, чтобы выйти из прерванного цикла и вернуться на верхний уровень toplevel, просто наберите :q так, как это показано ниже:

1]> (/ 1 0) *** — /: division by zero The following restarts are available: ABORT :R1 Abort main loop Break 1 [2]> :q [3]>

Вы должны узнать, какой эквивалент команды :q реализован в вашем варианте Lisp. Поэкспериментируйте, ознакомьтесь с руководством по эксплуатации или обратитесь к местному эксперту.

Что дальше?

Все фанаты фильма X-Men соглашаются со мной, когда я говорю, что последнее дополнение к серии — X Men First Class — оказалось еще лучше. Что может быть лучше, чем узнать о происхождении героев и сюжетной линии, которую вы полюбили. Кажется это, на самом деле, тенденция в Голливуде, коснувшаяся таких фильмов, как Звездные Войны, Бетмен и т.д.

Я буду следовать этой тенденции и в третьей статье дам вам представление об эволюции Lisp. Скромное начало для языка, который вам уже стал нравиться (если вы все еще читаете эту статью, то, вероятно, это произошло, или это просто мое собсвенное самоуспокоение, которого вам недостаточно?!).

Я также подберу темп изложения, поскольку мы только прошлись по самой поверхности языка Lisp.

Источник: rus-linux.net

Рейтинг
( Пока оценок нет )
Загрузка ...
EFT-Soft.ru