¿Por qué es tan importante estudiar un intérprete de lisp en lisp?

30

He visto muchos currículos de CS y sugerencias de aprendizaje para nuevos programadores que requieren que el aspirante a programador estudie un intérprete de lisp que está específicamente escrito en lisp. Todos estos sitios dicen cosas similares a "es una revelación intelectual", "es una experiencia de iluminación que todo programador serio debería tener" o "muestra relaciones hardware / software" y otras declaraciones vagas, particularmente de este artículo tomado de este reputado cómo hacerlo .

El sentimiento general de mi pregunta es, ¿cómo logra lisp los objetivos anteriores y por qué lisp? ¿Por qué no otro idioma?

Estoy preguntando esto porque acabo de terminar de escribir un intérprete de esquema en esquema (tomado de SICP http://mitpress.mit.edu/sicp/ ) y ahora estoy escribiendo un intérprete de Python en esquema y estoy luchando por tener esta legendaria epifanía se supone que proviene específicamente del primero. Estoy buscando detalles técnicos específicos entre los dos idiomas que pueda explotar en sus intérpretes de esquemas para comprender cómo funcionan los programas.

Más específicamente:

¿Por qué es tan enfatizado el estudio de un intérprete que está escrito en el idioma que interpreta? ¿Es simplemente un gran ejercicio mental para mantener el lenguaje original y el lenguaje correcto o existen problemas específicos cuyas soluciones solo se pueden encontrar en la naturaleza del lenguaje? ¿idioma original?

¿Cómo demuestran los intérpretes lisp buenos conceptos de arquitectura para el diseño de software futuro?

¿Qué extrañaría si hiciera este ejercicio en un lenguaje diferente como C ++ o Java?

¿Cuál es la comida para llevar o "herramienta mental" más utilizada en este ejercicio? ** **

** he seleccionado la respuesta que hice porque he notado que he obtenido de este ejercicio más habilidad en el diseño de herramientas de análisis sintáctico en mi cabeza que cualquier otra herramienta única y me gustaría encontrar diferentes métodos de análisis que pueden funcionar mejor para el esquema intérprete que el intérprete de python.

Ma-at
fuente
44
@gnat No es exactamente un consejo profesional, más una pregunta de "¿qué hay de bueno en Lisp?
Robert Harvey
1
@RobertHarvey ese enlace no es solo para la carrera sino también para el asesoramiento educativo , quise decir esto. Pero, bueno, Lisp-is-so-great es probablemente una buena opción también
mosquito
1
Parece que se pregunta qué aprenderá de un ejercicio en particular. Su reticencia es un signo de pereza, clave para cualquier buen programador, pero independientemente de la única forma de descubrir lo que aprenderá de un ejercicio es hacerlo y ver. Nadie puede decirte lo que aprenderás haciendo eso, solo tendrás que hacerlo.
Jimmy Hoffa
2
Si bien esta pregunta se relaciona con la educación en general, no la clasificaría como "consejo educativo" en la forma "¿Qué idioma debo aprender?" es. Es decir, no es específico de un determinado tipo de curso o trabajo. De hecho, si elimina algunas de las palabras de moda de la educación, esta es una pregunta sobre los lenguajes de programación en su conjunto, cuyas respuestas discuten las características del lenguaje. Tampoco es realmente específico de Lisp, pero se puede aplicar a otros lenguajes homoicónicos como xslt. Así que no diré que esta es una pregunta perfecta, solo que no es simplemente un "consejo profesional".
TheRubberDuck

Respuestas:

17

A riesgo de dar una respuesta "yo también", si lo intentas verás ...

Si estudias idiomas de computadora, es probable que tengas la impresión de que se trata al menos la mitad del análisis. Si aprende Lisp, se dará cuenta de que analizar la sintaxis de la superficie no es más que una conveniencia para las personas (como la mayoría de nosotros) a quienes no les gustan muchos paréntesis irritantes.

Entonces podría darse cuenta de que se pagó un gran precio por esa comodidad. En Lisp es trivial para un programa construir otro programa y ejecutarlo. En otros idiomas es una técnica avanzada, como hacer multiplicaciones en números romanos.

Por supuesto, casi todos preguntarían "¿quién necesita hacer eso?" Bueno, podrías ver muy bien que abre una vista completa de cosas que nunca antes te habías dado cuenta que no podías hacer antes. Puedes hacerlo en otros idiomas, pero no tan fácilmente.

INSERTADO para responder el comentario de Izkata:

  • El programa de comprensión del lenguaje natural de SHRDLU funcionó traduciendo una declaración o pregunta en inglés a un programa en un dialecto de Lisp llamado MICRO-PLANIFICADOR y ejecutándolo.
  • Los programas que manipulan programas, por ejemplo para simplificarlos o demostrar que son correctos, están escritos naturalmente en Lisp.
  • Utilicé la generación de programas en un programa para comprender escenas visuales, donde tenía que lidiar con todas las simetrías capaces en objetos tridimensionales, sin multiplicar el código.
  • Cualquier cosa que tenga que ver con la lógica y los acuerdos de prueba de teoremas en la manipulación de expresiones lógicas, que son una forma de programa.
  • Las matemáticas simbólicas, como el cálculo simbólico integral o diferencial, implica manipular expresiones matemáticas, que son como programas en miniatura.
  • Cualquier problema relacionado con la generación de código, o el término más elevado "evaluación parcial", es natural en Lisp. Hice esto para un programa de puente de base de datos hace mucho tiempo. Lo hice en C, que no fue tan fácil como Lisp, pero se me ocurrió la idea. Eso fue considerado como una técnica que casi nadie podía hacer en ese momento (especialmente las cabezas COBOL). Quizás más ahora, espero.

... son solo unos pocos ...

Entonces te das cuenta de que algunas cosas que hoy se consideran "modernas" han sido anticuadas en Lisp durante 40 años. Como la programación funcional. Como la recolección de basura. Como cierres.

Eso no quiere decir que los idiomas modernos no tengan nuevas buenas ideas, como OOP, etc. Pero si aprende Lisp, ampliará su perspectiva.

Mike Dunlavey
fuente
You can do it in other languages, but not nearly so easily.- ¿Me gusta? (La pregunta para mí parece ser porque a menudo se hacen declaraciones como estas, pero casi nunca se vuelven más específicas)
Izkata
Primero pensé que el mundo estaba revolucionado cuando me di cuenta de que JavaScript podía imprimir su propio código fuente y que los objetos podían atravesarse para obtener un literal de cadena que se podía evadir al literal del objeto. Luego me di cuenta de que Perl tenía esto todo junto con $ Data :: Dumper :: Deparse, y luego me di cuenta de que lisp lo tenía para siempre. La comprensión de los intérpretes desbloquea este poder que siempre ha existido para construir módulos vivos, y en Lisp esto es más accesible que cualquier otro idioma.
Dmitry
Lo curioso es que un programador de Lisp consciente de las funciones internas de Lisps siempre puede hacer su propio frontend de Lisp a cualquier lenguaje dinámico desde javascript a bash o perl o python; ceñir bien los bootstraps del entorno disponible.
Dmitry
19

La respuesta simple a su pregunta es probar Lisp, preferiblemente junto con SICP . Entonces serás iluminado.

Dicho eso ...

El código es datos
La mayoría de los idiomas hacen una distinción clara entre código y datos; Lisp no lo hace. Esto hace posible, por ejemplo, escribir trivialmente un analizador Lisp en Lisp y manipular el código Lisp dentro de Lisp. La mejor descripción de esta iluminación que he encontrado es La naturaleza de Lisp .

Esto es cierto en parte porque la sintaxis para el lenguaje es muy simple. Hace posibles cosas en Lisp (como la metaprogramación) que no son prácticas en otros idiomas porque la sintaxis se interpone en el camino.

Lecturas adicionales
Batir los promedios

Robert Harvey
fuente
3
El segundo párrafo no tiene sentido: homoiconicity! = Sintaxis simple; La sintaxis simple facilita la escritura de un analizador Lisp en cualquier idioma (consulte esto ). El tercer párrafo es vago, necesita ejemplos.
@MattFenwick es cierto que la homoiconicidad se puede hacer con una sintaxis compleja, pero eso sería extremadamente difícil. Es justo suponer que si se trata de una sintaxis homoicónica, será simple, si no por otra razón que la consistencia que se le exige, será ineficazmente más fácil de seguir que una sintaxis no homoicónica. Aunque su segundo punto es bueno, LISP es fácil de analizar porque es una sintaxis simple, no por homoiconicidad (incluso si la homoiconicidad es la causa de esa simplicidad)
Jimmy Hoffa
1
En cualquier caso, hay poca sobrecarga para tomar un valor de datos e interpretarlo como un programa. Esto es algo lindo La programación por configuración es sencilla cuando todo lo que tiene que hacer es escribir un intérprete para los datos de configuración. Las transformaciones matemáticas avanzadas (que son difíciles de implementar en idiomas con estado) a menudo se "reducen" a meras transformaciones sintácticas del fragmento puro de Lisp.
nomen
1
@MattFenwick: he eliminado la palabra "Homoiconicidad" de mi respuesta.
Robert Harvey
1
Desearía poder dar más de un +1 para The Nature of Lisp; Nunca he visto una explicación tan buena.
Doval
9

¿Por qué se enfatiza tanto el estudio de un intérprete que está escrito en el idioma que interpreta?

En general, estudiar a un intérprete le da una idea de su lenguaje y características. En general, estudiar código en un lenguaje de programación es como practicar un lenguaje hablado escuchando y leyendo: te familiariza con lo que ese lenguaje puede hacer, cómo se usa y los "modismos" comunes. Más específicamente, Lisp es un lenguaje homoicónico, lo que significa que su sintaxis para expresiones es la misma que su sintaxis para datos. Escribir código en Lisp se ve terriblemente como si estuvieras escribiendo una lista, y viceversa. Por lo tanto, interpretar el código Lisp con el código Lisp es tan simple como ejecutar listas con cary cdr.

¿Cómo debo capitalizar este ejercicio para aprovecharlo al máximo conceptualmente?

Piense en cómo se interpretaría el intérprete: en muchas implementaciones de intérpretes meta-circulares (donde un lenguaje homoicónico se interpreta a sí mismo) puede simplemente "pasar" por la función. Por ejemplo, para implementar car, simplemente tome carel argumento. Esto quita el énfasis de los mecanismos de almacenamiento de datos y se centra en la funcionalidad.

¿Cómo demuestran los intérpretes lisp buenos conceptos de arquitectura para el diseño de software futuro?

Los intérpretes pueden ser muy complicados, lo que fomenta una buena arquitectura al diseñarlos. Con eso en mente, este depende más del intérprete individual.

¿Qué extrañaría si hiciera este ejercicio en un lenguaje diferente como C ++ o Java?

Estos lenguajes no son homoicónicos, por lo que no se benefician de la gracia y la simplicidad de un intérprete meta-circular de Lisp. Esto hace que el ejercicio sea más difícil y quizás menos común, pero no diría que sea realmente menos beneficioso.

¿Cuál es la comida para llevar o "herramienta mental" más utilizada en este ejercicio?

No estoy seguro de tener una buena respuesta para esta; simplemente que ayuda a ver cómo funciona el intérprete y, lo que es más importante, jugar con él para ver cómo se pueden implementar fácilmente cambios menores en el idioma.

TheRubberDuck
fuente
5

LISP está estructurado de una manera que lo hace extremadamente fácil de analizar. Si intenta escribir un compilador, notará que es mucho más fácil si todo en su idioma es una expresión y tiene un bajo nivel de ambigüedad. LISP fuerza los paréntesis en todas partes para eliminar la ambigüedad y no tiene declaraciones, solo expresiones.

El hecho mismo de que LISP es muy fácil de analizar anima a los usuarios a analizar su propio código fuente y hacer trucos de magia con él. La línea entre los datos y el código se vuelve borrosa y puede hacer cosas que normalmente requieren bastante esfuerzo, como reflexión, reescritura dinámica de código, complementos y serialización.

Esa es la esencia de esto. El ejercicio probablemente tiene la intención de darle una idea de lo que es posible cuando el código es fácilmente analizable por sí mismo.

Alexander Torstling
fuente
No es Lisp lo que es fácil de analizar. Las expresiones S son fáciles de analizar. Además de eso, ENTONCES necesitas analizar Lisp.
Rainer Joswig
@Rainer: ¿No es eso una trampa? En mi mundo, analizar significa pasar del texto a un AST, que no dice nada acerca de la interpretación de los comandos.
Alexander Torstling
En C ++, el analizador detectará una declaración de función sintácticamente incorrecta. En Lisp no. El lector no sabe nada sobre el lenguaje de programación Lisp. El analizador de C ++ conoce la sintaxis completa de C ++. El lector Lisp solo conoce expresiones s.
Rainer Joswig,
Ah, entonces entiendo lo que quieres decir. Es cierto, aunque sigo pensando que un simple evaluador de lisp sería más sencillo de construir que uno simple de c ++. Eso es lo que hacen en SICP, ¿no es así (hace un tiempo que no lo leo)?
Alexander Torstling
El lenguaje utilizado en SICP es muy simple, ni siquiera el esquema completo. Un intérprete para un lenguaje similar a C también debería ser simple. C ++ es grande. Parte de su dificultad proviene de un número relativamente alto de sintaxis incorporada. En un sistema Lisp típico, gran parte de la sintaxis se construye con macros, fuera del intérprete. Las macros implementan la sintaxis y un mecanismo de extensión para las transformaciones de origen. Esto mantiene el núcleo más pequeño. Pero las macros pueden ser masivas. Por ejemplo, la implementación de la construcción LOOP tiene más de 2000 líneas de código macro complejo.
Rainer Joswig
4

No estoy seguro de que sea realmente importante para todos. Puede ser un desarrollador exitoso sin saber cómo funciona un intérprete Lisp. Sin embargo, al estudiar Ciencias de la Computación, las ideas básicas de Lisp deben aprenderse.

Los intérpretes de Lisp son importantes para los programadores de Lisp. Necesitan entender cómo funciona un intérprete ([y compilador] 1 ), para comprender completamente cómo usar el lenguaje.

Un intérprete Lisp se usa a menudo como una herramienta en informática para enseñar a los estudiantes algunas cosas:

Como dispositivo de enseñanza, un intérprete Lisp es útil, ya que se puede aprender y comprender en poco tiempo. Dado que pocos estudiantes ya saben acerca de Lisp, los estudiantes están en un campo nivelado cuando se trata de aprender sobre los conceptos.

Rainer Joswig
fuente