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.
c
language-design
lisp
fortran
casualcoder
fonte
fonte
Respostas:
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.
fonte
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.)
fonte
Curiosamente, uma resposta para essa pergunta já está no Programmers SE .
Para citar a parte relevante:
Para esclarecer melhor essa parte, Michael respondeu a um comentário com:
Dado que esta resposta é composta pela resposta de outra pessoa em outro lugar, é um wiki da comunidade.
fonte
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
moc
no Qt outablegen
no 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.
fonte
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.
fonte
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:
Um grande arquivo de configuração complexo com dezenas de parâmetros e centenas de definições.
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.
fonte
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.
fonte
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).
fonte
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.
fonte