Décima regra de Greenspun, todo grande projeto inclui um intérprete Lisp? [fechadas]

12

A décima regra de Greenspun (na verdade a única regra) afirma que:

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

Minha memória é que existem alguns trabalhos sobre o assunto, talvez para o projeto Quattro (planilha eletrônica) de Borland e possivelmente outros. O Google é inútil, talvez os termos de pesquisa certos não estejam surgindo. Estou procurando documentos ou artigos que apoiem essa reivindicação, se houver.

casualcoder
fonte
8
Você leu a explicação do significado da regra no artigo da Wikipedia? Duvido que houvesse um esforço sério para confirmar ou refutar a reivindicação, mas não foi realmente levada a sério .
precisa
3
O engraçado é que, embora a regra de Greenspun fosse apenas uma piada, eu realmente trabalhei em software de simulação que tinha um intérprete LISP incorporado. A configuração do software foi feita através de S-Expressions e é possível que você tenha escrito código LISP para fazer várias coisas na configuração.
Wkl
@YannisRizos - Literalmente, nenhum dos seus links afirma que a regra é uma piada. A Lei de Morris está enquadrada como tal, no entanto. Agora, figurativamente ....
casualcoder
2
@casualcoder "É irônico que, após minha morte, provavelmente seja a única coisa que alguém se lembra dos meus escritos". e o nome da regra sugere que ela foi escrita de uma maneira leve ...
yannis:
Não havia uma citação semelhante sobre Erlang e programas concorrentes?
Giorgio

Respostas:

15

A afirmação é hipérbole. Mas há sinais óbvios de inveja do Lisp em outras línguas. Veja o C # e como ele está se tornando mais funcional por natureza. Observe as várias estruturas de gerenciamento de processos de negócios, fluxo de trabalho e EAI que se esforçam para tornar possível programar o sistema sem alterar o programa.

Há um livro sobre idiomas específicos de domínio de Martin Fowler que fala sobre como fazer metaprogramação em linguagens orientadas a objetos. Portanto, há alguma verdade no hipérbole.

Paul Graham chamou o Lisp da linguagem mais poderosa, observando a lista dos primeiros que vieram com o Lisp . É fácil ver por que muitos idiomas são pálidos em comparação.

O caminho para contornar a décima regra é a programação poliglota. Perceber que uma linguagem / estrutura não é o martelo de ouro. Em vez de criar uma implementação ruim e ad hoc do Lisp, você pode apenas usar o Lisp.

Michael Brown
fonte
4
Poder e idade são independentes. É realmente muito irrelevante o quão bom ou ruim o LISP era no momento de sua criação, é importante como ele se compara aos idiomas hoje em dia. As primeiras são absolutamente sem importância.
DeadMG
2
@DeadMG, esses "primeiros" não são nada comparados às coisas que ainda não foram transportadas do Lisp para os outros idiomas.
SK-logic
1
@DeadMG, você está certo. Uma das coisas que as pessoas adoram em Ruby depois que começam a investigar é o aspecto da metaprogramação. O Lisp tem isso embutido. Os desenvolvedores de C # adoram o LINQ (por um bom motivo) e as implicações que a programação declarativa tem na simultaneidade. Lisp tem isso em espadas. À medida que os sistemas se tornam mais complexos, eles se tornam mais sobre nós reagindo a mensagens e menos sobre objetos. O Lisp começa por aí, a maioria das outras linguagens precisa adotá-lo ad hoc (daí a regra) ou através de uma estrutura (por exemplo, Biztalk, Tibco, etc).
Michael Brown
2
"em vez de criar uma implementação ad hoc ruim do Lisp, você pode simplesmente usar o Lisp", mas o corolário de Morris significa que você ainda está usando uma implementação ad hoc ruim;)
jk.
1
Nota de rodapé perfeita para essa entrada "a totalidade da cultura hacker é muitas vezes percebida como ha-ha-somente-séria pelos próprios hackers; para levar isso com muita leveza ou com seriedade, marca uma pessoa como uma pessoa de fora, uma wannabee ou em estágio larval . "
Michael Brown
10

A "décima regra" de Greenspun era uma piada sem graça. Quando for esticada o suficiente, se você cobrir "qualquer sistema de script ou configuração", obviamente a resposta a essa pergunta terá que ser "sim", pois a configuração é algo que qualquer programa não trivial exige em algum grau e o script é apenas um pouco menos comum à medida que você sobe na escala de complexidade.

Por outro lado, dê uma olhada no GOAL , uma variante Lisp inventada pela Naughty Dog para programação de jogos. Não parece muito com o Lisp "clássico". É um sistema altamente imperativo, com funcionalidade orientada a objetos, sem intérprete, suporte mínimo para coleta de lixo (dependendo das instalações de limpeza no nível de tempo de execução) e amplo suporte para montagem em linha.

Em outras palavras, quando tentaram usar o Lisp para um projeto suficientemente complexo, descobriram que, para fazer qualquer coisa útil, tinham que transformar o idioma em uma implementação informal ad-hoc especificada de metade do C ++! ;) (E eles finalmente tiveram que parar de usá-lo depois que o cara que criou o GOAL foi embora, porque ninguém conseguia entender seu código.)

Mason Wheeler
fonte
Acho que minha pergunta é sobre partes específicas de um sistema grande. Eventualmente, o sistema terá partes que são melhor codificadas em outro idioma devido aos processos ou técnicas de pensamento envolvidos no uso desse idioma, em vez da velocidade ou superioridade inerentes. A história do Sr. Lenaghan é um exemplo.
casualcoder
Na verdade, eles pararam de usar o GOAL porque foram comprados por empresas cuja base de código estava em C ++. Além disso, o GOAL foi bastante cego. Não assuma tutoriais on-line de menor denominador e palestras universitárias estão corretas :)
p_l
9

Curiosamente, uma resposta para essa pergunta está no Programmers SE .

Para citar a parte relevante:

O argumento de Greenspun era (em parte) que muitos programas complexos têm intérpretes embutidos. Em vez de transformar um intérprete em um idioma, ele sugeriu que faria mais sentido usar um idioma como o Lisp, que já possui um intérprete (ou compilador) embutido.

Na época, eu trabalhava em um aplicativo bastante grande que executava cálculos definidos pelo usuário usando um intérprete personalizado para um idioma personalizado. Decidi tentar reescrever seu núcleo no Lisp como um experimento em larga escala.

Demorou aproximadamente seis semanas. O código original era de ~ 100.000 linhas de Delphi (uma variante de Pascal). No Lisp isso foi reduzido para ~ 10.000 linhas. Ainda mais surpreendente, porém, foi o fato de o mecanismo Lisp ser 3-6 vezes mais rápido. E tenha em mente que este foi o trabalho de um neófito Lisp! Toda essa experiência foi muito reveladora para mim; pela primeira vez, vi a possibilidade de combinar desempenho e expressividade em um único idioma.
- Michael Lenaghan

Para esclarecer melhor essa parte, Michael respondeu a um comentário com:

Uau, isso deve ter sido um código Delphi realmente horrível, se de alguma forma conseguiu executar 3-6x mais lento que uma implementação Lisp! "Certo, vou contar isso como minha falha por não explicar melhor. A implementação Lisp foi capaz de transformar expressões de usuário em expressões Lisp - um processo trivialmente fácil - e depois compile as expressões Lisp no código nativo (com otimização total) Esse é o significado da Décima Regra de Greenspun.
- Michael Lenaghan

Dado que esta resposta é composta pela resposta de outra pessoa em outro lugar, é um wiki da comunidade.

codificador casual
fonte
2

A regra é uma piada, mas há um pouco de verdade nela. Qualquer sistema complexo conteria várias partes interpretadas (veja como o "padrão do intérprete" é popular entre aqueles que acreditam em todos esses padrões). Qualquer sistema complexo deve fornecer alguns meios de configuração, geralmente estruturados, frequentemente interpretados.

É provável que qualquer sistema complexo tenha várias passagens de geração de código e vários pré-processadores personalizados em seu processo de construção (pense mocno Qt ou tablegenno LLVM).

Muitos sistemas estão manipulando estruturas de dados complexas, semelhantes a árvores, usando um conjunto de (quase sempre) ferramentas para caminhar e transformar árvores mal projetadas, que se assemelham à funcionalidade de biblioteca do Common Lisp.

Tudo isso vem de graça com o Lisp e, na maioria dos casos, tudo o que ad hoc, não planejado, não pensado em implementações minuciosamente suficientes, seria totalmente inferior.

SK-logic
fonte
2

Qualquer sistema suficientemente complexo terá conceitos e requisitos específicos de domínio que são extremamente difíceis de expressar com as abstrações da linguagem em que você está trabalhando. Isso inadvertidamente força os programadores a criar abstrações específicas de domínio para aliviar o fardo de preencher a lacuna semântica entre a linguagem de programação e o domínio específico. Quando houver abstrações suficientes, você basicamente terá um intérprete de uma linguagem específica de domínio. Esta é uma parte inevitável do desenvolvimento de software.

davidk01
fonte
1

A regra provavelmente poderia ser mais precisa (e menos divertida), pois "todo sistema grande de software será necessário para implementar um comportamento dinâmico".

Isso pode ser feito de duas maneiras:

  1. Um grande arquivo de configuração complexo com dezenas de parâmetros e centenas de definições.

  2. Uma linguagem de script AD-HOC.

"sendmail" é provavelmente o exemplo canônico do tipo "1". Não consigo pensar em bons exemplos do tipo "2" que não envolvam a incorporação de uma linguagem de script "real" no Warcraft / LUA ou mesmo no Netscape / Javascript.

O problema é que, para alguns parâmetros, é rápido e simples fazê-lo com um arquivo de configuração, mas essa solução não é realmente escalável. No entanto, em nenhum momento será econômico despejar o arquivo de configuração em favor de uma abordagem de script ao adicionar uma ou duas opções ao arquivo de configuração. Portanto, o código que interpreta o arquivo de configuração acaba sendo um intérprete realmente mal escrito.

James Anderson
fonte
0

Isso pode ser verdade, como já foi dito, muitos programas requerem configuração e, portanto, contêm vários intérpretes do tipo lisp.

No entanto, a declaração também implica com um sorriso que tudo que você precisa para criar um programa é Lisp, e que todas as outras línguas são inferiores a ele.

Mas está errado, o Lisp pode ser expressivo, mas também é muito abstrato, tenta ocultar detalhes de uma plataforma e finge que nada além de listas existe no mundo dos computadores.

A realidade da programação de alto desempenho é que, às vezes, precisamos nos misturar com bits e bytes e fazer coisas específicas do SO, portanto, não é possível fazer tudo com apenas o Lisp, como a instrução implica.

É o contrário, não importa o quão complicado, inteligente ou sofisticado seja o idioma que você inventa, tudo o que acaba sendo é apenas outra maneira de escrever assembly.

vlsh
fonte
Parece relevante apenas para os ambientes ciganos mais antigos do final dos anos 50. Pessoalmente, achei as funções do Common Lisp para lidar com bits provavelmente uma das melhores (com a principal concorrência sendo Erlang). Matrizes, hashtables, estruturas são comuns.
p_l
É fácil escrever compiladores para o Lisp, pois você não precisa analisá-lo. Podem ser criadas funções Lisp e um compilador de macro (que é como o avaliador Lisp com apenas uma a meia página de código no início) que transforma essas expressões de lista em C, e você está escrevendo em C em Lisp, mas com todo o poder de macros e cálculo lambda, se desejar.
aoeu256 04/08/19
0

Quer deva ou não ser levado a sério, é o caso dos maiores projetos C e C ++ em que trabalhei.

O que não é verdade é que as linguagens de script personalizadas se assemelham ao Common Lisp. Os exemplos positivos se assemelham ao esquema (porque os designers mais inteligentes integraram Guile, SpiderMonkey e Lua em vez de inventar sua própria linguagem.) Os exemplos mais dignos de DailyWTF foram uma linguagem do tipo Forth e uma linguagem do tipo MUMPS.

Outro exemplo (sem saber se conta como Greenspunning, mas certamente um WTF) foi um intérprete XSLT usado para scripts de uso geral. Isso foi mais parecido com o Lisp, pois eles adicionavam um loop de feedback em que a saída seria transformada em XSLT uma segunda vez - então agora você tem macros efetivamente.
O motivo aqui não era obter acesso aos recursos lispy, mas evitar os procedimentos de controle de qualidade do código da empresa (que adicionavam 3 semanas de latência a cada correção de bug. XML era considerado "dados" e isento do processo).

finnw
fonte
-1

Infelizmente não!

Embora seja melhor incorporar apenas um intérprete lisp (y) real (javascript ou lua alos faz um bom trabalho), adicionar um homebrew 4gl a um projeto reduz o tamanho geral e aumenta a flexibilidade.

Projetos que "codificam tudo" têm contagens de módulo muito maiores e tornam-se difíceis de manejar e inflexíveis.

James Anderson
fonte