Y U NO SPEAK ESPERANTO?

3 agosto, 2011
Y U NO SPEAK ESPERANTO? — Kial vi ne parolas Esperanton?

Y U NO SPEAK ESPERANTO? — Kial vi ne parolas Esperanton?

Sonic 2 Prototype

28 junho, 2011

Muito tempo atrás (há uns 18 anos), numa terra distante (Santa Maria — RS, dá umas 4h de viagem a partir de Porto Alegre), fui na casa de um amigo de um amigo, que lá eles tinham a novidade: o jogo Sonic 2 de Mega Drive.

Eu já conhecia bem o Sonic 1 e já tinha ouvido falar um pouco do Sonic 2. Sabia que tinha uma raposa de dois rabos (o Tails) que acompanhava o Sonic e, se não houvesse um jogador para controlá-la, ela repetia os movimentos do Sonic. O Sonic pulava, e Tails pulava também, e assim por diante.

Quando fomos jogar, notei umas coisas curiosas. No início de cada fase, não aparecia o título dela (como Chemical Plant, etc.). Cada zona tinha somente 2 atos, e não havia chefe no final para derrotarmos. Depois da primeira fase (que eu não me lembro bem como era), vinha aquela que só tempos depois eu saberia que se chamava Chemical Plant. Me lembrava vagamente que antes de aparecer Chemical Plant, apareciam dois objetos vermelhos no meio da tela preta e que depois desciam um pouco e se posicionavam como parte do cenário quando o resto surgia. Achei tudo isso meio tosco. Também aconteceu uma vez de o Tails, controlado pelo computador obter um monitor de escudo para o Sonic. Isso não acontece no Sonic 2 oficial.

Tela de título do Sonic 2 Prototype/Beta

No final, joguei só essa vez. Se passamos da Chemical Plant, não lembro. Algum tempo depois (já era no mínimo 1994, porque eu já estava morando em outro condomínio), conheci o Sonic 2 oficial. Primeiro estranhei muito. O que era aquele menu na tela de título? O que eu conhecia não tinha menu! E agora as fases tinham nomes e chefes! (Sem tosquice desta vez.) Além do mais, o Sonic estava bem esquisito na tela de título. Preferia o simples sinal de positivo com o polegar, mas agora ele estava com uma cara meio “de mau” e fazendo um sinal que eu não sei o que é… deve estar pedindo carona. Bom, o Sonic 1 também fazia um sinal meio sem sentido, aquele “não” com o indicador que até hoje não sei por que o Sonic faz.

Tela de título do Sonic 2 final

Depois me acostumei e fiquei sabendo que aquele que era o Sonic 2 de verdade. E o que era então aquilo que eu tinha jogado? Sei lá… Lá pelos anos dois mil e pouco, pela internet, fiquei conhecendo umas ROMs de emulador do Sonic 2 Beta, e muitas teorias e discussões sobre fases incompletas, como a Hidden Palace, Dust Hill, Genocide City e Wood Zone. Fiquei até com vontade de postar nuns fóruns dizendo que eu tinha jogado uma versão preliminar do Sonic 2 semelhante àquela. Mas também, que graça ia ter atiçar a curiosidade dos outros se eu não tinha nenhuma informação útil para colaborar?

Acabei deixando de pesquisar sobre o assunto, mas um tempo depois, lá por dois mil e tantos, voltei a me interessar pelo assunto e descobri que tinham aparecido pela internet outros protótipos do Sonic 2! Entre elas, uma chamada de Early Prototype e vários betas. Baixei todas e pelos detalhes que eu lembrava, achei uma que fechava (que agora eu estou achando que era o próprio beta disponibilizado originalmente, o do Simon Wai… acho que me perdi nesse monte de versões). As outras, ou tinham chefes, ou já tinham títulos antes de cada ato, ou outras diferenças. Foi bem legal finalmente encontrar e relembrar aquele protótipo que eu conheci tanto tempo atrás (não foi sonho, então!)! E finalmente os “sonicólogos” do mundo todo conheceram essa versão também.

Resolvi escrever este post porque acabei encontrando várias ROMs de protótipos do Sonic que eu nem tinha jogado, entre Prototypes e Betas. Nem me lembro de onde baixei cada uma. Imagino que tenha sido do hidden-palace.org ou do powersonic.com.br

Kaj vi opinias la portugalan komplika?

5 abril, 2011

Isto é uma tradução deste artigo: E você acha o português complicado? (Ĉi tio estas traduko el la portugala de la supre menciita artikolo)

Intima rigardo de lingvo

Paulo Rónai komentas la malfacilaĵojn de sia patra lingvo, la hungara, kiun oni konsideras kiel unu el la plej kompleksaj lingvoj el Eŭropo. “Pasis multaj jaroj ĝis kiam mi rimarkis la komplikaĵojn de la mekanismo de la hungara lingvo. Laŭ mi estis lernanta aliajn lingvojn, mi estis miranta pri la mia”, li konfesas. Ĉe sia unua renkonto, la fremdulo ĝojiĝas pri la ŝajna simpleco de la lingvo: la ortografio estas preskaŭ fonetika (por unu sono, ĉiam po unu skribmaniero). Krom tio, la vortoj ne havas genrojn (vira, ina aŭ neŭtra), kaj tio igas ĉiujn adjektivojn unu-formaj, ĉar ne ekzistas la neceso akordi. La verbaj tempoj estas preskaŭ mizeraj: nur ekzistas unu estinteco kaj unu estanteco, plus kelkaj kunmetitaj verbaj tempoj. Ĉesas tie, tamen, tiu simpleco trompiga. Ekzistas feroca deklinacia sistemo, kun preskaŭ la duoblo da deklinacioj ol Latino. Vidu la hungaran inferon, per la propraj vortoj de Rónai:

“La malekzisto de verbaj tempoj estas kompensata, kaj fortike, per la abundo de aliaj specoj de rimedoj. La hungara, same kiel la rusa, malmulte zorgas pri la interrilato inter la tempoj de unu frazo, sed estas zorgema marki klare la aspekto de ĉiu ago aparte. Ĝi ne sentas diferencon inter “mi skribis / estis skribanta / estas skribinta / estis skribinta” (en la portulaga aperas 2 formoj de “estis skribinta”). Tiuj agoj miksiĝas (laŭ ĝia vidpunkto) sub malklara pasinta “írtam”, sed ĝi volas scii la cirkonstancojn per kiu la ago estis realigata: ĉu la persono skribis sub diktado aŭ kopiante; ĉu sur aparta folio aŭ en libro; ĉu kun la intenco konservi la skribaĵon; ĉu oni plenigis la folion aŭ ne; ĉu tio, kion oni skribis, estis esenca aŭ flanka afero; ĉu oni prenis la informojn el unu aŭ pluraj fontoj… kaj, laŭ la ĉefa aspekto, ĝi uzus la pasintecon “írtam” kun malsamaj prefiksoj (leírtam, átírtam, beírtam, felírtam, teleírtam, odaírtam, kiírtam, összeírtam…) aŭ, kiel ni dirus, uzus alian kunmetitan verbon. La riĉeco de nuancoj de tiuj prefiksoj estas mirinda: unu el ili (ki-), kune kun la sama írtam, indikos ke la skribinto donis ĉion kion ĝi povis kaj estas elĉerpita; alia (el-) montras ke la afero estos traktata fare de alia aŭtoro ankaŭ; alia (agyon-) montras ke ĝi mortis pro tiom da skribado.

La hungaraj adoleskantoj ne scias kio estas aspketoj de verbo, sed ili manipulas tion kun instinkta memfido; dum la fremduloj “tute perdas sian Latinon” sen akiri la hungaran de la aliaj. Eĉ tiom ke la samaj prefiksoj asociataj kun aliaj verboj indikas aspektojn tute diversaj: tiel, se fel-, sekvata de “skribi” signifas ke oni skribas por konservi la skribaĵon; de “legi”, ĝi signifas ke oni laŭte legas; de “vivi”, ke oni manĝas ĉion, kion oni havas; de “rigardi”, ke oni rigardas de sube ĝis supren; de “plori”, ke oni ekploregas; de “citi”, ke oni vokas mortulon; de “kovri”, ke oni malkovras; de “doni”, ke oni sendas ion per poŝto, aŭ ke oni denuncas iun, aŭ ke oni forlasas matĉon; de “preni”, signifas ke oni prenas ion de sur la planko, aŭ ke oni dungas iun, aŭ ke oni rigardas observon kiel gravan; kaj, finfine, kelkfoje ĝi esprimas nenion el tio, nur la finon de la ago.

Se tiu esprim-riĉeco pri la aspektoj estas surpriziga por la parolantoj de latinidaj lingvoj, ne ĝenos germanianon aŭ rusianon, kiuj konas en sia propra lingva sperto la uzadon de tiaj prefiksoj, perversaj fonemetoj kiuj, eĉ se ili ne vere estas vortoj, ofte disiĝas de la verboj, kelkfoje por tute anstataŭi ilin; sed ĝermanoj kaj slavoj perdas sian memfidon kiam ili ekkonas la ekziston de konjugacioj “transitiva” kaj alia “netransitiva” (neperfektaj nomoj, ĉar la duan oni uzas ankaŭ transitive, sed kun nedifinita objekto), kaj perpleksiĝas kiam ili sciiĝas ke la verbaj formoj povas speguli la personon ne nur de la subjekto, sed ankaŭ de la rekta objekto — kaj tio faras ke en la frazoj “Mi amas virinon”, “Mi amas blondajn virinojn” kaj “Mi amas vin”, oni uzos 3 malsamajn formojn de la verbo “szeretni” (ami): szeretek, szeretem, szeretlek.”

RÓNAI, PAULO. Kiel mi lernis la portugalan, kaj aliaj aventuroj, 2-a eldono reviziita. Rio de Janeiro, Artenova, 1975.

É de família…

27 dezembro, 2010

Pelo jeito é mal de família… Todo mundo troca nomes e mistura palavras na minha família. Abaixo uns exemplos (adaptados) das coisas que ouvi neste natal e algumas coisas mais antigas.

  • Oscar Nei-máier (Oscar Niemeyer)
  • Aquelas arvorezinhas… Banzai… Ah, não… É bonsai!
  • Aquela banda… A Guinness and Roses (Guns and Roses)
  • Em Porto Alegre tem aquele… o Trensúber (Trensurb)
  • Tu come sempre essa comida rabuscada? (rebuscada) Pra piorar, eu ouvi rabiscada
  • Nem li aquele livro Mary e eu… Como é que é? Marley e eu!
  • E aquele político, o Michel Tâmer (Michel Temer)
  • Eu vi no programa do Oscar Mesquita (Otávio Mesquita)
  • Quer que eu chame um táquis? (táxi)
  • Eu tava ouvindo a rádio Pópi Rópi (Pop Rock)
  • Vou ver uma sarge na internet. Como é que é? Sarge? Charge? Ah, vou ver no Youtube mesmo!
  • No tapete do teu quarto está escrito Rok enrou (essa foi por escrito)
  • “Pedra” em inglês… Deve ser “rolling”, por causa dos “Rolling Stones” (bom, tinha 50% de chances de acertar qual palavra era “pedra”… e errou)

Playlist

17 novembro, 2010

Tem uma promoção pra concorrer a um iPod. É só criar e divulgar sua playlist. Assim divulgo músicas que gosto e concorro ao mesmo tempo! O link da minha playlist é http://letras.ms/7anos/10924 Escutem!

Por que escrever “certo”?

30 outubro, 2010

Surgiu pela milésima vez o assunto “Por que escrever certo? A língua não evolui?” num fórum e a minha resposta ficou absurdamente longa. Resolvi escrever aqui e deixar lá so o link. E aqui ainda posso colocar uns subtítulos para separar melhor as idéias. Pelo que conheço dos meus poucos leitores regulares, eles já sabem de tudo isso (tem gente até mais viciada em usar o idioma corretamente do que eu), então não é pra eles que escrevo.

Durabilidade e alcance da informação

Hoje historiadores se valem muito de livros e manuscritos, mas talvez no futuro a internet seja uma fonte de pesquisa histórica. Não seria legal se o que você escreveu pudesse ser lido daqui a 200 anos por um pesquisador tibetano interessado em saber as opiniões dos internautas do Brasil em 2010? Ele terá bem menos trabalho se você escrever direito.

Para nós, “iço” é entendível, mas coitado do estrangeiro (no presente ou no futuro), que vai ir no dicionário, pensando que é uma palavra desconhecida e não vai encontrar. Ele provavelmente deduzirá o significado algum tempo depois, mas terá mais trabalho tudo porque a pessoa que escreveu não quis fazer o mínimo esforço de pôr em prática o que todo mundo aprende no primeiro ano da escola: escreve-se “isso”, não “iço”. A pronúncia é a mesma, mas a padronização traz benefícios.

Facilidade e rapidez de leitura

Até para um brasileiro, encontrar as palavras escritas sempre da forma correta facilita a leitura, pois o cérebro reconhece mais rápido as palavras. Se eu encontro “esta” no lugar de “está” (ou vice-versa), muitas vezes eu tenho que reler a frase pra ver se fui eu que li errado (posso ter pulado uma palavra ou uma pontuação) ou se o texto está errado mesmo.

Não-humanos

É sempre engraçado e irritante quando vejo um desses analfabetos colocar num tradutor automático uma frase como: “Ela esta feliz” (me faltou uma frase mais realista), e pega a tradução “She this happy” como se fosse um inglês perfeito e sai por aí postando em legenda de foto no Orkut, postando em ingrêis nos fóruns gringos, etc. Se ao menos se desse o trabalho de acentuar corretamente o “está”, teria muito mais chance da tradução sair correta (os tradutores automáticos já são ruins, imagina se a gente fica atrapalhando com grafias fora do padrão).

Outros casos de não-humanos seriam leitores de tela para pessoas com algum tipo de deficiência visual (não quero nem imaginar como um leitor leria algo em miguxês… droga, já imaginei) e, é claro alienígenas.

Concessões e gentilezas

A primeira vez que eu vi a abreviação “vo6″ eu não entendi porra nenhuma. É que aqui na minha região, a gente fala “vocês”, não “voceis”. Não seria legal se combinássemos de escrever todos do mesmo jeito? Bom, nesse caso já está combinado de todos escreverem “vocês”.

Por acaso pode parecer que eu levo uma certa vantagem porque a forma escrita “vocês” é mais parecida com o jeito que eu falo, mas em outros casos não é. Eu por exemplo, se fosse escrever como eu falo, escreveria “trabisseiro”, mas eu faço uma concessão (se quiser, pode considerar como uma “gentileza”) ao resto dos falantes do português e escrevo como foi padronizado: “travesseiro”, para facilitar o entendimento de todos.

União

Nossa língua, apesar de estar entre as mais faladas do mundo, não é tão poderosa. Se quisermos nos comunicar com o resto do mundo, precisamos aprender inglês, espanhol, francês, etc. Se ainda tivéssemos que aprender (ou ensinar aos estrangeiros) português de Portugal, português gaúcho, português nordestino, português angolano, seria pior ainda. A língua ensinada nas escolas, que é um pouco diferente do que falamos no dia-a-dia, é um jeito de nos manter mais unidos.

Línguas como o alemão e o italiano têm vários dialetos, mesmo que os países sejam menores que o Brasil. Mas os viajantes estrangeiros podem ficar sossegados que existe o alemão padrão e o italiano padrão que podem ser entendidos por toda a extensão de seu país correspondente (assim ouvi falar. Não sei alemão nem italiano).

Elitismo

Após defender o uso “correto” (coloco entre aspas porque na verdade acho que a melhor palavra seria padronizado) da língua, pode parecer que sou do time de pessoas que acham que simplificar a ortografia tiraria a “beleza”, a “riqueza”, o “valor”, e/ou a “história” da língua e por isso deveríamos fazer como o francês e o inglês que mantêm suas complicadas ortografias. Não concordo com eles. Na verdade, o que eu acho que eles querem dizer é que uma ortografia complexa serve pra distinguir os eruditos da plebe. Mas isso não é problema, porque a natureza se encarregará de criar idiotas suficientes para escrever errado em qualquer ortografia. Defendo, sim, que deve haver evolução, mas tem que ser algo razoavelmente organizado.

Evolução

Bom, acima expliquei as vantagens da padronização. Sei que há várias evoluções e simplificações possíveis na nossa ortografia. A minha reclamação é que as grafias miguxas, internéticas e assemelhadas não são uma evolução coerente da língua em direção a uma grafia simplificada. São uma bagunça. Se fosse uma coisa coerente, até eu apoiaria. Eu também gosto de testar novas grafias, como escrever “mause” (fica meio feio, né?) e “extender” (de onde tiraram a idéia de padronizar o “estender” com S e “extensão” com X?), mas sempre em doses leves, não em todas as palavras do texto.

Mas é muito difícil conseguir consenso sobre uma nova ortografia e aplicá-la globalmente a um mundo de livros, revistas, sites e programas de computador (corretores, tradutores e qualquer coisa que venham a inventar). Mesmo assim, fizeram uma reforma ortográfica no Brasil ano passado…

O artigo abaixo, aparentemente publicado antes da reforma de 2009, explica o tortuoso (mas interessante) caminho percorrido pela nossa língua até chegar ao estado atual. Na minha opinião, houve mudanças demais neste século passado. A mudança inicial salvou o português de ser uma bagunça como o inglês no quesito ortografia, mas as outras alteraram minúcias que serviram mais pra confundir a cabeça do povo, que mal consegue manter uma ortografia na cabeça.

http://revistalingua.uol.com.br/textos.asp?codigo=11184

Comparação de desempenho (2)

27 outubro, 2010

Este post não tem introdução nem desenvolvimento: já começa com as conclusões.

Link para os testes originais


P1: Tempo para analisar 261 PDFs em 1 único processo P2: Tempo para analisar 261 PDFs abrindo seqüencialmente 1 processo para cada P2÷P1
C++ 1,65s (64 bits) 3,53s (64 bits) 2,14
D 2,75s (32 bits) 5,71s (32 bits) 2,08
F# 3,35s
(64 bits / .NET 4.0)
71,54s
(64 bits / .NET 4.0)
21,36
Java 1,91s (64 bits) 40,93s (64 bits) 21,43

 

Boo 10,56s
(32 bits / .NET 3.5)
28,07s
(32 bits / .NET 3.5)
2,66
C++ debug 8,87s (64 bits) 11,20s (64 bits) 1,26
Lua 10,10s (64 bits) 12,38s (64 bits) 1,23
Python 9,28s (64 bits) 22,73s (64 bits) 2,45
Ruby 10,00s (32 bits) 23,49s (32 bits) 2,35

 

Resultados

Dividi os resultados em 2 categorias: a primeira, das linguagens que conseguiram tempos menores que 5 segundos; a segunda das outras. Como curiosidade, incluí uma versão de C++ na versão “debug” (sem otimizações), mostrando que o desempenho acaba ficando na segunda categoria. Então, se você sempre roda seus programas em modo debug, você não está usando todo o potencial da linguagem…

Destaquei em verde os dois melhores tempos em cada categoria. Na segunda coluna, destaquei também em vermelho piores tempos de cada categoria, porque as diferenças foram enormes e merecem atenção. Não dei o mesmo destaque na primeira coluna porque as diferenças não eram tão significativas.

Embora seja fácil analisar os resultados pelas cores, reenfatizo aqui pontos interessantes: como a inicialização do processo é absurdamente custosa em Java e F# (nas versões 64 bits), bastante custosa em Boo, Python e Ruby e pouco custosa em C++, D e Lua. Destaque para Lua, que é uma linguagem dinâmica (e muitas vezes executada a partir do código fonte) como Python e Ruby, mas tem uma inicialização rápida com C++ e D. Ruby 1.8 tinha a fama de ser muito lento (não testei). Já a versão 1.9 melhorou e compete diretamente com Python, embora não o alcance ainda.

Desta vez, não incluí o uso de memória, mas coloquei a proporção entre os tempos da primeira e da segunda colunas.

Melhorias no código fonte

O código fonte foi melhorado usando um profiler. A mudança principal está na função PdfXref::add_obj, que agora não chama read_number (removida), que era a função que mais degradava o desempenho. Quase todas as diferenças de desempenho entre os testes anteriores e estes se devem a esta melhora em add_obj. A única exceção é explicada a seguir.

Na implementação em D, houve uma correção que muda a classificação final. A variável pdfFile é agora passada e armazenada em PdfTokenReader por ponteiro, como deveria ser. Isso corrige o problema que fazia o scope(exit) ser necessário (embora haja em D um certo problema em ter structs com destrutores dentro de classes, no meu caso a culpa era minha mesmo). O resultado prático dessa mudança é que agora a implementação em D é consistentemente mais rápida que a implementação em F#.

Os códigos estão nas seguintes páginas. Mantive as implementações originais em C++, D, Java, Python e F# e adicionei as novas.

Código fonte em Java

Código fonte em C++

Código fonte em D

Código fonte em F#

Código fonte em Python

Código fonte em Lua

Código fonte em Boo

Código fonte em Ruby

32 ou 64 bits?

Para simplificar a tabela, não incluí versões 32 bits onde eu tinha disponível o compilador/interpretador de 64 bits. Mas alguns testes de 32 bits eu fiz, e pude concluir que as proporções continuam as mesmas para todas as linguagens: uma pequena mas consistente vantagem de desempenho na versão 64 bits, com a exceção da inicialização do Java e do F# onde há um grande impacto na performance em 64 bits. Portanto, os resultados do teste anterior ainda podem ser usados como referência.

Outras condições do teste

Outras variáveis não se alteraram. Usei a mesma máquina, exatamente os mesmo 261 arquivos de entrada e repeti o teste algumas vezes para obter o menor tempo atingível. Repeti cada teste 3 vezes no mínimo e repeti algumas vezes mais enquanto estivesse conseguindo obter tempos menores (isso foi diferente no teste anterior, onde repeti sempre 3 vezes cada execução).

Implementações usadas

Foram usadas as mesmas implementações de compiladores e interpretadores dos testes anteriores.

Nas linguagens a seguir, que rodam a partir dos fontes, não foi usada pré-compilação mesmo quando ela estava disponível (.pyc, luac, etc.):

Python 3.1.2, distribuição oficial para Windows, 64 bits

Ruby 1.9.2-p0, distribuição RubyInstaller para Windows, 32 bits.

Lua 5.1.4, inicialmente usei a distribuição LuaForWindows v5.1.4-40 (32 bits), mas como era bem fácil de fazer, substituí os executáveis e DLLs por versões de 64 bits a partir do projeto LuaBinaries.

A última linguagem adicionada foi Boo 0.9.3, usando o SharpDevelop 3.2.0 (build 5777). Ela não roda a partir do fonte, como Python, mas sim compila para o .NET Framework. Infelizmente, ainda não é compatível com o .NET 4.0, então não dá pra fazer uma comparação direta com F#. O desempenho ficou comparável ao das outras linguagens dinâmicas, apesar de Boo usar tipos estáticos.

Fim

Pronto, terminei de fazer todos os testes que eu queria fazer, finalmente. Foi interessante perceber a diferença na qualidade de documentação, ferramentas e comunidade das linguagens consolidadas (C++, Java, Python, Ruby, Lua) e das em desenvolvimento (D2 e Boo, deixando F# numa categoria intermediária). Por exemplo, uma linguagem consolidada que não muda muito dá a impressão de ser “estável”: ela não sofre atualizações tão freqüentes mas todo mundo usa e fala sobre ela; enquanto que uma linguagem aspirante sem um anúncio de nova versão no grupo de discussão oficial parece “abandonada”. Uma linguagem consolidada que passa por atualizações, parece “ter futuro”, ser “moderna”. Já no caso de uma aspirante, muitas novas funcionalidades podem por descuido não ter sua documentação atualizada (ou o contrário: existe documentação sobre um recurso que não está completo) e isso faz a linguagem parecer “instável”, “problemática”.

Antes de fazer o teste eu não gostava muito de Ruby, por parecer um “Python mais complicado”, como a confusão na definição de procs e lambdas e na precedência de operadores (ver este exemplo:

irb(main):058:0> true or false and false
=> false
irb(main):059:0> true || false && false
=> true

) mas usando deu pra perceber que é uma linguagem muito prática, que procura tornar fáceis as tarefas comuns (exemplos: attr_reader, attr_accessor, case/when, regexps, interpolação de strings, uso do símbolo @, ranges, etc.), ainda que as regras da linguagem sejam um pouco mais complicadas do que o necessário. Ah, e espero que a página da linguagem em português se atualize, pois está bem atrás da versão em inglês (compare: http://www.ruby-lang.org/pt/ e http://www.ruby-lang.org/en/)

Misinterpretações

14 outubro, 2010

Eu acho que o prefixo mis é muito útil e poderia ser usado em português. Por exemplo, eu frequentemente (e aí, uso trema ou não uso?) misinterpreto algumas frases com resultados engraçados. Tanto é que desde que eu criei este blog existe a categoria “Diálogos bizarros”, porque eu sabia que volta e meia eu ia ter algo pra postar sobre isso.

Caso 1:

— Olha, são marrecos!

E eu (em pensamento):

— São Marrecos? Que santo é esse?

 

Caso 2:

— Imagina se eu tivesse nascido 100 anos antes!

E eu (em pensamento):

— Se tivesse nascido sem ânus?

Mas quando ouvi a palavra “antes”, fiz reparse na frase e entendi.  Ainda bem que ele não disse “100 anos atrás”, hehehehe :-D

How to tell…

20 setembro, 2010

How to tell if your cat is planning to kill youÉ, é importantíssimo saber se teu gato está planejando te matar. E não te esquece de conferir se o teu cachorro é retartado.

Premiação

20 setembro, 2010

Tendo os resultados do teste de desempenho, escolhi dar alguns “prêmios” para as linguagens.

Prêmio Rapidez com consistência

C++

Prêmio Lentidão com consistência

Python. É lento, mas pelo menos inicializa num tempo razoável. Além disso, é a única linguagem com tipagem dinâmica dos testes, então não dá bem pra comparar.

Prêmio Lentidão de inicialização

As linguagens com máquinas virtuais e JIT: Java e F#, principalmente na versão 64 bits. Perderam até pro Python.

Acho melhor tirarem aqueles loops vazios até um milhão que puseram lá :-P

Prêmio Concisão

Python e F#. Apesar de eu não ter me preocupado com coisas como linhas em branco e comentários, essas duas linguagens tiveram os códigos mais concisos (quase empatadas). As duas usam da indentação para delimitar blocos.

Prêmio Verbosidade

PL/SQL. A implementação em PL/SQL não estava nos testes porque ela funciona dentro do banco de dados, coisa completamente diferente das outras linguagens. Mas ela merece o prêmio por ultrapassar a marca de 800 linhas para fazer o que Python e F# fazem com 500.

Java, D e C++ ficaram com resultados muito mais parecidos do que eu imaginava. Algumas implementações têm algumas checagens a mais e outras a menos no código, mas fora isso não tem muita diferença.

Prêmio Imaturidade

D versão 2. Esbarrei em 2 bugs (um era que to!double("0") falhava e outro é que o executável com otimização não fechava os arquivos sozinho*, ao contrário do que a documentação afirmava). O bug do to!double foi corrigido quando atualizei da versão 2.048 para 2.049, mas o fechamento dos arquivos teve que continuar manual (ainda bem que D tem o recurso scope(exit), muito mais legal que finally. É na verdade genial). Nessas horas eu penso que deveria ter usado D 1, que é mais estável (o D 2 ainda recebia modificações radicais até recentemente, mas está começando a estabilizar). Não sei se D não foi injustiçado por eu ter usado a versão bleeding-edge, mas praticamente todas as [implementações de ] linguagens que eu usei são bem recentes.

*Depois descobri que eu estava criando sem querer cópias do objeto File, porque ele é uma struct e não uma class. Corrigindo isso o problema sumiu e o desempenho melhorou.

Prêmio Mas eu tenho que fazer isso na mão?

1º lugar:

C++, por:
- ter que implementar uma função hash para fazer uma chave composta num unordered_map.
- por seus copy constructors, move constructors, fucking constructors, smart pointers, dumb pointers e references.

E para a STL do C++, por:
- ter que comparar com string::npos ou container.end() para saber se um elemento foi encontrado depois de uma busca;
- ser uma uma complicação aplicar a função hash personalizada ao unordered_map (struct com operator() const);
- find num map retornar um pair, sendo que eu só estou interessado no segundo elemento.

Sorte que por causa das novidades do C++1x eu não precisei usar um sstream (ou o inseguro sprintf) para converter números para strings…

2º lugar: Java, também por ter que implementar uma função hash para fazer uma chave composta num HashMap. Eu poderia ter concatenado os campos numa string e ter pegado o hash dessa string (como eu fiz em PL/SQL), mas resolvi fuçar na implementação do tipo Long e peguei a função hash de lá. Dei uma alterada pra fazer hash de 2 longs, não sei se prestou. Depois fiz algo parecido no C++.

Prêmio Viva, não preciso implementar funções hash!

Por conseguinte, pode-se dizer que Python, F# e D ganharam o prêmio “Viva, não preciso implementar funções hash!”

Prêmio Não tá faltando nada, não?

F#, por não precisar (nem permitir) usar return no final das funções.

— Pra retornar um 0 do main é só deixar o 0 solto ali no fim?

— É.

— Puxa!

Prêmio Union

F#. Definir o tipo PdfObject foi muito fácil em F#, disparado.

Prêmio Metaprogramação

D. Defini todas as subclasses de PdfObject usando geração de código a partir de strings. Demorou um pouco até eu conseguir fazer algo que não desse uma mensagem de erro bizarra, mas foi legal.

Ctrl+C, Ctrl+V é para fracos. Em D, o compilador faz isso por você.

Prêmio Diferente de todo o resto

F#. Eu já tinha lido um pouco sobre a família dessa linguagem (ML), mas foi a primeira vez que programei numa linguagem dessas. Refrescante, mesmo que eu tenha usado poucas abordagens novas. O legal é F# não tem a distinção de statement e expression (tudo é expressão). Longe de ser característica exclusiva de F#, mas acabou que de todas as linguagens que testei, ela foi a única com essa característica.

Prêmio {Curly braces}, que tédio

D, Java, C++. Depois de tanto programar com {chaves}, dá um certo tédio ver mais uma linguagem nesse estilo. Não que eu prefira estudar coisas bizarras como APL, Lisp ou Forth, nem morto. Mas é legal de vez em quando escrever um then ou apenas dois-pontos depois da condição de um if.

Prêmio Menor linha de comando

Python. Não precisa passar nada de especial na linha de comando pra rodar. As otimizações das opções -O e -OO são o mesmo que nada, praticamente.

Menção especial ao Java também, por não precisar de nenhuma opção de otimização e ainda assim ter bom desempenho (sem contar a inicialização, claro).

Prêmio Pipes e foreach, viva!

PowerShell, claro. Facilitou muito os testes. Se não fosse o PowerShell, teria escrito em Python, seria interessante também.

Prêmio Pseudocódigo

Python, que é praticamente pseudocódigo que executa (junto com Lua). Linguagens sempre acabam tendo esquisitices, Python e Lua se destacam por não se renderem à criação de $sintaxes <| bizarras. D e Java também têm potencial de se parecerem com pseudocódigo (só que com {chaves}), mas não acertaram exatamente no alvo, falta ou sobra algo…

Prêmio REPL

Python, por permitir testar trechos de código num ambiente interativo (Read-Eval-Print Loop) e permitir listar membros, ver os tipos das variáveis e sua documentação.

F#, porque também tem um REPL (o F# Interactive) e ajudou muito. Mas para alguns detalhes era mais prático usar o IntelliSense do Visual Studio do que o F# Interactive.

Prêmio Complicação desgraçada fiadapu

C++. Vejamos um exemplo:

Em Python, uma estrutura do tipo hash table, se chama dict. Esse é o nome do tipo, e existe a sintaxe com {} para construir um diretamente (embora seja possível construir com dict também).

Em Java, um tipo equivalente seria:

HashMap<String, PdfObject>

É necessário declarar o tipo dos elementos e não há sintaxe especial para inicializar a estrutura, mas tudo bem.

Na verdade, o nome completo do tipo é

java.util.HashMap<java.lang.String, PdfObject>

Um pouco mais complicado, mas nada de mais.

Em C++, eu usei um

unordered_map<string, shared_ptr<PdfObject>>

É um pouquinho maior, e eu precisei usar um shared_ptr para não ter que me preocupar com a desalocação dos PdfObject. Não é tão ruim, né?

Bom, internamente esse tipo é traduzido para:

std::tr1::unordered_map<
  std::basic_string<
    char,
    std::char_traits<char>,
    std::allocator<char>
  >,
  std::tr1::shared_ptr<PdfObject>,
  std::hash<
    std::basic_string<
      char,
      std::char_traits<char>,
      std::allocator<char>
    >
  >,
  std::equal_to<
    std::basic_string<
      char,
      std::char_traits<char>,
      std::allocator<char>
    >
  >,
  std::allocator<
    std::pair<
      std::basic_string<
        char,
        std::char_traits<char>,
        std::allocator<char>
      > const,
      std::tr1::shared_ptr<PdfObject>
    >
  >
>

“Simples”, né? E é isso que aparece nas mensagens de erro e no IntelliSense, só que sem indentação!

Prêmio C++ está afundando na própria complexidade, vamos começar de novo e fazer certo

Esse prêmio vai para o D, obviamente. Pena que D (pelo menos a versão 2) também ganhou o prêmio de imaturidade…

Prêmio Máquina virtual? E se eu não quiser levar 100MiB junto com o meu programa?

C++ e D. Dispensas explicações. Queria colocar mais linguagens nessas categoria, o que eu incluiria?


Seguir

Obtenha todo post novo entregue na sua caixa de entrada.