Minha graduação era em Ciência Cognitiva e Inteligência Artificial. A partir disso, tive uma introdução de um curso ao Lisp. Eu pensei que a linguagem era interessante (como em "elegante"), mas realmente não pensei muito nisso até que me deparei com a Décima Regra de Greenspun muito mais tarde:
Qualquer programa C ou Fortran suficientemente complicado contém uma implementação lenta ad hoc, especificada informalmente, cheia de bugs e com erros, de metade do Common Lisp.
O argumento de Greenspun foi (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 cerca de 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.
Algum tempo depois, quando comecei a trabalhar em um projeto baseado na Web, testei vários idiomas. Incluí Lisp e Scheme na mistura. No final, selecionei uma implementação Scheme-- Chez Scheme . Fiquei muito feliz com os resultados.
O projeto baseado na Web é um "mecanismo de seleção" de alto desempenho . Usamos o Scheme de várias maneiras diferentes, desde o processamento de dados até a consulta de dados até a geração de páginas. Em muitos pontos, na verdade começamos com um idioma diferente, mas acabamos migrando para o Scheme por razões que descreverei brevemente abaixo.
Agora eu posso responder sua pergunta (pelo menos em parte).
Durante a audição, analisamos várias implementações de Lisp e Scheme. No lado do Lisp, vimos (acredito) Allegro CL, CMUCL, SBCL e LispWorks. No lado do esquema, vimos (acredito) Bigloo, Frango, Chez, Gambit. (A seleção de idioma foi feita há muito tempo; é por isso que estou um pouco enevoado. Posso desenterrar algumas notas, se for importante.)
Logo de cara estávamos procurando a) threads nativas eb) suporte para Linux, Mac e Windows. Essas duas condições combinadas derrubaram todo mundo, exceto (acho) Allegro e Chez - então, para continuar a avaliação, tivemos que afrouxar o requisito de multiencadeamento.
Montamos um conjunto de pequenos programas e os usamos para avaliação e teste. Isso revelou uma série de questões. Por exemplo: algumas implementações tinham defeitos que impediam a execução de alguns testes; algumas implementações não puderam compilar código em tempo de execução; algumas implementações não conseguiram integrar facilmente o código compilado em tempo de execução ao código pré-compilado; algumas implementações tinham coletores de lixo claramente melhores (ou claramente piores) que as outras; etc.
Para nossas necessidades, apenas as três implementações comerciais - Allegro, Chez e Lispworks - passaram nos nossos testes primários. Dos três, apenas Chez passou em todos os testes com cores voadoras. Na época, acho que o Lispworks não tinha threads nativos em nenhuma plataforma (acho que agora) e acho que o Allegro só tinha threads nativos em algumas plataformas. Além disso, a Allegro tinha uma taxa de licenciamento em tempo de execução "que nos chamava", da qual eu não gostava muito. Acredito que o Lispworks não tinha taxa de tempo de execução e o Chez tinha um arranjo simples (e muito razoável) (e só funcionava se você usasse o compilador em tempo de execução).
Tendo produzido partes de código um tanto significativas no Lisp e no Scheme, aqui estão alguns pontos de comparação e contraste:
Os ambientes Lisp são muito mais maduros. Você ganha muito mais dinheiro. (Dito isso, mais código também equivale a mais bugs.)
Os ambientes Lisp são muito mais difíceis de aprender. Você precisa de muito mais tempo para se tornar proficiente; O Lisp comum é uma linguagem enorme - e isso é antes de você chegar às bibliotecas que as implementações comerciais adicionam sobre ela. (Dito isso, o caso de sintaxe de Scheme é muito mais sutil e complicado do que qualquer coisa no Lisp.)
Os ambientes Lisp podem ser um pouco mais difíceis de produzir binários. Você precisa "agitar" sua imagem para remover bits desnecessários e, se você não exercitar seu programa corretamente durante esse processo, poderá acabar com erros de tempo de execução posteriormente. . Por outro lado, com o Chez, compilamos um arquivo de nível superior que inclui todos os outros arquivos necessários e pronto.
Eu disse antes que acabamos usando o Scheme em vários lugares que não pretendíamos originalmente. Por quê? Eu posso pensar em três razões em cima da minha cabeça.
Primeiro, aprendemos a confiar no Chez (e seu desenvolvedor, Cadence). Pedimos muito à ferramenta e ela foi entregue de forma consistente. Por exemplo, o Chez tem historicamente um número trivialmente pequeno de defeitos e seu gerenciador de memória tem sido muito, muito bom.
Segundo, aprendemos a amar o desempenho que recebemos do Chez. Estávamos usando algo que parecia uma linguagem de script - e estávamos obtendo velocidade do código nativo a partir dela. Para algumas coisas que não importavam - mas nunca doía, e às vezes ajudava muito.
Terceiro, aprendemos a amar a abstração que o Esquema poderia proporcionar. A propósito, não me refiro apenas a macros; Quero dizer coisas como fechamentos, lambdas, chamadas finais, etc. Quando você começa a pensar nesses termos, outras línguas parecem bastante limitadas em comparação.
Scheme é perfeito? Não; é uma troca. Primeiro, ele permite que desenvolvedores individuais sejam mais eficazes - mas é mais difícil para os desenvolvedores grunhir o código um do outro, porque as indicações que a maioria dos idiomas possui (por exemplo, para loops) estão ausentes no Scheme (por exemplo, existem milhões de maneiras de fazer um loop for). Segundo, há um grupo muito menor de desenvolvedores para conversar, contratar e emprestar, etc.
Para resumir, acho que diria: Lisp e Scheme oferecem alguns recursos que não estão amplamente disponíveis em nenhum outro lugar. Essa capacidade é uma troca, portanto é melhor que ela faça sentido no seu caso particular. No nosso caso, os fatores determinantes entre escolher o Lisp ou o Scheme tinham mais a ver com recursos muito fundamentais (suporte da plataforma, threads da plataforma, compilação em tempo de execução, licenciamento em tempo de execução) do que com os recursos de idioma ou biblioteca. Novamente, no nosso caso, isso também foi uma troca: com o Chez, obtivemos os principais recursos que queríamos, mas perdemos as extensas bibliotecas que os ambientes comerciais do Lisp tinham.
Além disso, apenas para reiterar: analisamos os vários Lisps e Schemes há muito tempo; todos eles evoluíram e melhoraram desde então.