2012-03-02 5 views
22

Три Lispy homoiconic языков, Dylan, Julia и Seph все отошли от ведущей скобки - так вызова гипотетической функции в Common Lisp, который будет выглядеть так:Что может потерять Clojure, перейдя от ведущих круглых скобок, таких как Dylan, Julia и Seph?

(print hello world) 

Посмотрел бы, как следующий вызов гипотетической функции

print(hello world) 

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

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

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

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

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

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

+6

Большая часть LISP эстетики является тривиальным parseability и удобство использования в качестве данных кода; вы потеряете часть этого. – zmccord

+0

Функциональное приложение является лишь одной из многих возможных форм. Вы предлагаете относиться к ним по-другому? Clojure уже сделал ужасную вещь, отменив cons-клетки. Переход любого будущего полностью разрушит язык. –

+3

См. Также http://stackoverflow.com/questions/643892/fixing-lisp-syntax. Этот вопрос напоминает мне разработчика Pascal, которого я знал, кто, столкнувшись с использованием C, хотел набор макросов, которые сделали C более похожим на Pascal. Я думаю, что всегда есть соблазн уменьшить свой дискомфорт от чего-то нового, заставив его быть более знакомым. И все же иногда для вас полезно подойти к чему-то другому на своих условиях. – user100464

ответ

13

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

на совершенно иной точки зрения, это хорошо стоит смотреть это видео на the difference between familiar and easy делает лепечет синтаксис более знакомый не сделает его проще для людей, чтобы узнать и может сделать его вводящим в заблуждение, если он будет выглядеть так, как будто это не так.

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

23

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

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

+0

:) Согласитесь, вы не можете сделать людей счастливыми. Я предполагаю, что вы сохраните макросы, и я думаю, вы говорите «хорошо, вам придется переписать все эти макросы основного языка». Но дело в том, что кто-то решил, что это стоит того, по крайней мере, на трех разных языках. Мой вопрос был не тем, а почему. – hawkeye

0
Were Clojure to go down this path - what would it have to sacrifice to get there? 

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

ПРИМЕЧАНИЕ. Существуют и другие вещи, которые будут скарифицированы, как указано в других ответах.

2

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

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

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

1

Философия «код данных» - это то, что делает возможным надежное метапрограммирование. Сравните с 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 ] отдыхают в первую очередь)

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

13

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

19

(Кредит ответа AndreW Кука, который предоставил ссылку на Уилер и Глории "Readable Lisp S-expressions Project")

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

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

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

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

Обратите внимание, как синтаксис совместим с макросами, которая была проблема с previous projects that intended to improve Lisp syntax (как описано Wheeler и Gloria) , Поскольку это всего лишь сахар, окончательная форма каждого нового выражения является s-выражением, преобразованным с помощью языка, прежде чем макросы обрабатываются - так что макросы не нуждаются в особой обработке. Таким образом, «читаемый Lisp» проект сохраняет гомоконичность, свойство, которое позволяет Lisp представлять код как данные в языке, что позволяет ему быть мощной средой метапрограммирования.

+2

Если вы все уволены, мне всегда поразило, что ракетка (схема, поддерживающая несколько «языков») была бы хорошим местом для ее реализации - https://en.wikipedia.org/wiki/Racket_features#Language_Extensions –

3

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

Там могут быть семантические различия между Mathematica и Лиспа/Scheme/Clojure, но синтаксис Mathematica является демонстрация того, что вы можете переместить левую скобку над одним атомом и по-прежнему интерпретировать благоразумно, построить код с макросами и т.д.

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