Доброго времени суток, уважаемый читатель!
Перед каждым новичком в мире языка программирования Common Lisp
возникает проблема выбора среды разработки — Integrated Development Environment (далее, IDE).

Существует большое количество IDE для Common Lisp. Перечислим некоторые, самые распространенные, из них:

Для Знатоков
Знатоки могут возразить относительно последних двух пунктов списка.
Ведь, казалось бы, Lispbox = Emacs + Slime?!
Но, если внимательно посмотреть на сайт Lispbox, то, под ссылками для скачивания пакета, Вы увидите:
Last updated: February 6, 2011.

В данной статье я подробно расскажу как установить и настроить кроссплатформенную среду разработки для Common Lisp, как скачивать и устанавливать дополнительные библиотеки при помощи quicklisp — менеджера пакетов Common Lisp. Будет много полезных ссылок на ресурсы и материалы по языку.
Речь пойдет о связке GNU Emacs & Slime.
Если Вас интересует Common Lisp, Вам нужна кроссплатформенная, мощная, интерактивная Common Lisp IDE с блэкджеком и дамами дебаггером и дизассемблером (внезапно!), то, прошу под кат…



Выбор реализации Common Lisp


Common LispANSI стандартизированный язык программирования, не имеющий единой канонической реализации.
Приведу список основных реализаций:

Нам нужна кроссплатформенная, свободная, автивно развивающаяся реализация Common Lisp. Я выбрал SBCL.
Итак, начнем!!!

Подготовительные работы


MS Windows


  • Создаем директорию для GNU Emacs по адресу: C:\emacs\
  • Создаем директорию для SBCL по адресу: C:\sbcl\
  • Скачиваем последнюю версию GNU Emacs и распаковываем в директорию C:\emacs\
  • Скачиваем дистрибутив SBCL и устанавливаем в директорию C:\sbcl\
  • Заходим в директорию с GNU Emacs (C:\emacs\bin\), находим addpm.exe и запускаем его
    (добавит иконку запуска Emacs в меню Пуск)
  • Редактируем переменные окружения:
    • Создаем переменную окружения с названием HOME и значением
      C:\Users\%username%\
      , где %username% — имя Вашей учетной записи
    • Создаем переменную окружения с названием PATH и значением C:\emacs\bin\
  • Создаем пустой файл с названием .emacs в C:\Users\%username%\
  • Создаем пустую директорию C:\Users\%username%\.quicklisp\
  • Скачиваем файл quicklisp.lisp и размещаем его в директорию C:\Users\%username%\.quicklisp\

GNU/Linux (deb-based distributives)


  • Устанавливаем GNU Emacs:
    sudo aptitude install emacs
    sudo aptitude install emacs-goodies-el
    sudo aptitude install emacs24-el
    sudo aptitude install emacsen-common
    sudo aptitude install org-mode
    sudo aptitude install dict
    sudo aptitude install dict-freedict-eng-rus 
    
  • Устанавливаем SBCL:
    sudo aptitude install sbcl
    sudo aptitude install cl-clx-sbcl
    
  • Создаем пустой файл с названием .emacs в домашней директории ~/
  • Создаем пустую директорию ~/.quicklisp/
  • Скачиваем файл quicklisp.lisp и размещаем его в директорию ~/.quicklisp/


Настройка Emacs


Пора настроить Emacs для профессиональной работы с Common Lisp проектами.
Предупреждение
Вся дальнейшая ребота по настройке системы будет проходить в GNU Emacs.
Все, что приведено ниже относится и к MS Windows и к GNU/Linux.
Подразумевается владение основами редактирования в Emacs.

Откроем для редактирования файл .emacs. Поехали!
  • Дадим возможность Emacs определять опреационную систему, на которой он запущен:
    (defun system-is-linux ()
        "Linux system checking."
        (interactive)
        (string-equal system-type "gnu/linux"))
    
    (defun system-is-mac ()
        "Mac OS X system checking."
        (interactive)
        (string-equal system-type "darwin"))
    
    (defun system-is-windows ()
        "MS Windows system checking."
        (interactive)
        (string-equal system-type "windows-nt"))
    
  • Создадим переменные, содержащие путь до исполняемых файлов SBCL:
    ;; Paths (for Common Lisp compiler - SBCL)
    (setq unix-sbcl-bin    "/usr/bin/sbcl")
    (setq windows-sbcl-bin "C:/sbcl/sbcl.exe")
    
  • Настроим пакетный менеджер Emacs:
    ;; Package manager:
    ;; Initialise package and add Melpa repository
    (require 'package)
    (add-to-list 'package-archives
                 '("melpa" . "http://melpa.org/packages/") t) ;; Добавляем ресурс Melpa
    (package-initialize) ;; Инициализируем пакетный менеджер
    
    ;; Package list
    (defvar required-packages
      '(slime ;; Slime - IDE для Common Lisp, интегрированная с Emacs
        projectile ;; Удобный менеджер проектов
        auto-complete)) ;; Автодополнение
    
    ;; Require Common Lisp extensions
    (require 'cl)
    
    ;; Функция реализет проверку факта установки перечисленных выше пакетов:
    ;; slime, projectile, auto-complete
    (defun packages-installed-p ()
        "Packages availability checking."
        (interactive)
        (loop for package in required-packages
              unless (package-installed-p package)
                do (return nil)
              finally (return t)))
    
    ;; Автоматическая установка пакетов slime, projectile, auto-complete
    ;; при первом запуске Emacs
    ;; Auto-install packages
    (unless (packages-installed-p)
        (message "%s" "Emacs is now refreshing it's package database...")
        (package-refresh-contents)
        (message "%s" " done.")
        (dolist (package required-packages)
            (unless (package-installed-p package)
                (package-install package))))
    

    Теперь, когда Вы запустите Emacs снова, то начнется автоматическая загрузка и установка пакетов:
  • Настроим наши пакеты:
    (when (packages-installed-p)
    
        ;; Auto-complete
        (require 'auto-complete)
        (require 'auto-complete-config)
        (ac-config-default)
        (setq ac-auto-start        t)
        (setq ac-auto-show-manu    t)
        (global-auto-complete-mode t)
        (add-to-list 'ac-modes 'lisp-mode)
    
        ;; SLIME
        (require 'slime)
        (require 'slime-autoloads)
        (setq slime-net-coding-system 'utf-8-unix)
        (slime-setup '(slime-fancy slime-asdf slime-indentation))
        (if (or (file-exists-p unix-sbcl-bin) (file-exists-p windows-sbcl-bin))
            (if (system-is-windows)
                (setq inferior-lisp-program windows-sbcl-bin)
                (setq inferior-lisp-program unix-sbcl-bin))
            (message "%s" "SBCL not found..."))
        (add-to-list 'auto-mode-alist '("\\.cl\\'" . lisp-mode))
    
        ;; Projectile
        (require 'projectile)
        (projectile-global-mode))
    
  • Настроим отступы Lisp-кода:
    (setq-default lisp-body-indent 4)
    (setq lisp-indent-function 'common-lisp-indent-function)
    

Сохраняем файл .emacs и перезапускаем Emacs.
Emacs загрузит и установит Slime, Projectile и Auto Complete автоматически в директорию
C:\Users\%username%\.emacs.d\ для MS Windows и в директорию ~/.emacs.d/ в GNU/Linux.
Предупреждение
Написанный нами, только что, файл конфигурации .emacs является кроссплатформенным!
При переносе с Linux на Windows и наоборот, ничего не нужно менять!
Главное — расположить .emacs в нужную директорию (создание переменной окружения
HOME для MS Windows — обязательно!
).

Рано праздновать, нужно еще настроить quicklisp — пакетный менеджер Common Lisp.

Установка и настройка quicklisp


Quicklisp — пакетный менеджер языка Common Lisp.
  • В запущенном Emacs выполняем команду M-x slime (Alt-x slime);
    запустится среда разработки Common LispSlime
  • Выполним:
    ;; Подгрузим менеджер пакетов
    (load "~/.quicklisp/quicklisp.lisp")
    ;; Автоматический скачается и установится менеджер пакетов quicklisp
    ;; со всеми зависимостями
    (quicklisp-quickstart:install :path "~/.quicklisp/")
    ;; Создаст .sbclrc файл в домашней директории
    ;; и, при каждом запуске среды Slime/SBCL, будет подгружать
    ;; скаченные и установленные Вами пакеты и библиотеки
    (ql:add-to-init-file)
    

Для примера, установим пару библиотек для Common Lisp при помощи quicklisp:
  • библиотека создания графического интерфейса на основе Tk/Tcl:
    (ql:quickload 'ltk)
    
  • движок для регулярных выражений:
    (ql:quickload 'cl-ppcre)
    
  • работа с CSV форматом:
    (ql:quickload 'cl-csv)
    
  • работа с OpenGL:
    (ql:quickload 'cl-opengl)
    
  • работа с БД PostgreSQL:
    (ql:quickload 'postmodern)
    
  • Web-сервер:
    (ql:quickload 'hunchentoot)
    
  • реализация метода конечных элементов (FEM):
    (ql:quickload 'femlisp)
    
  • работа с матрицами:
    (ql:quickload 'clem)
    
  • обновление установленных библиотек и самого quicklisp:
    (ql:update-all-dists)
    (ql:update-client)
    

Для Common Lisp написано большое количество качественных библиотек на все случаи жизни.
При помощи quicklisp их легко установить и начать использовать.
Собственно, у Вас теперь есть все необходимое для того, чтобы с головой окунуться в мир Common Lisp!
Поздравляю!

Полезные ссылки




Спасибо за внимание!


Да пребудет с Вами Lisp...

Комментарии (12)


  1. Crandel
    08.06.2015 10:22
    +1

    не слышал чтобы в GNU/Linux использовалось sudo aptitude install для чего-либо. Только для debian-sourse дистрибутивов


    1. karlkorp Автор
      08.06.2015 18:42

      Прошу прощения, исправил.


  1. shock_one
    08.06.2015 12:13
    -1

    У меня есть вопрос о синтаксисе, и при этом не о скобках.
    Что вы думаете об удобочитаемости записей, которые нужно смотреть справа налево? Например,

    (to-customize (to-install Common-Lisp-IDE))
    


    В объектно-ориентированных языках это можно было бы записать как

    Common-Lisp-IDE.to-install.to-customize
    


    Это не относится непосредственно к LISP, в том же Haskell или C запись тоже «перевернутая». Привыкаете ли вы или со временем это продолжает вызывать дискомфорт, так как традиционно письменность в другую сторону.

    .LISP'e на писать легко арабам Наверное


    1. cosmrc
      08.06.2015 12:41

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

      Например в Скале пошли еще дальше — поубирали точки, и теперь можно писать

      names mkString ","
      

      вместо

      names.mkString(",")
      

      Но многие предпочитают такую запись не использовать.


      1. shock_one
        08.06.2015 12:48
        -1

        Но ведь теоретически можно сделать, чтобы функция была и самодостаточна и читалась слева направо.

        (((Common-Lisp-IDE) to-install) to-customize)
        


        Здесь точно так же как в LISP'e, только последний аргумент, а не первый, считается функцией.

        В Scala очень даже используют функции без точек

        names ++ otherNames
        


        Anyways, вопрос в том, удобно ли читать справа налево.


    1. wombtromb
      08.06.2015 13:41

      Это скорее вопрос нотации.

      toCustomize( toInstall(CL_IDE) )
      


      Тоже выглядит не особо.

      Есть достаточно общее решение композиции функций. В Clojure для этого есть специальная функция ->:
      (-> Common-lisp-IDE to-install to-customize)
      

      Будучи макросом, тоже самое можно сделать и в CL.


      1. shock_one
        08.06.2015 13:47
        -1

        Я не говорю, что проблема с скобках. Я сам согласился, что к C такой же вопрос.

        Конечно, можно написать макрос. Но как говорят, «in Rome, do as Romans do», «со своим уставом в чужой монастырь не ходят». Это как в каком-то Ruby возвращать два значения, где второе — ошибка, как принято в Go.

        Все пишут справа налево, так здесь принято. Но удобно ли читать такой код?


    1. karlkorp Автор
      08.06.2015 18:47

      По мне, так дело только в привычке…
      Просто я перестроил моё «миропонимание» таким образом: функция — первый элемент списка, остальное — аргументы (привет от Капитана Очевидность:-).
      Просто нужно привыкнуть…


  1. wombtromb
    08.06.2015 13:58

    Да я тоже не про скобки, я про то, что наличие функций как обьектов первого класса дает возможность строить элегантные конструкции, которые более идиоматичны для CL, чем цепочка вызовов. Хотя, усли вызовов двое, как в примере выше, то вприцнипе, ничего страшного нет и я сам регулярно так делаю. Но если действительно цепочка вызовов — то без композиции функций очень сложно понять кто что получает и кто что ожидает получить, особенно, если arity функций не всегда равен 1.

    Все пишут справа налево, так здесь принято.


    Вообще, тезис сильный. Я, например, стараюсь использовать композиции и частичное применение, привыкать к неудобному — не очень полезно.


    1. shock_one
      08.06.2015 14:59
      -1

      Могу ли я сделать вывод из вашего сообщение, что несмотря на опыт, запись справа налево остается неудобной, особенно если параметров несколько?


      1. wombtromb
        08.06.2015 15:25

        Не могу говорить за сообщество, но лично за себя ответ «да, мне неудобно».


  1. PerlPower
    08.06.2015 19:37

    Скажите, а куда можно пойти работать лисповиком в России/Украине/Белоруссии или по удаленке? Понятно, что софта на лиспе хватает, но интересует именно коммерческая сторона вопроса для среднего программиста.