Legibilidad de expresiones S

9

En pocas palabras y para aquellos que no lo sabían, las funciones / operadores / construcciones de Lisp se llaman uniformemente de esta manera:

(function arg0 arg1 ... argN)

Entonces, ¿qué en un lenguaje tipo C expresarías como

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

se transforma en un sexp de Lisp como

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

. A medida que las cosas se vuelven más reales / complicadas, también lo hacen sus expresiones s correspondientes.

Soy consciente de que esta es una pregunta subjetiva, pero, ¿para muchos hackers de Lisp esta pequeña molestia tendrá que lidiar siempre?

¿O uno se acostumbra principalmente a esta (falta de) sintaxis tarde o temprano?

En cualquier caso, ¿es una buena idea agregar líneas de corte (que no agregaría en su equivalente C, la mayoría de las veces) para facilitar la lectura, especialmente a largo plazo? Cualquier otra sugerencia sería bienvenida.

vemv
fuente
1
¿Has intentado usar Lisp en un entorno compatible con Lisp como emacs? No lo tocaría de otra manera.
David Thornley
No, no lo he hecho, ¿en qué formas puede mejorar mi experiencia Lisp?
vemv
escribir funciones cortas también es muy importante, aunque solo he jugado un poco con clojure.
Kevin
3
En un buen entorno Lisp, ignoras los paréntesis y lees la estructura por la sangría. Como habrás notado, leer la estructura contando paréntesis es realmente muy molesto.
David Thornley

Respuestas:

8

¿Cómo se analiza?

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

El árbol de análisis probablemente se parece a

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

hmm ... serialicemos este árbol en una lista, notación de prefijo

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

Este formato de árbol de análisis es bastante fácil de manipular, pero tengo un problema. Odio los separadores. Me gustan los terminadores. Al mismo tiempo, me gusta rociar en espacios en blanco.

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

hmm ... el espacio en blanco adicional hace que ciertas cosas sean más difíciles de analizar ... Tal vez podría simplemente hacer una regla de que el árbol se representa como (raíz, hoja, hoja, hoja).

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

Ahora mi serialización de un árbol de análisis es lisp (renombrar la función para aplicar, y esto probablemente se ejecute). Si quiero programas que escriban programas, es agradable manipular solo los árboles de análisis.

Esto no es del todo cómo surgieron las expresiones s, pero se identificó temprano, y es una característica que usan los programadores de lisp. Nuestros programas se analizan previamente en cierto sentido, y escribir programas para manipularlos es bastante fácil debido al formato. Es por eso que la falta de sintaxis a veces se considera una fortaleza.

Pero como dijo David, use un editor consciente de s-expression. Es más probable que pierda la pista de una llave de cierre en una expresión s que una llave de cierre en xml ( </foo>solo se cierra <foo>, pero el par derecho cierra CUALQUIER expresión de s). En raqueta, el uso de corchetes para algunas expresiones, junto con un buen estilo de sangría, corrige la mayoría de los problemas.

La versión lisp:

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

No está mal.

ccoakley
fuente
Las listas son más versátiles y poderosas que las declaraciones exprs + sin duda. Probar Emacs (¿o qué más?) Es tentador, pero la última vez que lo intenté me asustó mucho. ¿Qué aporta exactamente la conciencia sexp?
vemv
Cosas simples: hacen resaltar los elementos parentes abiertos y cercanos (o resaltan expresiones s enteras de manera diferente). Tienen buenas reglas de sangría. Emacs tiene otras cosas, pero probablemente no son tan importantes para la legibilidad. Hay otros editores conscientes de la expresión s. No necesitas emacs. Si emacs lo asusta, pruebe los paquetes de textmate, sublime, etc. Una vez que su editor comienza a ayudarlo con la legibilidad, las cosas se vuelven un poco más fáciles. Hago la mayoría de las cosas lispy en raqueta, lo que permite corchetes en cualquier lugar donde se puedan usar parens. Ser capaz de cambiar ayuda a la legibilidad.
ccoakley
1
Por otro lado, haga uso de los permisos, definiciones, etc. anidados, divida esas cosas en pedazos más pequeños. Si no puede encontrar un buen nombre para un fragmento, trátelo como una advertencia sobre su diseño. Encuentre el equilibrio entre demasiado pequeño para nombrar y demasiado grande para leer.
ccoakley
Oh, ese último consejo es ... memorable :) Intentando Sublime mientras escribo esto.
vemv
5

Lo que es realmente bueno de s-exp es que después de un corto período de tiempo, ya no los ves, es como python para tus ojos, PERO la computadora todavía tiene el árbol fácilmente.

  • Por lo tanto, la sangría es automática, no hay ambigüedad, no tiene que presionar la tecla dos veces o algo así cuando desea finalizar un bloque.

  • Si elige un código aleatorio, todo el material se sangra fácilmente con solo un comando de su editor favorito

  • Puede navegar a través de su código con mucha facilidad, saltar entre s-exp, intercambiarlos, etc. con un buen editor

Además, debido a que los datos que está manipulando son los mismos que el código que está escribiendo, podría usar el mismo lenguaje para manipular su código, ¿verdad?

Bueno, puedes hacerlo, eso es lo que son las macros, manipulas el código que estás escribiendo antes de que sea evaluado como cualquier otra lista, por eso se dice que Lisp es un "Lenguaje de Programación Programable". Escribes código que escribe tu código por ti.

Aquí hay un buen artículo que describe la naturaleza de Lisp y por qué los programadores de Lisp sonrieron cuando ven XML.

Daimrod
fuente