Исправление синтаксиса Lisp - PullRequest
15 голосов
/ 13 марта 2009

Будучи новичком в Лиспе, мне интересно, можно ли "исправить" синтаксис Лиспа?

Некоторые люди говорят, что синтаксис в Лиспе - одна из его сильных сторон. Я не совсем понимаю это.

Разве нельзя заменить «очевидные» скобки комбинацией пробелов, новых строк и отступов? Как в Python?

Мне кажется, скобки - это наиболее часто используемые символы в коде на Лиспе. Мне интересно, правда ли это - но если это так, разве это не предположение, что в синтаксисе есть некоторая избыточность?

Есть ли простой ответ на вопрос - почему так много скобок?

Например:

(defun factorial (x)
    (if (= x 0)
        1
        (* x 
           (factorial (- x 1)))))

Почему бы и нет:

defun factorial (x)
  if (= x 0)
    1
    * x
      factorial
        - x 1

например. закрывайте скобки в конце строки и всегда открывайте их в новых строках. Только 1 будет неоднозначным - это 1 или (1) - но мы могли бы ввести исключение - одиночные токены не являются «листинговыми».

Может ли это сработать?

Edit:

Спасибо всем! Теперь я вижу ссылки на сайте lispin .

Ответы [ 16 ]

29 голосов
/ 14 марта 2009

Вы передумаете, когда напишите пару макросов.

27 голосов
/ 13 марта 2009

Это было сделано много раз (препроцессор <двадцать строк будет творить чудеса). Но есть и преимущество в том, чтобы они были явными. Это приводит к параллелизму между кодом и данными и в некотором смысле выводит вас из такого мышления, которое заставляет вас находить их раздражающими. </p>

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

Когда вы смотрите на Lisp, вы должны думать: «Все - это список. Ммм»

(Хорошо, хорошо, "Ommm" необязательно).

17 голосов
/ 14 марта 2009

«Возможно, этот процесс следует рассматривать как обряд для хакеров Lisp».

- Стил и Габриэль, "Эволюция Лиспа", 1993

12 голосов
/ 13 марта 2009

То, что вы предлагаете, похоже, было реализовано в Lispin

Edit: sindikat указывает в комментариях ниже, что ссылка больше не действительна. Вот последняя действующая версия сайта из веб-архива: http://wayback.archive.org/web/20080517144846id_/http://www.lispin.org/

9 голосов
/ 14 марта 2009

Несколько раз я сравнивал код на Лиспе и эквивалентный код на других языках. В коде Lisp больше паренов, но если вы посчитаете все символы группировки [] {} () в других языках, у Lisp будет меньше паренов, чем у всех этих. Это не более многословно: это более последовательно!

С этой точки зрения, проблема в том, что Лисп использует один тип конструкции (списки) для всего. И это основа для его макросов, его объектной системы, пары его самых мощных циклических конструкций и так далее. То, что вы видите как незначительную проблему стиля (будут ли скобки выглядеть круче? Вероятно), на самом деле является признаком языковой силы.

Тем не менее, Лисп - это все, чтобы дать власть программисту. Если хотите, напишите свой собственный диалект, который позволит вам это сделать. Lisp (в отличие от некоторых языков, о которых я мог бы упомянуть!) - это сила программиста, так что используйте его. Если ты сможешь заставить это работать, возможно, это взлетит. Я не думаю, что это произойдет, но ничто не мешает вам попробовать, и в любом случае вы многому научитесь.

6 голосов
/ 14 марта 2009

Смысл синтаксиса lisp в том, что он не существует. S-выражение - это дерево тождеств, в котором древовидная структура обозначена паренами (отступы и ). Стоит отметить, что секспланы предназначались только для представления на низком уровне, но людям это все больше нравилось и они продолжали его использовать.

Что выражение означает для механизма исполнения невероятно гибко в lisp, а также контекстно-зависимо.

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

В lisp я могу изменить значение всего, даже с учетом контекста. Иметь специальный синтаксис для нескольких предопределенных конструкций было бы глупо, потому что я мог бы в конечном итоге использовать свое собственное 'if' или свои собственные специализированные замыкания и т. Д. Что если моему новому 'if' нужно 4 аргумента (например, для группировки определенных if из a запрограммировать и сказать некоторым группам всегда терпеть неудачу или преуспевать в определенных ситуациях)? Как мне расширить синтаксис предопределенного «если»? Гораздо проще прибегнуть к AST (sexps), но зачем вообще использовать специальный синтаксис?

Также обратите внимание, что использование редактора, такого как emacs, позволяет очень легко редактировать такое дерево в структурированном виде. Например, наличие ключа для транспонирования двух узлов в дереве одинаково полезно для обмена объявлениями переменных и для замены двух операторов в программном блоке (подсказка: именно поэтому «дополнительные» парены полезны в let, cond и т. Д.).

Итак, вот почему несинтаксис lisp равен , поэтому привлекателен для многих людей, которые привыкли к идее расширения языка вместо того, чтобы подгонять задачу под нужды предопределенный набор инструментов ... но это не значит, что синтаксический сахар не используется для пользовательских конструкций!

Некоторые примеры пользовательских синтаксисов, которые мы используем:

  • cl-syntax-sugar - наиболее заметное расширение - это [] паренсы, используемые для крошечных замыканий, когда вы не хотите называть переменные замыкания
  • cl-quasi-quote - прежде всего, синтаксис <xml > для включения генерации xhtml в код lisp (обратите внимание, что этот синтаксис предоставляется библиотекой user , и может быть включен контекстно-зависимым способом)
5 голосов
/ 14 марта 2009

Даже Пол Грэм , вокальный защитник семейства языков Lisp, удалил некоторые скобки из своего собственного диалекта Arc :

Примечание для хакеров Lisp: Если вы привыкли к обычному Lisp cond оператор, если это то же самое, но с меньшим скобки. Э.Г.

(cond (a b)
      (c d)
      (t e))

становится

(if a b
    c d
    e)

(из учебника Arc )

5 голосов
/ 13 марта 2009

Это может сработать. Это называется Дилан .

3 голосов
/ 13 марта 2009

Есть два вида людей и торговли: те, кто обрабатывает информацию с помощью встроенной в стек машины в своем мозгу, и те, кто потребляет ее большими кусками или блоками. Эти группы взаимно несовместимы друг с другом; они читают разные книги, имеют разные стили написания и, самое главное, пишут код на разных языках программирования. Я принадлежу ко второй группе; тем не менее, я знаю многих коллег-программистов из первой группы.

Для людей из первой группы нет ничего плохого во вложенных предложениях и подпунктах; они понимают рекурсию естественно; они смотрят на код медленно, оператор за оператором, строка за строкой, и машина стека в их мозгах продолжает подсчитывать скобки и скобки на подсознательном уровне. Синтаксис Lisp для них вполне естественный. Черт, они, вероятно, изобрели стековые машины и язык Forth. Но покажите им, скажем, Python (о нет!), И они беспомощно заглянут в листы кода, не понимая, почему эти глупые блоки кода оставлены открытыми , без соответствующих закрывающих операторов.

Для нас, бедных парней из второй группы, нет другого выбора, кроме как сгруппировать операторы кода в блоки и сделать для них визуальный отступ. Мы смотрим на экран, заполненный кодом, сначала замечая крупномасштабную структуру, затем отдельные функции или методы, затем группы операторов внутри этих методов, затем строки и операторы сверху вниз. Мы не можем мыслить линейно; нам нужны визуальные границы и чистая политика отступов. Следовательно, мы не можем смириться с работой с Лиспом; для нас это нерегулярный беспорядок ключевых слов и глупых скобок.

Большинство языков программирования совместимы с обоими способами мышления (эти «блоки» существуют для разума). Заметными исключениями являются Lisp и Forth, которые являются только первой группой, и Python, который является только второй группой. Я не думаю, что вам нужно адаптировать Lisp к вашему образу мышления, если вы принадлежите ко второй группе. Если вам все еще нужен функциональный язык, попробуйте Haskell. Это функциональный язык, предназначенный для людей, которые думают в виде блоков, а не стеков.

1 голос
/ 05 октября 2012

Эта ветка старая, но я решил внести свой вклад, потому что создал очень похожую систему чтения .

РЕДАКТИРОВАТЬ: Некоторые образцы использования:

!defun fact (n)
  if (zerop n)
    1
    * n
      fact
        (1- n)
!defun fact !n
  if !zerop n
    1
    !* n !fact !1- n

Для получения дополнительной информации проверьте домашнюю страницу проекта.

...