¿Qué perdería Clojure al alejarse de los paréntesis principales como Dylan, Julia y Seph?


Tres lenguas homoicónicas lispy, Dylan, Julia y Seph se alejaron de los paréntesis iniciales, por lo que una llamada a una función hipotética en Common Lisp se vería como:

(print hello world)

Se vería como la siguiente llamada a la función hipotética

print(hello world)

En las tres lenguas mencionadas anteriormente.

Si Clojure siguiera este camino - ¿qué tendría que sacrificar para llegar allí?

Razonamiento: Aparte de los increíbles datos funcionales perezosos estructuras en Clojure, y la sintaxis mejorada para mapas y seqs, el soporte de lenguaje para concurrencia, la plataforma JVM, las herramientas y la comunidad awesome - lo distintivo de que es 'un LISP' es el paréntesis que da homoiconicidad que da macros que proporcionan abstracción de sintaxis.

Pero si no necesitas paréntesis iniciales - ¿por qué tenerlos? Los únicos argumentos que se me ocurren para mantenerlos son

(1) reutilización del soporte de herramientas en emacs

(2) que la gente 'piense en LISP' y no trate de tratarlo como otro lenguaje procedimental)

Author: Lyndon White, 2012-03-02

9 answers

Escribir macros sería mucho más difícil porque la estructura ya no sería simple. necesitaría otra forma de codificar donde las expresiones comienzan y se detienenusando algún símbolo sintáctico para marcar el inicio y el final de las expresiones para poder escribir código que genere expresiones tal vez podría resolver este problema agregando algo como un ( para marcar el inicio de la expresión...

En un ángulo completamente diferente, vale la pena ver esto video sobre la diferencia entre familiar y fácil hacer que la sintaxis de lisps sea más familiar no hará que sea más fácil que la gente aprenda y puede hacerlo engañoso si se parece mucho a algo que no es.

Incluso si estás completamente en desacuerdo, ese video vale la pena la hora.

 13
Author: Arthur Ulfeldt,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2012-03-02 17:19:52

Simplemente mover los paréntesis un átomo para las llamadas a funciones no sería suficiente para satisfacer a nadie; la gente se quejará de la falta de operadores de infijo, bloques de inicio/fin, etc. Además, probablemente tendría que introducir comas / delimitadores en todo tipo de lugares.

Dales eso y las macros serán mucho más difíciles de escribir correctamente (y probablemente sería aún más difícil escribir macros que se vean y actúen bien con toda la nueva sintaxis que hayas introducido para entonces). Y las macros no algo que es una buena característica que puedes ignorar o hacer mucho más molesto; todo el lenguaje (como cualquier otro Lisp) está construido justo encima de ellos. La mayoría de las cosas "visibles para el usuario" que están en clojure.core, incluyendo let, def, defn etc son macros.

 23
Author: Joost Diepenmaat,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2012-03-02 12:43:01

(Crédito a la respuesta de Andrew cooke, quien proporcionó el enlace al Proyecto de Wheeler y Gloria "Readable Lisp S-expressions Project")

El enlace anterior es un proyecto destinado a proporcionar una sintaxis legible para todos los lenguajes basados en expresiones-s, incluyendo Scheme y Clojure. La conclusión es que se puede hacer: hay una manera de tener Lisp legible sin los paréntesis.

Básicamente lo que el proyecto de David Wheeler hace es agregar azúcar sintáctico a lenguajes similares a Lisp para proporcione una sintaxis más moderna, de manera que no rompa el soporte de Lisp para lenguajes específicos de dominio. Las mejoras son opcionales y compatibles con versiones anteriores, por lo que puede incluir tanto o tan poco como desee y mezclarlas con el código existente.

Este proyecto define tres nuevos tipos de expresión:

  • Curly-infix-expressions. (+ 1 2 3) se convierte en {1 + 2 + 3} en cada lugar que desee utilizar operadores infix de cualquier arity. (Hay un caso especial que necesita ser manejado con cuidado si la expresión en línea utiliza varios operadores, como {1 + 2 * 3} - aunque {1 + {2 * 3}} funciona como se esperaba).
  • Neoteric-expresiones. (f x y) se convierte en f(x, y) (requiere que ningún espacio entre el nombre de la función y sus parámetros)
  • Dulce-expresiones. Los padres de apertura y cierre se pueden reemplazar con (opcional) indentación semántica similar a python. Las expresiones dulces se pueden mezclar libremente con paréntesis tradicionales expresiones-s.

El resultado es código compatible con Lisp pero mucho más legible. Un ejemplo de cómo el nuevo azúcar sintáctico mejora la legibilidad:

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

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

Se convierte en:

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

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

Tenga en cuenta cómo la sintaxis es compatible con macros, lo cual fue un problema con proyectos anteriores que pretendían mejorar la sintaxis de Lisp (como lo describieron Wheeler y Gloria). Debido a que es solo azúcar, la forma final de cada nueva expresión es una expresión en s, transformada por el lector de idiomas antes de procesar las macros, por lo que las macros no necesitan ningún tratamiento especial. Por lo tanto, el proyecto" readable Lisp " conserva homoiconicity, la propiedad que permite a Lisp representar código como datos dentro del lenguaje, que es lo que le permite ser un poderoso entorno de meta-programación.

 19
Author: TuringTest,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2013-07-11 10:31:56

No tendrías que sacrificar nada. hay un enfoque muy cuidadosamente pensado por david wheeler que es completamente transparente y compatible con versiones anteriores, con soporte completo para macros, etc.

 13
Author: andrew cooke,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2012-03-08 22:29:53

Usted tendría Mathematica. Mathematica acepta llamadas a funciones como f[x, y, z], pero cuando se investiga más a fondo, se encuentra que f[x, y, z] es en realidad azúcar sintáctica para una lista en la queHead (elemento 0) es f y el Rest (elementos 1 a N) es {x, y, z}. Puede construir llamadas a funciones a partir de listas que se parecen mucho a expresiones-S y puede descomponer funciones no evaluadas en listas (Hold evita la evaluación, al igual que quote en Lisp).

Puede haber diferencias semánticas entre Mathematica y Lisp/Scheme/Clojure, pero la sintaxis de Mathematica es una demostración de que se puede mover el paréntesis izquierdo por un átomo y todavía interpretarlo con sensatez, construir código con macros, etc.

La sintaxis es bastante fácil de convertir con un preprocesador (mucho más fácil que la semántica). Probablemente podría obtener la sintaxis que desea a través de alguna subclase inteligente de LispReader de Clojure. Hay incluso un proyecto que busca resolver los paréntesis molestos de Clojure reemplazándolos todos con corchetes. (Me sorprende que esto se considere un gran problema.)

 3
Author: Jim Pivarski,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2014-01-31 16:59:10

Solía codificar C/C#/Java/Pascal, así que enfatizo con la sensación de que el código Lisp es un poco extraño. Sin embargo, esa sensación solo dura unas pocas semanas, después de un tiempo bastante corto, el estilo Lisp se sentirá muy natural y comenzarás a reprender a otros lenguajes por su sintaxis "irregular": -)

Hay una muy buena razón para la sintaxis Lisp. Los paréntesis iniciales hacen que el código sea lógicamente más fácil de analizar y leer, al recopilar tanto una función como las expresiones que componen sus argumentos en una sola forma.

Y cuando manipulas código / usas macros, son estas formas las que importan: estos son los bloques de construcción de todo tu código. Así que fundamentalmente tiene sentido poner los paréntesis en un lugar que delimite exactamente estas formas, en lugar de dejar arbitrariamente el primer elemento fuera de la forma.

 2
Author: mikera,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2012-03-03 02:14:30

La filosofía "el código es datos" es lo que hace posible la metaprogramación confiable. En comparación con Perl / Ruby, que tienen una sintaxis compleja, sus enfoques de metaprogramación solo son confiables en circunstancias muy limitadas. La metaprogramación de Lisp es tan perfectamente confiable que el núcleo del lenguaje depende de ello. La razón de esto es la sintaxis uniforme compartida por código y datos (la propiedad de homoiconicity). Las expresiones-S son la forma en que se realiza esta uniformidad.

Que dijo, hay circunstancias en Clojure donde el paréntesis implícito es posible:

Por ejemplo, las siguientes tres expresiones son equivalentes:

  1. (primero (descanso (descanso [1 2 3 4 5 6 7 8 9])))
  2. (-> [1 2 3 4 5 6 7 8 9] (rest) (rest) (first))
  3. (-> [1 2 3 4 5 6 7 8 9] descanso descanso primero)

Observe que en la tercera macro -> es capaz en este contexto de inferir paréntesis y por lo tanto dejarlos fuera. Hay muchos casos especiales como este. En el diseño del general Clojure se equivoca en el lado de menos paréntesis. Véase, por ejemplo, la controvertida decisión de omitir paréntesis en cond. Clojure tiene muchos principios y es coherente con esta elección.

 1
Author: rplevy,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2012-03-08 22:26:17

Curiosamente - hay una sintaxis de Raqueta alternativa :

@foo{blah blah blah}

Se lee como

(foo "blah blah blah")
 1
Author: hawkeye,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2014-09-12 07:30:57
Were Clojure to go down this path - what would it have to sacrifice to get there?

El sacrificio sería el sentimiento/mental-modal de escribir código creando Lista de Lista de Lista.. o más técnicamente "escribir el AST directamente".

NOTA: Hay otras cosas también que serán escarificadas como se menciona en otras respuestas.

 0
Author: Ankur,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2012-03-02 16:39:42