Python vs. PL/SQL vs. F#

Ultimamente tenho andado bastante interessado em programação, especialmente testar novas linguagens. E me surgiu um problema interessante: ver quantas páginas tem um PDF armazenado num BLOB no banco de dados. Dei uma pesquisada sobre as soluções existentes, sobre a especificação do formato PDF e resolvi que seria um bom exercício de programação implementar um leitor de PDF tosco só para descobrir o número de páginas. Muito mais interessante do que pegar algo pronto. E queria que fosse um parser. Extrair a informação usando só expressões regulares não vale :-)

A idéia era implementar em PL/SQL para aprender a linguagem. Afinal, PL/SQL tem o que se espera de uma linguagem de programação: funções, recursão, estruturas de dados, expressões regulares etc. Inclusive a passagem de parâmetros tem mais recursos do que existem em C++ e Java. Portanto, deve ser possível fazer o que eu quero (para os impacientes que não querem ler até o fim: possível é, mas deu um trabalho…).

Como garantia, decidi primeiro implementar em Python, porque aprender uma linguagem nova junto com o formato PDF ia ser complicado/frustrante demais. Depois era só traduzir o programa já testado. Aproveito e aprendo algumas novidades do Python 3 (mais especificamente, 3.1).

O programa em Python fluiu sem muitos problemas. A maior surpresa foi a forte separação entre array de bytes e strings na versão 3. Tive um certo trabalho com algumas conversões para que não desse erro de tipo (não sei se fiz da melhor forma), mas em geral eu gostei do tratamento de Unicode do Python 3.

Então, fui fazer a conversão para PL/SQL. A implementação foi uma sucessão de idas e vindas conforme eu ia descobrindo limitações da linguagem.

Existem objetos e records. Qual usar? Comecei com objetos mas não era possível declarar a classe localmente, tinha que ser global (como se alguém fosse querer armazenar um PdfTokenReader no banco…). Seguindo em frente, descobri que objetos não podem conter tabelas index-by (isto é, hashes/dictionaries/maps dependendo da sua linguagem preferida), porque esse tipo de tabela não pode ser persistida no banco (e objetos devem ser persistíveis). Vamos tentar records. Converto todos os membros para funções independentes. Até eu descobrir que não conseguia declarar records mutuamente recursivos. O problema é que não achei nenhuma sintaxe de forward-declaration de tipos. E a linguagem obriga a dar um nome a todos os tipos compostos (que nem Pascal e Delphi), não dá pra declarar uma variável com “table of…” diretamente. Comecei a ensaiar uma volta aos objetos porque parecia que eles tinham um mecanismo de referências, mas descobri que elas não funcionam como eu esperava (essa linguagem é cheia de limitações…), então continuei com records. Tive que simular ponteiros usando uma tabela indexada por inteiros, hehe.

Por último, me interessei pela linguagem F#, que virou linguagem de primeira linha no Visual Studio 2010. Ela é baseada em OCaml, mas achei bem melhor. É bem mais legível porque é baseada na indentação. Os operadores matemáticos funcionam pra qualquer tipo numérico. A orientação a objetos se integra muito bem com o framework .NET, sem precisar se contorcer com listas encadeadas simples se não quiser. E, claro, sem funções toscamente implementadas de forma recursiva que estouram a pilha quando a lista é muito grande. Scala é outra linguagem parecida (só que para a JVM), mas não sei por que eu tendi mais para F#. Edit: Aliás, sei sim. Scala é meio confusa, certas coisas acontecem implicitamente e tem que estudar mais a linguagem pra entender essas coisas.

A implementação em F# também foi tranqüila. Me baseei na versão em Python e um pouco na versão PL/SQL para ver como estruturar os tipos (como no Python dá pra armazenar qualquer tipo em qualquer variável, ficou meio bagunçado e tive que dar uma arrumada pra fazer a tradução). Só senti falta do comando break, que eu substituí pela primeira coisa que vinha na cabeça: ou função recursiva, ou uma flag booleana, ou (minha favorita) colocando todo o código dentro da condição do while (em vez de colocar no corpo). Também poderia ter usado exceções, caso eu precisasse de um break desesperadamente, mas não precisei chegar a tanto. Agora que me rendi ao .NET, talvez seja uma boa hora de aprender Boo. Se eu fosse projetar uma linguagem, ela seria muito parecida com Lua ou Boo (há muito tempo atrás eu imaginei como seria uma linguagem parecida com Python e com macros… descobri que não fui o único a ter essa idéia, hehe), mas eu ia preferir gerar código nativo. Se bem que ainda tenho muito a aprender de F#…

As implementações estão linkadas abaixo. Python e F# têm aproximadamente o mesmo tamanho, e PL/SQL tem mais ou menos o dobro de linhas…

Como contar o número de páginas num PDF com Python

Como contar o número de páginas num PDF com PL/SQL

Como contar o número de páginas num PDF com F#

Anúncios

Um pensamento sobre “Python vs. PL/SQL vs. F#

Deixe um comentário

Preencha os seus dados abaixo ou clique em um ícone para log in:

Logotipo do WordPress.com

Você está comentando utilizando sua conta WordPress.com. Sair / Alterar )

Imagem do Twitter

Você está comentando utilizando sua conta Twitter. Sair / Alterar )

Foto do Facebook

Você está comentando utilizando sua conta Facebook. Sair / Alterar )

Foto do Google+

Você está comentando utilizando sua conta Google+. Sair / Alterar )

Conectando a %s