La dixième règle de Greenspun, chaque grand projet comprend-il un interprète Lisp? [fermé]


12

La dixième règle de Greenspun (en fait la seule règle) stipule que:

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

Je me souviens qu'il y a des articles sur le sujet, peut-être pour le projet Quattro (tableur) de Borland et peut-être d'autres. Google est inutile, peut-être que les bons termes de recherche ne vous viennent pas à l'esprit. Je recherche des documents ou des articles à l'appui de cette affirmation, le cas échéant.


8
Avez-vous lu l' explication de la signification de la règle dans l'article Wikipedia? Je doute qu'il y aurait de sérieux efforts pour confirmer ou infirmer la réclamation, elle n'était pas vraiment destinée à être prise au sérieux .
yannis

3
Ce qui est drôle, c'est que même si la règle de Greenspun n'était qu'une blague, j'ai en fait travaillé sur un logiciel de simulation doté d'un interpréteur LISP intégré. La configuration du logiciel a été entièrement effectuée via S-Expressions et on aurait pu imaginer écrire du code LISP pour faire diverses choses dans la configuration.
wkl

@YannisRizos - Littéralement, aucun de vos liens ne prétend que la règle est une blague. La loi de Morris est cependant conçue comme telle. Maintenant, au figuré ....
casualcoder

2
@casualcoder "Il est ironique que ce soit, après ma mort, la seule chose dont tout le monde se souvienne de mes écrits." et la dénomination de la règle laisse entendre qu'elle a été écrite de manière légère ...
yannis

N'y avait-il pas une citation similaire concernant Erlang et les programmes concurrents?
Giorgio

Réponses:


15

L'énoncé est hyperbole. Mais il existe des signes évidents d'envie Lisp dans d'autres langues. Regardez C # et comment il devient de plus en plus fonctionnel. Regardez les différents cadres de gestion des processus métier, de workflow et d'EAI qui se mettent en quatre pour permettre de programmer le système sans changer le programme.

Il y a un livre sur les langages spécifiques au domaine de Martin Fowler qui explique comment faire de la méta-programmation dans les langages orientés objet. Il y a donc une part de vérité dans l'hyperbole.

Paul Graham a appelé Lisp la langue la plus puissante en regardant la liste des premières livrées avec Lisp , il est facile de voir pourquoi de nombreuses langues pâlissent en comparaison.

La voie autour de la dixième règle est la programmation polyglotte. Réaliser qu'un seul langage / framework n'est pas le marteau d'or. Ensuite, au lieu de créer une mauvaise implémentation ad hoc de Lisp, vous pouvez simplement utiliser Lisp.


4
Le pouvoir et l'âge sont indépendants. Il n'est vraiment pas pertinent de savoir à quel point LISP était bon ou mauvais au moment de sa création, peu importe comment il se compare aux langues d'aujourd'hui. Les premiers sont tout à fait sans importance.
DeadMG

2
@DeadMG, ces "premières" ne sont rien comparées aux choses qui n'ont pas encore été portées de Lisp vers les autres langues.
SK-logic

1
@DeadMG, vous avez raison. L'une des choses que les gens aiment à propos de Ruby après avoir commencé à creuser, c'est l'aspect méta-programmation. Lisp a cela intégré. Les développeurs C # adorent LINQ (avec raison) et les implications de la programmation déclarative sur la concurrence. Lisp a cela à la pelle. À mesure que les systèmes deviennent plus complexes, ils deviennent davantage des nœuds réagissant aux messages et moins des objets. Lisp commence là-bas, la plupart des autres langages doivent l'appliquer soit ad hoc (d'où la règle), soit via un framework (par exemple Biztalk, Tibco, etc.).
Michael Brown

2
"au lieu de créer une mauvaise implémentation ad hoc de Lisp, vous pouvez simplement utiliser Lisp" mais le corollaire de Morris signifie que vous utilisez toujours une implémentation pauvre et ad hoc;)
jk.

1
Parfait sidérote à cette entrée "l'intégralité de la culture des hackers est souvent perçue comme ha-ha-only-serious par les hackers eux-mêmes; le prendre trop à la légère ou trop au sérieux marque une personne comme un outsider, un wannabee ou au stade larvaire . "
Michael Brown

10

La «dixième règle» de Greenspun était un peu snark. Lorsqu'il est suffisamment étendu, si vous le faites couvrir "tout système de script ou de configuration", la réponse à cette question devra évidemment être "oui", car la configuration est quelque chose que tout programme non trivial nécessite dans une certaine mesure, et le script n'est que légèrement moins courant lorsque vous montez dans l'échelle de complexité.

D'un autre côté, jetez un œil à GOAL , une variante Lisp inventée par Naughty Dog pour la programmation de jeux. Cela ne ressemble pas du tout au Lisp "classique". Il s'agit d'un système de style hautement impératif, avec des fonctionnalités orientées objet, pas d'interpréteur, une prise en charge minimale de la récupération de place (en s'appuyant à la place sur des installations de nettoyage au niveau de l'exécution) et une prise en charge étendue de l'assemblage en ligne.

En d'autres termes, lorsqu'ils ont essayé d'utiliser Lisp pour un projet suffisamment complexe, ils ont constaté que pour faire quoi que ce soit d'utile, ils devaient transformer le langage en une implémentation ad hoc et spécifiée de manière informelle de la moitié de C ++! ;) (Et ils ont finalement dû cesser de l'utiliser après le départ du gars qui a conçu GOAL, car personne ne pouvait comprendre son code.)


Je suppose que ma question concerne des parties spécifiques d'un grand système. Finalement, le système aura des parties qui sont mieux codées dans une autre langue en raison des processus de pensée ou des techniques impliqués dans l'utilisation de cette langue, plutôt que de la vitesse ou de la supériorité inhérente. L'histoire de M. Lenaghan en est un exemple.
casualcoder

En fait, ils ont cessé d'utiliser GOAL parce qu'ils ont été achetés par une société dont la base de code était en C ++. De plus, GOAL était assez lisp. Ne présumez pas que les didacticiels en ligne et les conférences universitaires au plus petit dénominateur sont corrects :)
p_l

9

Curieusement, une réponse à cette question se trouve déjà dans Programmers SE .

Pour citer la partie pertinente:

Le point de Greenspun était (en partie) que de nombreux programmes complexes ont des interprètes intégrés. Plutôt que de construire un interprète dans une langue, il a suggéré qu'il serait plus logique d'utiliser une langue comme Lisp qui a déjà un interprète (ou un compilateur) intégré.

À l'époque, je travaillais sur une application assez grande qui effectuait des calculs définis par l'utilisateur à l'aide d'un interpréteur personnalisé pour une langue personnalisée. J'ai décidé d'essayer de réécrire son noyau en Lisp comme une expérience à grande échelle.

Cela a pris environ six semaines. Le code d'origine était d'environ 100 000 lignes de Delphi (une variante Pascal). À Lisp, ce nombre a été réduit à environ 10 000 lignes. Encore plus surprenant, cependant, le fait que le moteur Lisp était 3-6 fois plus rapide. Et gardez à l'esprit que c'était l'œuvre d'un néophyte Lisp! Toute cette expérience m'a ouvert les yeux; pour la première fois, j'ai vu la possibilité de combiner performance et expressivité dans une seule langue.
- Michael Lenaghan

Pour clarifier davantage cette partie, Michael a répondu à un commentaire avec:

Wow, cela a dû être un code Delphi vraiment horrible s'il réussissait en quelque sorte à fonctionner 3-6x plus lentement qu'une implémentation Lisp! "D'accord, je compterai cela comme mon échec pour ne pas l'expliquer mieux. expressions utilisateur en expressions Lisp - un processus trivialement facile - puis compilez les expressions Lisp en code natif (avec optimisation complète). C'est le sens de la dixième règle de Greenspun.
- Michael Lenaghan

Étant donné que cette réponse est composée de la réponse de quelqu'un d'autre ailleurs, il s'agit d'un wiki communautaire.


2

La règle est une blague, mais elle contient un peu de vérité. Tout système complexe contiendrait un certain nombre de parties interprétées (voir comment le «modèle d'interpréteur» est populaire parmi ceux qui croient en tous ces modèles. Mumbo-jumbo). Tout système complexe doit fournir des moyens de configuration, souvent structurés, souvent interprétés.

Tout système complexe est très susceptible d'avoir plusieurs passes de génération de code et divers préprocesseurs personnalisés dans son processus de construction (pensez à des choses comme mocdans Qt ou tablegendans LLVM).

De nombreux systèmes jonglent avec les structures de données arborescentes complexes en utilisant un ensemble (presque toujours) d'outils d'arborescence et de transformation mal conçus ressemblant étroitement à la fonctionnalité de bibliothèque de Common Lisp.

Toutes ces choses sont gratuites avec Lisp, et dans la plupart des cas, toutes les implémentations ad hoc, imprévues et non réfléchies, seraient complètement inférieures.


2

Tout système suffisamment complexe aura des concepts et des exigences spécifiques au domaine qui sont extrêmement difficiles à exprimer avec les abstractions du langage dans lequel vous travaillez. Cela oblige par inadvertance les programmeurs à créer des abstractions spécifiques au domaine pour alléger le fardeau de combler l'écart sémantique entre le langage de programmation. et le domaine spécifique. Une fois qu'il y a suffisamment de ces abstractions, vous disposez essentiellement d'un interprète d'une langue spécifique au domaine. C'est une partie inévitable du développement logiciel.


1

La règle pourrait probablement être plus précise (et moins amusante) car "chaque grand système basé sur un logiciel sera nécessaire pour implémenter un comportement dynamique".

Ceci peut être fait de deux façons-

  1. Un grand fichier de configuration complexe avec des dizaines de paramètres et des centaines de définitions.

  2. Un langage de script AD-HOC.

"sendmail" est probablement l'exemple canonique de type "1". Je ne peux pas penser à de bons exemples de type "2" qui n'impliquent pas l'intégration d'un "vrai" langage de script à la Warcraft / LUA ou même Netscape / Javascript.

Le problème est que pour quelques paramètres, il est simple et rapide de le faire avec un fichier de configuration, mais cette solution n'est pas vraiment évolutive. Cependant, il ne sera à aucun moment économique de vider le fichier de configuration en faveur d'une approche de script lors de l'ajout d'une ou deux options au fichier de configuration. Ainsi, le code qui interprète le fichier de configuration finit par être un interpréteur vraiment mal écrit.


0

Cela peut être vrai, comme d'autres l'ont dit, de nombreux programmes nécessitent une configurabilité et contiennent donc divers interpréteurs de type lisp.

Cependant, la déclaration implique également avec un sourire narquois que tout ce dont vous avez besoin pour créer un programme est Lisp, et que toutes les autres langues lui sont inférieures.

Mais c'est faux, Lisp peut être expressif, mais c'est aussi trop abstrait, il essaie de cacher les détails d'une plate-forme et de ne faire que des listes dans le monde informatique.

La réalité de la programmation haute performance, c'est que parfois nous avons besoin de nous mêler à des bits et des octets, et de faire des choses spécifiques au système d'exploitation, il n'est donc pas possible de tout faire avec seulement Lisp comme l'indique la déclaration.

C'est plutôt l'inverse, peu importe la complexité, l'intelligence ou la sophistication d'un langage que vous inventez, tout ce qu'il finit par être n'est qu'une autre façon d'écrire l'assemblage.


Semble ne concerner que les environnements les plus anciens de la fin des années 50. Personnellement, j'ai trouvé les fonctions de Common Lisp pour traiter les bits probablement l'une des meilleures (la principale concurrence étant Erlang). Les tableaux, les tables de hachage, les structures sont tous courants.
p_l

Il est facile d'écrire des compilateurs pour Lisp car vous n'avez pas besoin de l'analyser. Des fonctions Lisp pourraient être créées et un compilateur de macros (qui ne ressemble à l'évaluateur Lisp qu'une à une demi-page de code au début) qui transforme ces expressions List en C, et vous écrivez en C en Lisp mais avec toute la puissance de macros et de calcul lambda si vous le souhaitez.
aoeu256

0

Que ce soit censé être pris au sérieux ou non, c'est le cas des plus grands projets C et C ++ sur lesquels j'ai travaillé.

Ce qui n'est pas vrai, c'est que les langages de script personnalisés ressemblent à Common Lisp. Les exemples positifs ressemblent à Scheme (parce que les concepteurs les plus intelligents ont intégré Guile, SpiderMonkey et Lua au lieu d'inventer leur propre langage.) Les exemples les plus dignes de DailyWTF étaient un langage semblable à Forth et un langage semblable à MUMPS.

Un autre exemple (je ne sais pas si cela compte comme Greenspunning, mais certainement un WTF) était un interpréteur XSLT utilisé pour les scripts à usage général. C'était plus semblable à Lisp car ils ont ajouté une boucle de rétroaction où la sortie serait transformée en XSLT une deuxième fois - alors maintenant vous avez effectivement des macros.
Le motif ici n'était cependant pas d'avoir accès aux fonctionnalités lispy mais de contourner les procédures de QA du code de l'entreprise (qui ajoutaient 3 semaines de latence à chaque correction de bogue. XML était considéré comme des "données" et exempté du processus.)


-1

Malheureusement non!

Bien qu'il soit préférable d'intégrer simplement un véritable interprète lisp (y) (javascript ou lua alos fait du bon travail), l'ajout d'un homebrew 4gl à un projet réduit la taille globale tout en augmentant la flexibilité.

Les projets qui "codent tout" ont un nombre de modules beaucoup plus important et deviennent encombrants et rigides.

En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.