"Величайший из когда-либо созданных языков программирования"
— Alan Kay, «on Lisp»



Когда Маккарти разработал Lisp в конце 1950-х, он радикально отличался от существующих языков, самым главным из которых был Fortran.

Lisp воплотил девять новых идей:

1. Условные высказывания (Conditionals). Условные высказывания это if-then-else конструкция. Сейчас мы воспринимаем их как должное. Они были изобретены Маккарти во время разработки Lisp. (Fortran в то время имел только goto-утверждения, тесно связанные с инструкцией ветвления на лежащем в основе железе.) Маккарти, будучи в комитете по Algol, внёс условные высказывания в Algol, откуда они распространились на другие языки.

2. Функциональные типы (A function type). В Lisp'е функции это объекты первого класса — они являются типом данных, также как числа, строки и т.д., и имеют буквальное представление, могут храниться в переменных, могут быть переданы как аргументы, и.т.д.

3. Рекурсия (Recursion). Рекурсия, конечно, существовала как математическая концепция до Lisp'а, но Lisp был первым языком программирования поддерживающим её. (Это возможно подразумевается в создании функций как объектов первого класса.)

4. Новая концепция переменных (A new concept of variables). В Lisp'е все переменные являются эффективными указателями. Значения — это то, что есть у типов, а не у переменных, а присвоение или связывание переменных означает копирование указателей, а не того, на что они указывают.

5. Сборка мусора (Garbage-collection).

6. Программы состоят из выражений (Programs composed of expressions). Программы на Lisp'е это деревья выражений, каждое из которых возвращает значение. (Некоторые Lisp-выражения могут возвращать множественные значения.) Это входит в контраст с Fortran'ом и с множеством других успешных языков, которые различают «выражения» и «утверждения».

Было естественным иметь такое различие в Fortran'е, потому что язык был линейно-ориентированным (не удивительно для языка, в котором форматом ввода была перфокарта). Вы не могли иметь вложенные утверждения. И пока вам требовались математические выражения для работы, не было смысла в том, чтобы заставлять что-нибудь ещё возвращать значение, потому что могло не быть чего-то, что ожидало возврата.

Ограничения были сняты с появлением блочно-структурированных языков, но к тому моменту было уже слишком поздно. Различие между выражениями и утверждениями уже закрепилось. Оно перешло от Fortran'а к Algol'у и далее к их потомкам.

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

(if foo (= x 1) (= x 2))

либо

(= x (if foo 1 2))

7. Символьный тип (A symbol type). Символы отличаются от строк, в этом случае вы можете проверить на равенство, сравнив указатели.

8. Нотация для кода (A notation for code) с использованием деревьев из символов.

9. Весь язык всегда доступен (The whole language always available). Нет явного различия между временем чтения, временем компиляции и временем выполнения. Вы можете компилировать или запускать код во время чтения, или читать или запускать кода пока компилируете, или читать или компилировать код во время выполнения.

Запуск кода во время чтения позволяет пользователям перепрограммировать синтаксис Lisp'а; запуск кода во время компиляции это основа для макросов; компилирование во время выполнения это основа использования Lisp'ов как языка расширения в таких программах как Emacs; и наконец, чтение во время выполнения позволяет программам взаимодействовать, используя s-выражения, идея, недавно переизобретённая в XML.

Заключение


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

Со временем язык по умолчанию, воплощённый в успехе популярных языков, постепенно эволюционировал в сторону Lisp. Пункты 1-5 теперь широко распространены. Пункт 6 начинает появляться в мэйнстриме. В Python'е в некотором виде есть пункт 7, хотя подходящего синтаксиса нет. Пункт 8, который (с пунктом 9) делает возможным макросы в Lisp'е, до сих пор есть только в Lisp'е, возможно потому что (а) он требует эти скобки или чего-то столь же плохого, и (б) если вы добавите это последнее увеличение мощности, то больше не сможете утверждать, что изобрели новый язык, а только лишь разработали новый диалект Lisp'а; -)

Хотя это полезно для современных программистов, странно описывать Lisp с точки зрения его отличия от случайных приёмов, принятых в других языках. Возможно это не то, о чём думал Маккарти. Lisp не был спроектирован, чтобы исправить ошибки Fortran'а; он появился скорее как побочный продукт попытки аксиоматизировать вычисления.

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


  1. shuhray
    22.11.2019 12:53
    +1

    В Agda не так давно добавили рефлексию (можно заключить кусок кода в кавычки и программа его сможет обрабатывать как данные). И вот это уже было в Lisp.


  1. Iwanowsky
    22.11.2019 14:24
    +1

    Помню, как в студенческие времена в прошлом веке делали лабораторные работы, практические занятия, выполняли контрольные работы, сдавали зачеты-экзамены по ЛИСПу и Прологу. И эти языки мне очень нравились. У нас был очень хороший преподаватель, кот. сам в основном работал на ЛИСПе (работал программистом в какой-то организации), писал в т.ч. на ЛИСПе СУБД, экспертные системы, системы обработки данных и пр. В качестве курсовых работ у нас были в т.ч. реализации игр на ЛИСПе и Прологе (в т.ч. обход графа, выбор оптимального хода и т.д.) Потом ЛИСП мне понадобился и для АвтоКАД — тоже очень удобная вещь.


    1. vgbege
      22.11.2019 19:41
      +1

      эх, а мне не пригодилось. но кар/кудр и красные/зеленые отсечения до сих пор в памяти. а вдруг пригодится :)


  1. xztau
    22.11.2019 17:49
    -2

    Где бы его сейчас применить, этот ваш лисп…


    1. newpy
      23.11.2019 11:32

      Wallmart, Сбербанк, Apple, Deutche Bank, Datomic и тд.
      Коротко
      https://clojure.org/community/success_stories
      Список компаний пополняемый:
      https://clojure.org/community/companies


      1. psycho-coder
        23.11.2019 12:37
        +1

        Хотел было написать подобный коммент, вовремя вспомнил, что комменты иногда надо обновлять.


      1. Iwanowsky
        23.11.2019 20:43
        -1

        ЛИСП — это серьезный инструмент, если на нем работать в больших серьезных проектах.


  1. shuhray
    22.11.2019 17:58

    Вообще, сейчас поучил Idris и впечатление такое «на этом уже можно программировать». От языков вроде Haskell такого впечатления нет.


    1. vasyapivo
      22.11.2019 18:08
      +1

      IDE и дебаггер завезли?


      1. shuhray
        22.11.2019 18:54

        Есть плагин к редактору Atom, удобно.


      1. potan
        23.11.2019 19:37

        Как перестал заниматься reverse engineering программировать на C и C++ потребности воспользоваться дебаггером ни разу не возникало.
        А тема IDE для Idris очень хорошо раскрыта в книге Type-Driven Development. Рекомендую почитать, описанные там приемы в IDEA, пр крайней мере со Scala, тоже работают.


    1. DarkEld3r
      22.11.2019 18:14

      Почему? В смысле, можно мысль развернуть?
      Так-то я толком ни одного ни другого не знаю, но, по идее, хаскель более зрелый, пусть и несколько обросший легаси, а идрис более аккуратно сделан (работа над ошибками), но экспериментальный.
      Или что вообще подразумевается под "на этом уже можно программировать"?


      Ну и к лиспу это имеет хоть какое-то отношение? (:


      1. shuhray
        22.11.2019 18:58
        +2

        Сейчас пишу большую программу на C++ и регулярно думаю «хорошо бы здесь использовать сигма-тип (dependent sum)». Кстати, в C++ добавили сигма-тип! (std::variant). Но лучше бы не добавляли, огорчение одно.


  1. lz961
    22.11.2019 20:40
    +1

    язык MAthematica идеологически очень близок к Лиспу, если не ошибаюсь (локальные и глобальные замены, прямые и отложенные вычисления и т.п.)


    1. potan
      23.11.2019 19:40

      Скорее Julia. Mathematica более высокоуровневая и специализированная штука.


  1. MagisterLudi
    24.11.2019 16:41

    Спасибо за перевод!

    Дополним коллекцию:
    Пол Грэм. Все статьи на русском.