39 pontos por xguru 2022-12-12 | 7 comentários | Compartilhar no WhatsApp

O que é uma "Little Language"?

  • "Linguagens pequenas" são linguagens criadas com o objetivo de resolver um problema específico
    → SQL, RegEx, Dhall,..
    → Também são chamadas de DSL

Por que linguagens pequenas são necessárias?

  • À medida que as aplicações ficaram muito mais complexas, o código-fonte também cresceu, mas ficou mais difícil de entender
  • O onboarding de novos funcionários é difícil, erros acontecem por falta de compreensão das dependências, e mudanças no código vão ficando cada vez mais difíceis de gerenciar
  • Nos últimos 10 anos, as bases de código cresceram de 100 a 500 vezes
    • O kernel Linux começou com 10 mil linhas em 1992, mas 20 anos depois chegou a 30 milhões de linhas
  • Esse código não cresceu apenas porque "há mais funcionalidades". Também porque a forma como construímos software mudou
    • Assim como na construção de uma pirâmide, para colocar a última pedra é preciso haver muito mais pedras embaixo

Superando a tendência

  • Será que é realmente necessário ter centenas de milhares de linhas de código para criar um OS moderno?
  • Alan Kay desafiou essa suposição no programa STEPS em 2006
  • Acreditamos que criar a 'linguagem' adequada ao problema a ser resolvido torna a solução mais fácil, e faz com que ela seja menor e mais fácil de entender

  • No STEPS, foi criada a linguagem Nile, que implementou funcionalidade semelhante à de um renderizador Cairo de 44.000 linhas com cerca de 300 linhas de código

Por que linguagens de alto nível não bastam?

  • Não daria para simplesmente criar uma linguagem de propósito geral em um nível mais alto?
  • Pessoalmente, acho que já chegamos a retornos decrescentes na expressividade das linguagens de propósito geral
  • Como seria uma linguagem ainda mais alta? Se usarmos Python como exemplo, ele já está em um nível tão alto que parece pseudocódigo
  • O problema das linguagens de propósito geral é que você precisa traduzir seu problema em um algoritmo e depois expressar esse algoritmo na linguagem escolhida
    • Em 1986, em Programming Pearls, Jon Bentley convidou Donald Knuth e Doug McIlroy para escreverem um programa que contasse a frequência das palavras; Don escreveu, em WEB, uma variante de Pascal, ao longo de 10 páginas com estruturas de dados complexas
    • Já Doug implementou isso usando uma pipeline Unix de 6 linhas com tr, sort, uniq, sort, sed e outros

Quanto menos, melhor: Less is More

  • Os comandos Unix acima mostram outra característica das linguagens pequenas.
    "Linguagens menos poderosas e runtimes mais poderosos"
  • Gonzalez fala dessa tendência em "The end of history for programming"
    • Empurrar problemas do espaço do usuário para problemas de runtime
      • Tornando os programas semelhantes a expressões matemáticas puras, enquanto a complexidade do runtime aumenta bastante
  • Expressões regulares e SQL não conseguem expressar nada além de busca de texto e trabalho com banco de dados, respectivamente
  • Isso contrasta com linguagens como C, que não têm runtime e nas quais tudo pode ser expresso
  • As linguagens pequenas ficam na outra ponta do espectro de poder de C
    • Não apenas abstraem a arquitetura do computador, mas também limitam os tipos de programas que podem ser expressos e, por design, são Turing-incomplete
    • Isso pode soar muito restritivo, mas abre uma nova dimensão de possibilidades para otimização e análise estática

Análise estática

  • Linguagens menos poderosas são mais fáceis de raciocinar e podem oferecer garantias mais fortes do que linguagens de propósito geral
  • Por exemplo, Dhall é uma "Total Functional Programming Language" para gerar arquivos de configuração
    • Isto é, para eliminar o risco de entrar em loop infinito, programas em Dhall "garantem" que "(1) não falham e (2) terminam em tempo finito"
    • (1) é alcançado evitando lançar exceptions. Comandos que podem falhar retornam um valor Optional como resultado (podendo haver ou não um valor)
    • (2) é alcançado ao não permitir definições recursivas
  • Em outras linguagens funcionais, recursão é a forma básica de implementar loops, mas Dhall precisa depender da função embutida fold
  • Não ter uma estrutura geral de loop significa que Dhall não é Turing-complete. Mas isso não é um problema, porque não é uma linguagem de propósito geral
  • Quando a linguagem é pequena, raciocinar sobre ela fica muito mais fácil
    • Por exemplo, é difícil verificar se um programa em Python não tem outros efeitos colaterais, mas em SQL basta verificar se a consulta começa com SELECT
  • No caso de Nile, a equipe do STEPS chegou a criar um depurador gráfico, que pode ser visto diretamente
    • Isso é possível porque Nile é uma linguagem pequena e fácil de analisar

A necessidade de velocidade

  • Linguagens de programação mais poderosas não apenas aumentam a chance de bugs, como também podem prejudicar o desempenho
  • Por exemplo, se um programa não for expresso como algoritmo, o runtime pode escolher o algoritmo por conta própria
    • Expressões lentas podem ser substituídas por rápidas (desde que se prove que produzem o mesmo resultado)
  • Por exemplo, uma consulta SQL não diz como ela deve ser executada
    • O mecanismo do banco de dados pode decidir livremente qual plano de execução é o mais adequado
      • Se deve usar índice, índice composto, ou fazer um scan completo da tabela do banco de dados
    • Motores de banco de dados modernos também coletam estatísticas sobre a distribuição dos valores em cada coluna, então conseguem escolher na hora o plano de consulta estatisticamente ótimo
    • Se a consulta viesse em forma de algoritmo, isso seria impossível
  • Um dos "ingredientes secretos" que tornaram a linguagem Nile tão concisa foi o "Jitblt", um compilador Just-in-Time para renderização gráfica
    • Em discussões entre as equipes do STEPS e do Cairo, descobriram que muito código do Cairo era usado para otimizar manualmente operações de composição de pixels
    • Em teoria, esse trabalho poderia ser delegado a um compilador
    • Dan Amelang, da equipe do Cairo, se voluntariou para implementar esse compilador: o Jitblt
    • Isso significou separar o trabalho de otimização do pipeline gráfico da descrição matemática pura do que deveria ser renderizado,
      o que permitiu que Nile rodasse tão rápido quanto o código original do Cairo otimizado manualmente

Small languages, Big Potential (Linguagens pequenas, grande potencial)

  • Então o que aconteceu com o STEPS? Será que eles criaram um OS executado por código curto o bastante para caber em uma camiseta?
  • O resultado final do STEPS foi o KSWorld
    • Um OS completo com editor de documentos e planilha integrados
    • 17.000 linhas de código
    • Um pouco longo demais para caber em uma camiseta, mas eu considero um sucesso
  • A criação do KSWorld mostra que "linguagens pequenas" têm um grande potencial
  • Mas ainda há muitas perguntas sem resposta
    • Como essas linguagens conversariam entre si?
    • Elas deveriam compilar para uma representação intermediária comum?
    • Ou runtimes diferentes deveriam coexistir em paralelo e se comunicar por protocolos padronizados (como pipelines Unix, TCP/IP etc.)?
    • Ou cada linguagem seria pequena o suficiente para poder ser reimplementada em várias linguagens hospedeiras?
    • Ou talvez a direção certa seja combinar tudo isso?
  • De qualquer forma, estou convencido de que precisamos pensar em outras maneiras de construir software
    • Talvez as "linguagens pequenas" façam parte dessa história
    • O importante é não continuar empilhando mais tijolos sobre tudo por tempo demais, e sim parar por tempo suficiente para imaginar algo melhor

7 comentários

 
ide127 2022-12-15

"
Acreditamos que criar uma 'linguagem' adequada ao problema que precisamos resolver torna a resolução mais fácil e faz com que a solução seja menor e mais fácil de entender.
"

Ao ler essa parte, o que senti foi que, no fim das contas, 'linguagem pequena' talvez tenha o mesmo significado de framework. Como no caso de JavaScript -> React, em que funções frequentemente usadas e padrões de design são impostos e acabam sendo transformados em uma espécie de gramática.

 
chicol 2022-12-14

Que tema interessante.

 
kunggom 2022-12-12

Pensando bem, descobri recentemente uma ferramenta de geração de DSL chamada MPS (Meta Programming System) feita pela JetBrains.
Pelo visto, isso é bem mais antigo do que eu imaginava. Fiquei interessado e queria dar uma olhada mais a fundo, mas acabei adiando por vários motivos. Se alguém aqui já usou isso, eu gostaria de ouvir algum relato de experiência.

 
uglyduck68 2022-12-12

Uau, obrigado

 
nicewook 2022-12-12

Li com gratidão.

 
roxie 2022-12-12

Lisp todo sorridente

 
xguru 2022-12-12

Achei uma história interessante e quis compartilhar a tradução.