Legibilidade das expressões S

9

Em poucas palavras e para aqueles que não o conheciam, as funções / operadores / construções do Lisp são todos uniformemente chamados assim:

(function arg0 arg1 ... argN)

Então, o que em uma linguagem do tipo C você expressaria como

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

é transformado em um sexp Lisp como

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

. À medida que as coisas ficam mais reais / complicadas, o mesmo acontece com as expressões s correspondentes, para mim.

Estou ciente de que essa é provavelmente uma pergunta subjetiva, mas - é para muitos hackers do Lisp esse pequeno aborrecimento com o qual sempre devemos lidar?

Ou alguém costuma se acostumar com essa (falta de) sintaxe mais cedo ou mais tarde?

Em qualquer caso, adicionar linhas de interrupção (que você não adicionaria em seu equivalente C, na maioria das vezes) para facilitar a leitura é uma boa idéia, especialmente a longo prazo? Quaisquer outras sugestões serão bem-vindas.

vemv
fonte
11
Você já tentou usar o Lisp em um ambiente compatível com o Lisp como o emacs? Eu não tocaria de outra maneira.
David Thornley
Não, não. De que formas ele pode melhorar minha experiência com o Lisp?
vemv
escrever funções curtas também é muito importante, embora eu tenha apenas brincado com o clojure.
21711 Kevin
3
Em um bom ambiente Lisp, você ignora os parênteses e lê a estrutura pelo recuo. Como você notou, ler a estrutura contando parênteses é muito, muito chato.
David Thornley

Respostas:

8

Como você analisa

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

A árvore de análise provavelmente se parece com algo como

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

hmm ... vamos serializar esta árvore em uma lista, notação de prefixo

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

Esse formato de árvore de análise é muito fácil de manipular, mas eu tenho um problema. Eu odeio separadores. Eu gosto de terminadores. Ao mesmo tempo, gosto de borrifar espaço em branco.

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

hmm ... o espaço em branco adicional dificulta a análise de algumas coisas ... Talvez eu pudesse estabelecer uma regra de que a árvore é representada como (folha de folha de raiz).

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

Agora minha serialização de uma árvore de análise é lisp (renomeie a função a ser aplicada, e isso provavelmente é executado). Se eu quiser programas que escrevam programas, é bom manipular árvores de análise.

Não é exatamente assim que as expressões s surgiram, mas foram identificadas mais cedo e é um recurso que os programadores lisp usam. Nossos programas são pré-analisados ​​em algum sentido, e escrever programas para manipular programas é bastante fácil por causa do formato. É por isso que a falta de sintaxe às vezes é considerada uma força.

Mas, como David disse, use um editor com reconhecimento de expressão s. É mais provável que você perca o controle de uma chave de fechamento em uma expressão s do que uma chave de fechamento em xml ( </foo>apenas fecha <foo>, mas o parêntese direito fecha QUALQUER expressão s). Na raquete, o uso de colchetes para algumas expressões, associado ao bom estilo de indentação, corrige a maioria dos problemas.

A versão lisp:

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

Não é tão ruim.

ccoakley
fonte
As listas são mais versáteis e poderosas do que as declarações exprs +, sem dúvida. Tentar o Emacs (ou o que mais?) É tentador, mas a última vez que tentei me assustou muito. O que a consciência sexp traz exatamente?
vemv
Coisas simples: destacam os pontos de abertura e fechamento (ou realçam expressões s inteiras de maneira diferente). Eles têm boas regras de recuo. O Emacs tem outras coisas, mas provavelmente não são tão importantes para facilitar a leitura. Existem outros editores com reconhecimento de expressão s. Você não precisa do emacs. Se o emacs o assusta, tente os pacotes para textmate, sublime, etc. Quando o editor começa a ajudar na legibilidade, as coisas ficam um pouco mais fáceis. Faço a maioria das coisas lispy na raquete, o que permite colchetes em qualquer lugar onde parênteses possam ser usados. Ser capaz de mudar ajuda na legibilidade.
ccoakley
11
Como um aparte, faça uso de lets, define, etc. aninhados, quebre essas coisas em pedaços menores. Se você não conseguir criar um bom nome para um pedaço, trate isso como um aviso sobre seu design. Encontre o equilíbrio entre muito pequeno para nomear e muito grande para ler.
ccoakley
Oh, esse último conselho é ... memorável :) Tentando sublime enquanto escrevo isso.
vemv
5

O que é realmente legal no s-exp é que, após um curto período de tempo, você não os vê mais, é como python aos seus olhos, mas o computador ainda tem a árvore facilmente.

  • Portanto, o recuo é automático, não há ambiguidade, você não precisa pressionar a tecla tab duas vezes ou algo assim quando quiser finalizar um bloco.

  • Se você escolher algum código aleatório, todo o conteúdo é facilmente recuado com apenas um comando do seu editor favorito

  • Você pode navegar pelo seu código com muita facilidade, alternar entre s-exp, trocá-los e assim por diante com um bom editor

Além disso, como os dados que você está manipulando são os mesmos que o código que está escrevendo, você pode usar a mesma linguagem para manipular seu código, certo?

Bem, você pode fazê-lo, é isso que são as macros, você manipula o código que está escrevendo antes de ser avaliado como qualquer outra lista, é por isso que se diz que o Lisp é uma "Linguagem de Programação Programável". Você escreve um código que escreve seu código para você.

Aqui está um bom artigo que descreve a natureza do Lisp e por que os programadores do Lisp sorriram quando viram o XML.

Daimrod
fonte