Na última conferência ClojureConj, Glenn Vanderburg, diretor de engenharia da LivingSocial, apresentou uma amostra do seu trabalho em reescrever os algoritmos TeX's utilizando a linguagem Clojure. Nesse processo ele percebeu o quanto a programação mudou nesses últimos 30 anos.
Pequeno resumo sobre Tex
Primeiramente, a história pode ajudar a explicar a importância do TeX. O criador Donald Knuth lançou o TeX 1.0 em 1982, e segundo Glenn, mesmo após trinta e dois anos, isso ainda representa o estado da arte em composição tipográfica. Além disso, na época do lançamento, TeX foi um dos poucos exemplos de programa em que o código fonte era disponibilizado como fonte de aprendizado.
TeX é uma obra prima: ele é eficiente, portável e produz ótimos resultados e, mesmo após 30 anos, ainda é amplamente utilizado.
Glenn também faz uma curiosa observação sobre o autor Donald Knuth, pois ele decidiu iniciar o desenvolvimento do TeX após receber as primeiras páginas de revisão do seu grande trabalho "The Art of Computer Programming", onde avaliou o resultado visual como "lamentavelmente feio".
Então, Knuth começou a escrever um programa para tornar seu trabalho mais aceitável visualmente. Quando o TeX se tornou disponível, Tony Hoare, famoso pelo algoritmo Quicksort, encorajou Knuth a publicar o código fonte, pois isso poderia ser utilizado por estudantes.
Na época de 1982, a internet ainda engatinhava e não existiam muitos exemplos de código fonte disponíveis. Este objetivo deu a Knuth o impulso para iniciar o trabalho sobre literate programming (programação literária), e assim o código fonte do TeX foi publicado em 1986. E, segundo Glenn, se manteve como o "programa mais lido no mundo" até o Kernel do Linux ser lançado.
Por dentro do Tex
A arquitetura do TeX é um encadeamento de tarefas que processa texto, quebrando ele em diversos tipos de objetos, como páginas, parágrafos, linhas, palavras, etc.; e finalmente produzindo um arquivo DVI. Glenn também comenta que analisando o projeto é maravilhoso ver como a programação era "primitiva" trinta anos atrás.
O código fonte do TeX é recheado de exemplos que atualmente não são classificados como boas práticas de programação, como:
- variáveis globais;
- variáveis com nome utilizando apenas um caractere;
- uso de "goto";
- funções com centenas de linhas;
- muitas macros;
- código duplicado;
- reuso de variável local;
- suposição de single-thread por todo o código;
- mutabilidade;
Ler o código fonte é como visitar uma outra era [...] Desde o tempo que o livro foi publicado em 1986, isto representava um autêntico estilo de programação que, em muitos aspectos, já está obsoleto.
Este estilo é principalmente uma consequência das limitações de hardware que eram disponíveis na época - com limitado poder de processamento e disponibilidade de memória. E de acordo com Glenn, Knuth se esforçou muito para reduzir as chamadas de funções, pois isto na época poderia ser custoso. Isto fez com que o TeX fosse um código altamente integrado tão "amarrado que quase impossível extrair qualquer parte para ser utilizada isoladamente"
TeX é agressivamente otimizado através técnicas que possuem uma má reputação atualmente. Mas as razões para torcemos o nariz para essas técnicas são reflexos dos trinta anos da Lei de Moore e também a evolução de técnicas de implementação nas linguagens.
Reimplementando TeX utilizando Clojure: Cló
Na visão de Glenn, portanto, TeX não pode ser o melhor exemplo para servir de guia a um programador iniciante. Durante seu trabalho de reimplementação, Glenn pode observar o quanto a programação mudou e também pode demonstrar reais exemplos de como algoritmos mudam quando eles são traduzidos da forma procedural para o estilo funcional.
Ainda de acordo com Glenn, é muito difícil descobrir o que o código do TeX está fazendo, principalmente pela sua extrema otimização. Inicialmente, ele tentou manter seu projeto o mais próximo da implementação original do TeX.
Contudo, Text é estritamente single-thread, contrariando um dos objetivos da computação atual que é realizar o melhor uso do hardware multi-core disponível.
As abstrações do Clojure permitiram que Glenn implementasse o básico do encadeamento de tarefas, permitindo assim a troca da execução sequencial para execução paralela apenas trocando a macro Threading. A implementação de Cló foi inicialmente mais lenta do que a versão TeX, mas após a troca para execução paralela já se pode observar um benefício substancial.
Outro ponto interessante apontado por Glenn, é que ele sentiu obrigado a implementar os mesmos tipos de otimizações implementadas no TeX. Glenn então percebeu que isso iria prevenir o uso de boas abstrações que naturalmente existem no paradigma funcional, tornando as coisas mais complexas do que deveriam. Isso também levou Glenn a se questionar quanto da TeX API foi influenciada pelo paradigma da linguagem em que foi escrita, especificamente em relação a mutabilidade e o fato da aplicação ser single-thread.
A reflexão mais importante para Glenn, foi perceber como a programação evoluiu. Realizando um paralelo entre a programação atual e a programação de 1982, Glenn destaca:
- computadores eram extremamente lentos e com pouca memória;
- a maioria dos programadores nunca tinha visto um multiprocessador;
- não havia o padrão IEEE para aritmética de ponto flutuante;
- portabilidade significava suporte para quase 40 diferentes sistemas operacionais, cada um deles com diferentes estruturas de sistemas de arquivos, diferente I/O e alocação API e codificação
- não era possível carregar código de forma dinâmica;
- otimização por compiladores ainda eram projetos de pesquisa;
- não havia open source e free software, e você tinha que reimplementar funcionalidades básicas como por exemplo estruturas de dados;
- quando disponível, o controle de versão era rudimentar;
- teste automatizados eram desconhecidos;
Ao final, Glenn aponta que, embora temos espaço para evoluir muito na computação, também devemos apreciar as evoluções da área desde o lançamento do Tex.