Читаемость S-выражений

9

Короче говоря, и для тех, кто этого не знал, все функции / операторы / конструкции Lisp называются следующим образом:

(function arg0 arg1 ... argN)

Так что на языке C-like вы бы выразили как

if (a > b && foo(param))

превращается в Lisp Sexp как

(if (and (> a b) (foo param)))

, Поскольку вещи становятся более реальными / сложными, то и их соответствующие s-выражения, для меня.

Я знаю, что это, скорее всего, субъективный вопрос, но - для многих лисповских хакеров с этим небольшим раздражением придется всегда иметь дело?

Или рано или поздно привыкли к этому (отсутствию) синтаксиса?

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

vemv
источник
1
Вы пробовали использовать Lisp в среде, в которой есть Lisp, такой как emacs? Я бы не трогал это по-другому.
Дэвид Торнли
Нет, в каких формах это может улучшить мой опыт в Лиспе?
VEMV
Написание коротких функций также очень важно, хотя я только немного поиграл с clojure.
Кевин
3
В хорошей среде Lisp вы игнорируете круглые скобки и читаете структуру по отступам. Как вы заметили, чтение структуры путем подсчета скобок действительно очень раздражает.
Дэвид Торнли

Ответы:

8

Как вы разбираете

if (a > b && foo(param)) {
  doSomething();
} else {
  doSomethingElse();
}

Дерево разбора, вероятно, выглядит примерно так

if:
  condition:
    and:
      lt:
        left: a
        right: b
      function:
        name: foo
        param: param
  true-block:
    function:
      name: doSomething
  false-block:
    function:
      name: doSomethingElse

хм ... давайте сериализуем это дерево в список, префикс нотации

if(and(<(a, b), function(foo, param)), function(doSomething), function(doSomethingElse))

Этот формат дерева разбора довольно легко манипулировать, но у меня есть одна проблема. Я ненавижу разделители. Мне нравятся терминаторы. В то же время мне нравится разбрызгивание в пустое пространство.

if( and (<(a b) function(foo param)) function (doSomething) function ( doSomethingElse))

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

(if (and (< a b) (function foo param)) (function doSomething) (function doSomethineElse)

Теперь моя сериализация дерева разбора - lisp (функция переименования применяется, и это, вероятно, выполняется). Если мне нужны программы, которые пишут программы, неплохо просто манипулировать деревьями разбора.

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

Но, как сказал Дэвид, используйте редактор с поддержкой s-выражений. С большей вероятностью вы потеряете след закрывающей фигурной скобки в s-выражении, чем закрывающей фигурной скобки в xml ( </foo>только закрывается <foo>, но правая часть закрывает ЛЮБОЕ s-выражение). В рэкетах использование квадратных скобок для некоторых выражений в сочетании с хорошим стилем отступа решает большинство проблем.

Версия LISP:

(if (and (< a b) (foo param))
  (doSomething)
  (doSomethingElse))

Не плохо.

ccoakley
источник
Списки более универсальны и мощны, чем выражения exprs +, без сомнения. Попытка Emacs (или что еще?) Заманчива, но последнее время, когда я пробовал, просто очень напугало меня. Что именно дает секс-осведомленность?
vemv
Простые вещи: они отражают подсветку на близких и открытых паренах (или выделяют целые s-выражения по-разному). У них хорошие правила отступа. В Emacs есть и другие вещи, но они, вероятно, не так важны для удобства чтения. Существуют и другие редакторы, поддерживающие s-выражения. Вам не нужны Emacs. Если emacs вас пугает, попробуйте связки для textmate, sublime и т. Д. Как только ваш редактор начинает помогать с читабельностью, все становится немного проще. Я делаю самые грязные вещи в ракетке, что позволяет использовать квадратные скобки везде, где можно использовать паренсов. Возможность переключения помогает читабельности.
Ccoakley
1
Кроме того, используйте вложенные let, определения и т. Д. Разбейте этот материал на более мелкие части. Если вы не можете придумать хорошее название для куска, относитесь к нему как к предупреждению о вашем дизайне. Найдите баланс между слишком маленьким для имени и слишком большим для чтения.
Ccoakley
О, этот последний совет ... запоминающийся :) Попытка Возвышенного, поскольку я пишу это.
vemv
5

Что действительно хорошо в s-exp, так это то, что через короткий промежуток времени вы их больше не видите, на ваш взгляд это как python, НО у компьютера все еще есть дерево.

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

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

  • Вы можете перемещаться по коду очень легко, прыгать между втор-ехр, поменять их местами и так далее с хорошим редактором

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

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

Вот хорошая статья, которая описывает природу Лиспа и почему программисты Лисп улыбнулись, увидев XML.

Daimrod
источник