español ecmascript javascript lisp ecma262

javascript - español - ¿Es ECMAScript realmente un dialecto de Lisp?



ecmascript vs javascript (9)

"dialecto" definitivamente lo estira demasiado. Sin embargo, como alguien que aprendió y usó Python, Javascript y Scheme, Javascript claramente tiene una sensación de Lisp-ier muy lejos (y Coffeescript probablemente incluso más) que Python.

En cuanto a por qué el Simposio Europeo Lisp querría presentar Javascript como un Lisp, obviamente quieren aprovechar la popularidad del Javascript para el cual la población de programadores es muchas, muchas veces más grande que todos los demás dialectos Lisp en su lista combinada. .

Un amigo mío llamó mi atención sobre el mensaje de bienvenida del 4º Simposio europeo de Lisp :

... implementación y aplicación de cualquiera de los dialectos Lisp, incluidos Common Lisp, Scheme, Emacs Lisp, AutoLisp, ISLISP, Dylan, Clojure, ACL2, ECMAScript , ...

y luego le preguntaron si ECMAScript es realmente un dialecto de Lisp. ¿Realmente se puede considerar así? ¿Por qué?

¿Existe un conjunto de criterios bien definido y claro para ayudarnos a detectar si un idioma es un dialecto de Lisp? ¿O se está tomando un dialecto en un sentido muy laxo (y en ese caso podemos agregar Python, Perl, Haskell, etc. a la lista de dialectos Lisp?)


Aunque no llamaría JavaScript a Lisp, es, en mi humilde opinión, más parecido al modo Lisp de hacer las cosas que la mayoría de los lenguajes principales (incluso los más funcionales).

Por un lado, al igual que Lisp, es, en esencia, un lenguaje simple e imperativo basado en el cálculo lambda no tipificado que es apto para ser impulsado por un REPL.

En segundo lugar, es fácil incorporar datos literales (incluido el código en forma de expresiones lambda) en JavaScript, ya que un subconjunto de este es equivalente a JSON. Este es un patrón de Lisp común.

En tercer lugar, su modelo de valores y tipos es muy liso. Está orientado a objetos en un sentido amplio de la palabra en el sentido de que todos los valores tienen un concepto de identidad, pero no está particularmente orientado a objetos en los sentidos más estrechos de la palabra. Al igual que en Lisp, los objetos se escriben a máquina y son muy dinámicos. El código generalmente se divide en unidades de funciones, no en clases.

De hecho, hay un par de desarrollos (más o menos) recientes en el mundo de JavaScript que hacen que el idioma se sienta bastante liso a veces. Tome jQuery, por ejemplo. La incrustación de selectores de CSS como un sublenguaje es un enfoque bastante parecido a Lisp, en mi opinión. O considere el protocolo de metaobjetos de ECMAScript Harmony: realmente parece un puerto directo de Common Lisp (¡mucho más que los sistemas de metaobjetos de Python o Ruby!). La lista continua.

JavaScript carece de macros y una implementación sensata de un REPL con integración de editor, lo cual es desafortunado. Ciertamente, las influencias de otros idiomas también son muy visibles (y no necesariamente malas). Aún así, existe una gran cantidad de compatibilidad cultural entre los campamentos Lisp y JavaScript. Algunos de ellos pueden ser una coincidencia (como el reciente aumento de la compilación JIT de JavaScript), algunos sistemáticos, pero definitivamente están ahí.


Brendan Eich quería hacer un lenguaje tipo esquema para Netscape, pero la realidad intervino y terminó teniendo que conformarse con algo que se parecía vagamente a C y Java para personas "normales", pero que funcionaba como un lenguaje funcional.

Personalmente, creo que es un esfuerzo innecesario llamar a ECMAScript "Lisp", pero cada uno es suyo. La clave de un Lisp real parece ser la característica de que la notación de estructura de datos y la notación de códigos son las mismas, y eso no es cierto acerca de ECMAScript (o Ruby o Python o cualquier otro lenguaje funcional dinámico que no sea Lisp).

Advertencia: no tengo credenciales de Lisp :-)


Creo que ECMAScript es un dialecto de LISP en el mismo sentido en que el inglés es un dialecto del francés. Hay puntos en común, pero tendrás problemas con las asignaciones de una sola armada solo con el conocimiento de la otra :)

Me parece interesante que solo una de las tres presentaciones principales destacadas para el 4º Simposio Europeo de Lisp concierne directamente a Lisp (las otras dos son sobre x86 / JVM / Python y Scala).


No es un "dialecto". Aprendí LISP en los años 70 y no lo he usado desde entonces, pero cuando aprendí JavaScript recientemente me encontré pensando que era similar a LISP. Creo que eso se debe a dos factores: (1) JSON es una estructura asociativa similar a una lista y (2) parece que los ''objetos'' de JS son esencialmente JSON. Así que, aunque no escriba programas JS en JSON como escribiría LISP en listas, casi lo hace.

Así que mi respuesta es que hay suficientes similitudes que los programadores familiarizados con LISP recordarán cuando usen JavaScript. Declaraciones como JS = LISP en un traje de Java solo expresan esa sensación. Creo que eso es todo.


No es. Tiene muchas raíces funcionales, pero también lo hacen muchos otros idiomas que no son lisp, como usted señaló.

Los Lisps tienen una característica restante que los hace lisps, que es que el código de lisp está escrito en términos de estructuras de datos lisp (homoiconicidad). Esto es lo que habilita el potente sistema de macros de lisps, y por qué se ve tan extraño para los que no escuchan. Una llamada a función es solo una lista, donde el primer elemento de la lista es el nombre de la función.

Como el código de lisp es solo un ceceo de datos, es posible hacer algunas cosas extremadamente poderosas con la metaprogramación, que simplemente no se puede hacer en otros idiomas. Muchos cefaleas, incluso los modernos, como clojure, se implementan en gran medida en sí mismos como un conjunto de macros.


No, no es.

Para ser considerado un Lisp, uno tiene que ser homoicónico, lo cual no es ECMAscript.


Sí lo es. Citando a Crockford:

"JavaScript tiene mucho en común con Scheme. Es un lenguaje dinámico. Tiene un tipo de datos flexible (matrices) que puede simular fácilmente expresiones s. Y lo más importante, las funciones son lambdas.

Debido a esta gran similitud, todas las funciones de [primer programador recursivo] ''The Little Schemer'' se pueden escribir en JavaScript ".
http://www.crockford.com/javascript/little.html

Sobre el tema de la homoiconicidad, recomendaría buscar esa palabra junto con JavaScript. Decir que no es "homoicónico" es cierto, pero no es el final de la historia.


Si llama a ECMAScript Lisp, básicamente está afirmando que cualquier lenguaje dinámico es Lisp. Como ya tenemos un "lenguaje dinámico", estás reduciendo "Lisp" a un sinónimo inútil para él en lugar de permitirle tener un significado más específico.

Lisp debe referirse a un lenguaje con ciertos atributos.

Un lenguaje es Lisp si:

  • Su código fuente es datos estructurados en árbol, que tiene una notación impresa directa como listas anidadas. Cada estructura de árbol posible tiene una representación en la notación correspondiente y es susceptible de recibir un significado como construcción; la notación en sí no tiene que ser extendida para extender el idioma.

  • Los datos estructurados en árbol son una estructura de datos principal en el lenguaje mismo, lo que hace que los programas sean susceptibles de manipulación por parte de los programas.

  • El idioma tiene un tipo de datos de símbolo. Los símbolos tienen una representación impresa que se interna : cuando dos o más instancias de la misma notación impresa para un símbolo aparecen en la notación, todas denotan el mismo objeto.

    • La virtud principal de un objeto de símbolo es que es diferente de todos los demás símbolos. Los símbolos se combinan con varias otras entidades de varias maneras en la semántica de los programas Lisp y, por lo tanto, sirven como nombres para esas entidades.
    • Por ejemplo, el dialecto de Lisp generalmente tiene variables, al igual que otros idiomas. En Lisp, las variables se denotan por símbolos (los objetos en la memoria) en lugar de nombres de texto. Cuando parte de un programa Lisp define alguna variable a , la sintaxis para ese a es un objeto de símbolo y no la cadena de caracteres "a" , que es solo el nombre de ese símbolo para imprimir. Una referencia a la variable, la expresión escrita como a otro lugar en el programa, también es un objeto on. Debido a la forma en que funcionan los símbolos, es el mismo objeto; este objeto sameness luego conecta la referencia a la definición. La uniformidad del objeto se puede implementar como igualdad del puntero en el nivel de la máquina. Sabemos que dos valores de símbolo son iguales porque son punteros a la misma ubicación de memoria en el montón (un objeto de tipo de símbolo).
    • Ejemplo: el dialecto NewLisp que tiene una gestión de memoria no tradicional para la mayoría de los tipos de datos, incluidas las listas anidadas , hace una excepción para los símbolos al hacer que se comporten de la manera anterior. Sin esto, no sería Lisp. Cita: "Los objetos en newLISP ( sin incluir símbolos y contextos) pasan por la copia de valor a otras funciones definidas por el usuario. Como resultado, cada nuevo objetoLISP solo requiere una referencia". [énfasis mío]. Pasar símbolos también, como por valor de copia, destruiría su identidad: una función que recibe un símbolo no obtendría la original y, por lo tanto, no recibiría correctamente su identidad.
  • Las expresiones compuestas en un lenguaje Lisp -las que no son primarias simples como números o cadenas- consisten en una lista simple, cuyo primer elemento es un símbolo que indica la operación. Los elementos restantes, si los hay, son expresiones de argumento. El dialecto de Lisp aplica algún tipo de estrategia de evaluación para reducir la expresión a un valor y evocar cualquier efecto secundario que pueda tener.
  • Podría argumentar tentativamente que las listas hechas con celdas binarias que contienen pares de valores, terminadas por un objeto de lista vacío especial, probablemente deberían considerarse parte de la definición de Lisp: todo el asunto de poder hacer una nueva lista de un uno existente "consing" un nuevo elemento en el frente, y la fácil recursión en el "primer" y "resto" de una lista, y así sucesivamente.

Y luego me detendría allí mismo. Algunas personas creen que los sistemas Lisp deben ser interactivos: proporcionan un entorno con un oyente, en el que todo se puede modificar, y se puede redefinir en cualquier momento, y así sucesivamente. Algunos creen que Lisps tiene que tener funciones de primera clase: que tiene que haber un operador lambda , y así sucesivamente. Los tradicionalistas acérrimos pueden incluso insistir en que tiene que haber funciones de car y cdr , la notación de puntos dotados de listas impropias, y que las listas deben estar formadas por celdas, y terminadas específicamente por el símbolo nil denota la lista vacía, y también un booleano falso. Insistir en car y cdr permite que Scheme sea un Lisp, pero nil sea ​​el terminador de lista y las reglas falsas

Sin embargo, cuanto más profundizamos en la definición de "dialecto de Lisp", más se vuelve político; la gente se molesta porque su dialecto favorito (tal vez el que ellos mismos crearon) está siendo excluido por algún tecnicismo. Insistir en car y cdr permite que Scheme sea un Lisp, pero nil es el terminador de la lista y el falso lo descarta. ¿Qué, Scheme no es un Lisp?

Entonces, basado en lo anterior, ECMAScript no es un dialecto de Lisp. Sin embargo, una implementación de ECMAScript contiene una funcionalidad que puede exponerse como un dialecto Lisp y se han desarrollado numerosos dialectos de este tipo . Alguien que necesita quiere que ECMAScript sea considerado un Lisp por algunas razones emocionales, tal vez debería contentarse con eso: que la semántica para soportar Lisp está ahí, y solo necesita una interfaz adecuada para esa semántica, que se puede desarrollar en ECMAScript y que puede interoperar con el código ECMAScript.