Что потеряет Clojure, отказавшись от ведущих скобок, таких как Дилан, Джулия и Сеф? - PullRequest
24 голосов
/ 02 марта 2012

Три нецензурных гомоиконических языка, Дилан , Джулия и Сеф - все они отошли от ведущих скобок - так что вызов гипотетической функции в Common Lisp выглядит следующим образом:

(print hello world)

Будет выглядеть следующий гипотетический вызов функции

print(hello world)

на трех языках, упомянутых выше.

Если бы Clojure пошел по этому пути - чем он должен был бы пожертвовать, чтобы туда попасть?

Причина: Помимо удивительных ленивых функциональных структур данных в Clojure и улучшенного синтаксиса для карт иseqs, языковая поддержка параллелизма, платформа JVM, инструментарий и потрясающее сообщество - отличительная черта того, что «LISP» - это лидирующая скобка, дающая гомоконичность, которая дает макросы, обеспечивающие абстракцию синтаксиса.

Но если вам не нужны ведущие скобки - зачем их?Единственные аргументы, которые я могу придумать для их сохранения, это

(1) повторное использование поддержки инструментов в emacs

(2), побуждающее людей «думать в LISP» и не пытаться воспринимать это как другоепроцедурный язык)

Ответы [ 9 ]

23 голосов
/ 02 марта 2012

Простое перемещение скобок на один атом для вызовов функций будет недостаточно, чтобы удовлетворить кого-либо;люди будут жаловаться на отсутствие инфиксных операторов, блоков начала / конца и т. д. Кроме того, вам, вероятно, придется вводить запятые / разделители в самых разных местах.писать правильно (и, вероятно, было бы еще труднее написать макросы, которые выглядят и работают хорошо со всем новым синтаксисом, который вы ввели к тому времени).А макросы - это не та приятная особенность, которую вы можете игнорировать или сильно раздражать;весь язык (как и любой другой Лисп) построен прямо над ними.Большинство «видимых для пользователя» вещей, которые есть в clojure.core, включая let, def, defn и т. Д., Являются макросами.

19 голосов
/ 08 июля 2013

(Благодарю за ответ Эндрю Кука, который предоставил ссылку на проект Уилера и Глории "Читаемый проект S-выражений Lisp" )

Ссылка выше - это проект, предназначенный для обеспечения читабельного синтаксиса для всех языков на основе s-выражений, включая Scheme и Clojure. Вывод таков: это можно сделать: есть способ иметь читаемый Лисп без скобок .

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

Этот проект определяет три новых типа выражений:

  • Фигурное-инфиксное-выражение. (+ 1 2 3) становится {1 + 2 + 3} в каждом месте, где вы хотите использовать инфиксные операторы любой арности. (Существует особый случай, который необходимо обрабатывать с осторожностью, если встроенное выражение использует несколько операторов, например {1 + 2 * 3} - хотя {1 + {2 * 3}} работает как положено).
  • Neoteric-выражение. (f x y) становится f (x y) (требуется, чтобы между именем функции и ее параметрами не было пробела)
  • Сладкое-выражение. Открывающих и закрывающих родителей можно заменить на (необязательно) питоноподобный семантический отступ . Сладкие выражения можно свободно смешивать с традиционными скобками s-выражений.

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

(define (gcd_ a b)
    (let (r (% b a))
        (if (= r 0) a (gcd_ r a))))

(define-macro (my-gcd)
    (apply gcd_ (args) 2))

становится:

define gcd_(a b)
    let r {b % a}
        if {r = 0} a gcd_(r a)

define-macro my-gcd()
    apply gcd_ (args) 2

Обратите внимание, как синтаксис совместим с макросами, что было проблемой с предыдущими проектами, которые предназначались для улучшения синтаксиса Lisp (как описано Уилером и Глорией). Поскольку это просто сахар, конечной формой каждого нового выражения является s-выражение, преобразованное средством чтения языка перед обработкой макросов, поэтому макросы не нуждаются в особой обработке. Таким образом, проект «читаемый Лисп» сохраняет гомоичность, свойство, которое позволяет Лиспу представлять код как данные в языке, что позволяет ему быть мощной средой метапрограммирования.

13 голосов
/ 09 марта 2012

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

13 голосов
/ 02 марта 2012

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

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

даже если вы полностью не согласны, это видео того стоит.

3 голосов
/ 31 января 2014

У тебя будет Mathematica.Mathematica принимает вызовы функций как f[x, y, z], но когда вы исследуете его дальше, вы обнаружите, что f[x, y, z] на самом деле является синтаксическим сахаром для списка, в котором Head (элемент 0) равен f иRest (элементы с 1 по N) равно {x, y, z}.Вы можете создавать вызовы функций из списков, которые очень похожи на S-выражения, и вы можете разбивать неоцененные функции на списки (Hold предотвращает оценку, очень похоже на quote в Lisp).

Могут быть семантические различия между Mathematica и Lisp / Scheme / Clojure, но синтаксис Mathematica является демонстрацией того, что вы можете переместить левую круглую скобку на один атом и все же интерпретировать ее разумно, построить код с помощью макросов и т. Д.

Синтаксис довольно легко конвертировать с помощью препроцессора (намного проще, чем семантика).Скорее всего, вы могли бы получить нужный синтаксис с помощью умного подкласса LispReader от Clojure .Есть даже проект , который пытается решить смещающие скобки Clojure, заменяя их все квадратными скобками.(Меня поражает, что это считается большим делом.)

2 голосов
/ 03 марта 2012

Я использовал для кодирования C / C # / Java / Pascal, поэтому я подчеркиваю, что код на Лиспе немного чужд. Однако это чувство длится всего несколько недель - через довольно короткий промежуток времени стиль Lisp станет очень естественным, и вы начнете ругать другие языки за их «неправильный» синтаксис: -)

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

И когда вы манипулируете кодом / используете макросы, именно эти формы имеют значение: это строительные блоки всего вашего кода. Так что в принципе имеет смысл поместить скобки в место, которое точно ограничивает эти формы, а не произвольно оставлять первый элемент за пределами формы.

1 голос
/ 12 сентября 2014

Довольно интересно - есть альтернативный синтаксис Racket :

@foo{blah blah blah}

читается как

(foo "blah blah blah")
1 голос
/ 08 марта 2012

Философия «код - данные» делает возможным надежное метапрограммирование.Сравните с Perl / Ruby, которые имеют сложный синтаксис, их подходы к метапрограммированию надежны только в очень ограниченных условиях.Метапрограммирование на Лиспе настолько надежно, что ядро ​​языка зависит от него.Причиной этого является единый синтаксис, общий для кода и данных (свойство гомоичоничности).S-выражения - это способ реализации этого единообразия.

При этом в Clojure существуют обстоятельства, при которых возможны подразумеваемые скобки:

Например, следующие три выражения эквивалентны:

  1. (первый (отдых (отдых [1 2 3 4 5 6 7 8 9])))
  2. (-> [1 2 3 4 5 6 7 8 9] (отдых) (отдых)) (первый))
  3. (-> [1 2 3 4 5 6 7 8 9] rest rest first)

Обратите внимание, что в третьем макросе -> можетэтот контекст, чтобы вывести скобки и тем самым исключить их.Есть много особых сценариев, подобных этому.В целом дизайн Clojure ошибается в сторону меньших скобок.Смотрите, например, спорное решение покинуть из скобки в конде.Clojure очень принципиален и последовательн в этом выборе.

0 голосов
/ 02 марта 2012
Were Clojure to go down this path - what would it have to sacrifice to get there?

Жертвой было бы чувство / ментально-модальное написание кода путем создания Списка Списка Списка .. или, если говорить технически, «непосредственное написание AST».

ПРИМЕЧАНИЕ: есть и другие вещи, которые будут раскритикованы, как упоминалось в других ответах.

...