Décima regla de Greenspun, ¿todo proyecto grande incluye un intérprete Lisp? [cerrado]


12

La décima regla de Greenspun (en realidad la única regla) establece que:

Any sufficiently complicated C or Fortran program contains an ad hoc, informally-specified, bug-ridden, slow implementation of half of Common Lisp.

Mi memoria es que hay algunos documentos sobre el tema, tal vez para el proyecto Quattro (hoja de cálculo) de Borland y posiblemente otros. Google no es útil, tal vez no se te ocurran los términos de búsqueda correctos. Estoy buscando documentos o artículos que respalden esta afirmación, si corresponde.


8
¿Leíste la explicación del significado de la regla en el artículo de Wikipedia? Dudo que haya un esfuerzo serio para confirmar o refutar el reclamo, en realidad no estaba destinado a ser tomado en serio .
Yannis

3
Lo curioso es que, si bien la regla de Greenspun era solo una broma, en realidad trabajé en un software de simulación que tenía un intérprete LISP incorporado. La configuración del software se realizó a través de S-Expressions y uno podría haber escrito código LISP para hacer varias cosas en la configuración.
wkl

@YannisRizos - Literalmente, ninguno de sus enlaces afirma que la Regla es una broma. Sin embargo, la Ley de Morris está enmarcada como tal. Ahora, en sentido figurado ...
casualcoder

2
@casualcoder "Es irónico que esto, después de mi muerte, sea probablemente lo único que alguien recuerde de mis escritos". y el nombramiento de la regla insinúa que fue escrita de una manera alegre ...
yannis

¿No hubo una cita similar con respecto a Erlang y los programas concurrentes?
Giorgio

Respuestas:


15

La declaración es una hipérbole. Pero hay signos obvios de envidia de Lisp en otros idiomas. Mire C # y cómo se está volviendo más funcional en la naturaleza. Observe los diversos marcos de Business Process Management, workflow y EAI que hacen todo lo posible para que sea posible programar el sistema sin cambiar el programa.

Hay un libro sobre lenguajes específicos de dominio de Martin Fowler que habla sobre cómo hacer metaprogramación en lenguajes orientados a objetos. Entonces hay algo de verdad en la hipérbole.

Paul Graham calificó a Lisp como el lenguaje más poderoso al observar la lista de los primeros que vinieron con Lisp , es fácil ver por qué muchos idiomas palidecen en comparación.

El camino alrededor de la décima regla es la programación políglota. Al darse cuenta de que un idioma / marco no es el martillo de oro. Luego, en lugar de crear una implementación pobre y ad hoc de Lisp, puede usar Lisp.


44
El poder y la edad son independientes. Es realmente irrelevante lo bueno o malo que era LISP en el momento de su creación, importa cómo se compara con los idiomas de hoy. Los primeros no tienen importancia.
DeadMG

2
@DeadMG, estos "primeros" no son nada en comparación con las cosas que aún no se han portado de Lisp a los otros idiomas.
SK-logic

1
@DeadMG, tienes razón. Una de las cosas que la gente ama de Ruby después de comenzar a investigar es el aspecto de la metaprogramación. Lisp tiene eso incorporado. Los desarrolladores de C # adoran LINQ (con buenas razones) y las implicaciones que la programación declarativa tiene en la concurrencia. Lisp tiene eso en picas. A medida que los sistemas se vuelven más complejos, se vuelven más sobre los nodos que reaccionan a los mensajes y menos sobre los objetos. Lisp comienza allí, la mayoría de los otros idiomas tienen que agregarlo ya sea ad hoc (de ahí la regla) o mediante un marco (por ejemplo, Biztalk, Tibco, etc.).
Michael Brown

2
"en lugar de crear una implementación pobre y ad hoc de Lisp, simplemente puede usar Lisp", pero el corolario de Morris significa que todavía está usando una implementación pobre y ad hoc;)
jk.

1
Nota al margen perfecta para esa entrada "los piratas informáticos a menudo perciben la totalidad de la cultura hacker como ha-ha-solo-seria; tomarla demasiado a la ligera o demasiado en serio marca a una persona como un extraño, un aspirante o en estado larval . "
Michael Brown

10

La "décima regla" de Greenspun fue un poco snark. Cuando se estira lo suficiente, si hace que cubra "cualquier sistema de script o configuración", entonces obviamente la respuesta a esta pregunta tendrá que ser "sí", ya que la configuración es algo que cualquier programa no trivial requiere en algún grado, y el script es solo un poco menos común a medida que avanza la escala de complejidad.

Por otro lado, eche un vistazo a GOAL , una variante de Lisp inventada por Naughty Dog para la programación de juegos. No se parece mucho a Lisp "clásico". Es un sistema de estilo altamente imperativo, con funcionalidad orientada a objetos, sin intérprete, soporte mínimo para la recolección de basura (confiando en su lugar en instalaciones de limpieza de nivel de tiempo de ejecución) y amplio soporte para ensamblaje en línea.

En otras palabras, cuando intentaron usar Lisp para un proyecto suficientemente complejo, ¡descubrieron que para hacer algo útil tenían que convertir el lenguaje en una implementación ad-hoc, especificada informalmente de la mitad de C ++! ;) (Y finalmente tuvieron que dejar de usarlo después de que el tipo que diseñó GOAL se fue, porque nadie podía entender su código).


Supongo que mi pregunta es sobre partes específicas de un sistema grande. Eventualmente, el sistema tendrá partes que están mejor codificadas en otro idioma debido a los procesos de pensamiento o técnicas involucradas en el uso de ese lenguaje, en lugar de la velocidad inherente o la superioridad. La historia del Sr. Lenaghan es un ejemplo.
casualcoder

En realidad, dejaron de usar GOAL porque fueron comprados por una compañía cuyo código base estaba en C ++. Además, el objetivo fue bastante lisp. No asuma más bajo denominador tutoriales en línea y conferencias en la universidad son correctos :)
P_L

9

Curiosamente, una respuesta a esta pregunta ya está en Programmers SE .

Para citar la parte relevante:

El punto de Greenspun fue (en parte) que muchos programas complejos tienen intérpretes incorporados. En lugar de construir un intérprete en un idioma, sugirió que podría tener más sentido usar un lenguaje como Lisp que ya tiene un intérprete (o compilador) incorporado.

En ese momento, había estado trabajando en una aplicación bastante grande que realizaba cálculos definidos por el usuario utilizando un intérprete personalizado para un idioma personalizado. Decidí intentar reescribir su núcleo en Lisp como un experimento a gran escala.

Tomó aproximadamente seis semanas. El código original era ~ 100,000 líneas de Delphi (una variante de Pascal). En Lisp eso se redujo a ~ 10,000 líneas. Sin embargo, aún más sorprendente fue el hecho de que el motor Lisp era 3-6 veces más rápido. ¡Y tenga en cuenta que este fue el trabajo de un neófito Lisp! Toda esa experiencia me abrió los ojos; Por primera vez, vi la posibilidad de combinar rendimiento y expresividad en un solo idioma.
- Michael Lenaghan

Para aclarar aún más esa parte, Michael respondió a un comentario con:

¡Guau, eso debe haber sido un código de Delphi realmente horrible si de alguna manera logró funcionar 3-6 veces más lento que una implementación de Lisp! "Correcto, lo contaré como mi error por no explicarlo mejor. expresiones de usuario en expresiones Lisp, un proceso trivialmente fácil, y luego compila las expresiones Lisp en código nativo (con optimización completa). Ese es el significado de la Décima Regla de Greenspun.
-– Michael Lenaghan

Dado que esta respuesta se compone de la respuesta de otra persona en otra parte, es una wiki comunitaria.


2

La regla es una broma, pero hay un poco de verdad en ella. Cualquier sistema complejo contendría una cantidad de partes interpretadas (vea, cómo el "patrón de intérprete" es popular entre aquellos que creen en todos esos patrones mumbo-jumbo). Cualquier sistema complejo debe proporcionar algunos medios de configuración, a menudo estructurados, a menudo interpretados.

Es muy probable que cualquier sistema complejo tenga varios pases de generación de código y varios preprocesadores personalizados en su proceso de construcción (piense en cosas como mocen Qt o tablegenen LLVM).

Muchos sistemas están haciendo malabarismos con las complejas estructuras de datos en forma de árbol utilizando un conjunto (casi siempre) de herramientas para caminar y transformar árboles mal diseñadas, que se parecen mucho a la funcionalidad de la biblioteca de Common Lisp.

Todas estas cosas vienen gratis con Lisp, y en la mayoría de los casos, todas esas implementaciones ad hoc, no planificadas, no pensadas a fondo, serían completamente inferiores.


2

Cualquier sistema suficientemente complejo tendrá conceptos y requisitos específicos del dominio que son extremadamente difíciles de expresar con las abstracciones del lenguaje en el que está trabajando. Esto inadvertidamente obliga a los programadores a crear abstracciones específicas del dominio para aliviar la carga de cerrar la brecha semántica entre el lenguaje de programación y el dominio específico. Una vez que hay suficientes de estas abstracciones, básicamente tienes un intérprete de un lenguaje específico de dominio. Esta es una parte inevitable del desarrollo de software.


1

La regla probablemente podría ser más precisa (y menos divertida) ya que "se requerirá que cada sistema basado en software grande implemente un comportamiento dinámico".

Esto se puede hacer de dos maneras-

  1. Un gran archivo de configuración complejo con docenas de parámetros y cientos de definiciones.

  2. Un lenguaje de script AD-HOC.

"sendmail" es probablemente el ejemplo canónico del tipo "1". No puedo pensar en ningún buen ejemplo de tipo "2" que no implique la incorporación de un lenguaje de script "real" a la Warcraft / LUA o incluso Netscape / Javascript.

El problema es que, para algunos parámetros, es rápido y sencillo hacerlo con un archivo de configuración, pero esta solución realmente no escala. Sin embargo, en ningún momento será económico volcar el archivo de configuración a favor de un enfoque de script al agregar una o dos opciones al archivo de configuración. Entonces, el código que interpreta el archivo de configuración acaba siendo un intérprete muy mal escrito.


0

Eso puede ser cierto, como otros han dicho, muchos programas requieren configurabilidad y, por lo tanto, contienen varios intérpretes tipo lisp.

Sin embargo, la declaración también implica con una sonrisa que todo lo que necesita para hacer un programa es Lisp, y que todos los demás lenguajes son inferiores.

Pero está mal, Lisp puede ser expresivo, pero también es demasiado abstracto, trata de ocultar detalles de una plataforma y simula que solo existen listas en el mundo de las computadoras.

La realidad de la programación de alto rendimiento es que a veces necesitamos mezclarnos con bits y bytes, y hacer cosas específicas del sistema operativo, por lo que no es posible hacer todo solo con Lisp como lo implica la declaración.

Es más bien al revés, no importa cuán complicado, inteligente o sofisticado sea el lenguaje que inventes, todo lo que termina siendo es simplemente otra forma de escribir ensamblado.


Parece relevante solo para los entornos de ceceo más antiguos de finales de los 50. Personalmente, encontré que las funciones de Common Lisp para tratar con bits son probablemente una de las mejores (con la competencia principal como Erlang). Las matrices, tablas hash, estructuras son todos comunes.
p_l

Es fácil compilar compiladores para Lisp ya que no necesita analizarlo. Se podrían hacer funciones de Lisp y un compilador de macros (que es como el evaluador de Lisp de solo una página y media de código al principio) que convierte esas expresiones de Lista en C, y está escribiendo en C en Lisp pero con todo el poder de macros y cálculo lambda si quieres.
aoeu256

0

Ya sea que haya sido tomado en serio o no, es cierto para los proyectos C y C ++ más grandes en los que he trabajado.

Lo que no es cierto es que los lenguajes de script personalizados se parecen a Common Lisp. Los ejemplos positivos se asemejan a Scheme (porque los diseñadores más inteligentes integraron Guile, SpiderMonkey y Lua en lugar de inventar su propio idioma). Los ejemplos más dignos de DailyWTF fueron un lenguaje similar a Forth y un lenguaje similar a MUMPS.

Otro ejemplo (no estoy seguro si cuenta como Greenspunning, pero ciertamente un WTF) fue un intérprete XSLT utilizado para secuencias de comandos de propósito general. Esto era más parecido a Lisp, ya que agregaron un ciclo de retroalimentación donde la salida se transformaría XSLT por segunda vez, por lo que ahora tiene macros de manera efectiva.
Sin embargo, el motivo aquí no era obtener acceso a las funciones de lispy, sino eludir los procedimientos de control de calidad del código de la empresa (que agregaban 3 semanas de latencia a cada corrección de errores. XML se consideraba "datos" y estaba exento del proceso).


-1

¡Lamentablemente no!

Si bien es mejor integrar un intérprete real de lisp (y) (javascript o lua alos hace un buen trabajo), agregar un homebrew 4gl a un proyecto reduce el tamaño general al tiempo que aumenta la flexibilidad.

Los proyectos que "codifican todo" tienen un recuento de módulos mucho mayor y se vuelven difíciles de manejar e inflexibles.

Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.