Tolkien é um ótimo escritor. As histórias que ele conta é que não compartilham da mesma glória.
Acabei de ler o primeiro capítulo do segundo volume do Senhor dos Anéis. Ok, eu sobrevivi ao primeiro volume (que eu comecei a ler sem nenhuma pressa algum tempo atrás). Sobrevivi ao Tom Bombadil e ao banho anual da Goldberry. Sobrevivi às canções élficas que derrubam até os hobbits de sono (sim, isso é parte da história). Sobrevivi até a Lothlórien e o um mês que a galera ficou jogando fora lá comendo, dormindo e vendo televisão (a.k.a. Mirror of Galadriel) enquanto Sauron et al. tocavam o terror no mundo. Mas este capítulo foi demás.
Veja bem. Boromir, o inútil, depois de tentar roubar o anel do Frodo e atrapalhar a missão, não tendo feito nada de muito útil até esse ponto da história exceto ter ajudado a escavar a neve do monte Caradhras, que no fim das contas eles não atravessaram, perde a briga para um bando de orcs. Aragorn encontra Boromir semi-morto, depois de os orcs terem ido embora. "Eu ferrei com tudo. Agora os orcs levaram os hobbits embora. Vou morrer minha morte miserável aqui", diz Boromir, e morre sua morte miserável ali. Nesse momento a galera sai correndo na pista dos orcs para salvar os hobbits, certo?
Errado. Primeiro, Aragorn, Legolas e Gimli discutem como eles vão fazer o funeral do Boromir. Sim, é mais importante satisfazer o morto do que ir salvar os hobbits (afinal ninguém se importa muito com os hobbits nessa história). Aí eles decidem que cavar dá muito trabalho, então melhor é colocar o Boromir dentro do barquinho dele, junto com seus pertences e os dos orcs que ele conseguiu matar, e levar o barquinho até um ponto do rio e deixar o rio levar embora, não sem primeiro fazer dez mil preparativos. Claro que depois de largarem o barquinho, Aragorn e Legolas ainda cantam umas musiquinhas em homenagem ao morto. A essas alturas o Tolkien já está de saco cheio de escrever poemas (o livro é cheio de poemas), então as musiquinhas têm uma métrica totalmente capenga em comparação com as do primeiro livro. Really, a cena parece as firulas de cavalaria do Dom Quixote, com a diferença de que o Dom Quixote é intencionalmente zoação.
Até que, no final da tarde (essa história toda começou de manhã), Aragorn conclui: "Já sei! Quem sabe a gente vai atrás dos orcs, for a change?" "‘Well, after them!’ said Gimli. ‘Dwarves too can go swiftly, and they do not tire sooner than Orcs. But it will be a long chase: they have a long start.’" A long start? Imagine! Só umas seis horas de vantagem enquanto a gente colocava um morto num barco. O que são meras seis horas comparadas com os trinta dias que a gente passou comendo e dormindo em Lothlórien?
A essas alturas, a motivação primária que eu tenho para continuar lendo esse livro é o prospecto de ler The Last Ringbearer depois. E no fim das contas eu estou reclamando à toa; essa história é uma boa fonte de diversão.
Quando eu reescrevi o blog system, eu resolvi manter o índice de posts em um arquivo CSV e usar as funções fgetcsv e fputcsv para manipulá-lo. Minha intuição prontamente me disse "isso é PHP, tu vai te ferrar", mas eu não lhe dei importância. Afinal, provavelmente seria mais eficiente usar essas funções do que ler uma linha inteira e usar a explode para separar os campos. (Sim, eu usei um txt ao invés de um SQLite. Eu sou feliz assim, ok?)
Na verdade o que eu queria era manter o arquivo como tab-separated values, de maneira que ele fosse o mais fácil possível de manipular com as ferramentas convencionais do Unix (cut, awk, etc.). As funções do PHP aceitam um delimitador como argumento, então pensei eu que bastaria mudar o delimitador para "\t" ao invés da vírgula e tudo estaria bem. Evidentemente eu estava errado: um dos argumentos da fputcsv é um "enclosure", um caractere que deve ser usado ao redor de valores que contêm espaços (ou outras situações? who knows?). O valor padrão para a enclosure é a aspa dupla. Acontece que a fputcsv exige uma enclosure: não é possível passar uma string vazia, ou NULL, por exemplo, para evitar que a função imprima uma enclosure em volta das strings que considerar dignas de serem envoltas. Lá se vai meu tab-separated file bonitinho. Mas ok, não é um problema fatal.
A segunda curiosidade é que a fgetcsv aceita um argumento "escape", que diz qual é o caractere de escape (\ por default). Evidentemente, você tem que usar um caractere de escape; a possibilidade de ler um arquivo em um formato em que todos os caracteres exceto o delimitador de campo e o "\n" tenham seus valores literais é inconcebível. Mas ok, podemos setar o escape para um caractere não-imprimível do ASCII (e.g., "\1") e esquecer da existência dele. Acontece que a fputcsv não aceita um caractere de escape, logo você não tem como usar o mesmo caractere não-imprimível nas duas funções. WTF?
Na verdade, agora testando melhor (já que a documentação não nos conta muita coisa), aparentemente a fputcsv nunca produz um caractere de escape: se o delimitador aparece em um dos campos, ele é duplicado na saída (i.e., a"b vira a""b). Evidentemente, não há como eliminar esse comportamento. Mas então o que será que faz o escape character da fgetcsv?
# php -r 'while ($a = fgetcsv(STDIN, 999, ",", "\"", "\\"))
{ var_export($a); echo "\n"; }'
a,z
array (
0 => 'a',
1 => 'z',
)
a\tb,z
array (
0 => 'a\\tb',
1 => 'z',
)
Ok, o escape não serve para introduzir seqüências do tipo \t. Talvez para remover o significado especial de outros caracteres?
a\,b,z array ( 0 => 'a\\', 1 => 'b', 2 => 'z', ) a b,z array ( 0 => 'a b', 1 => 'z', ) a\ b,z array ( 0 => 'a\\ b', 1 => 'z', )
Muito bem. Como vimos, o escape character serve para, hã... hmm.
Mas o fatal blow eu tive hoje, olhando a lista de todos os posts do blog e constatando que o post sobre o filme π estava aparecendo com o nome vazio. Eis que:
# php -r '
$h = fopen("entryidx.entries", "r");
while ($a = fgetcsv($h, 9999, "\t"))
if ($a[0]=="20120322-pi") var_export($a);'
array (
0 => '20120322-pi',
1 => 'π',
2 => '2012-03-22 23:53 -0300',
3 => 'film',
)
# LC_ALL=C php -r '
$h = fopen("entryidx.entries", "r");
while ($a = fgetcsv($h, 9999, "\t"))
if ($a[0]=="20120322-pi") var_export($a);'
array (
0 => '20120322-pi',
1 => '',
2 => '2012-03-22 23:53 -0300',
3 => 'film',
)
A próxima versão do Blognir deverá usar fgets/explode.
UPDATE: Aparentemente o problema só ocorre quando um caractere não-ASCII aparece no começo de um campo. Whut?
UPDATE 2:
"a b","c d" array ( 0 => 'a b', 1 => 'c d', ) "a"b","c"d" array ( 0 => 'ab"', 1 => 'cd"', ) "a\"b","c d" array ( 0 => 'a\\"b', 1 => 'c d', )
[Este post foi engolido por um tigre. (31/03/2013)]
Com este post tenho o objetivo único e exclusivo de reclamar da vida. É improvável que haja qualquer informação proveitosa contida aqui. You have been warned.
Quando eu entrei para a Inf, os Sioux possuíam o mundo as páginas pessoais dos alunos eram contidas no diretório home de seus usuários (especificamente, em ~/public_html). O camarada podia acessar a portal.inf.ufrgs.br por SSH e editar as páginas remotamente com o Vim. Outra vantagem é que se podia rodar scripts remotamente para gerar páginas ou fazer algum procedimento de manutenção. Bem, mais ou menos. O home da portal é montado sem permissão de execução, o que significa que só dá para rodar os binários que já estão lá (e.g., bash, perl), e para poder rodar os scripts que eu tinha no ~/bin sem ter que digitar bash nome-do-script toda vez eu tinha que fazer uma gambiarra no ~/.bashrc para criar uma função com o mesmo nome do script para cada script presente no ~/bin. Mas ok, dava pra tolerar.
Em algum momento da história do mundo, as páginas pessoais foram levadas para um servidor separado, "por motivos de segurança". Conseqüentemente, não dava mais para alterar as páginas via portal. Montar o diretório das páginas por sshfs? Claro que não, a portal não tem sshfs e não executa binários do home. Solicitar à administração da rede para instalarem o sshfs na portal? Não faremos isso, por motivos de segurança. Well, dá pra montar o sshfs usando a máquina de casa, e se divertir com a latência do 3G. Heh.
Um dia me contaram que dava para acessar a portal, e de lá se logar nas máquinas dos laboratórios da graduação, de onde se pode rodar sshfs e tudo o mais que se queira. Hmm, boa! O camarada tem que se logar três vezes (uma na portal, uma nos labs, e uma no sshfs), mas ainda vale a pena. Se o 3G cai meu Vim fica parado lá me esperando e eu não corro o risco de ter salvo meio arquivo no home.
No semestre passado, atualizaram o OS das máquinas dos labs, e agora não é mais possível fazer o login remoto. Yay! Bom, sobrou o sshfs de casa. Felizmente, agora o meu 3G é um pouquinho melhor, com uma latência normalmente abaixo do 1 segundo (vs. os 4 da Tim), e a coisa é pelo menos utilizável.
O servidor das páginas pessoais também monta os homes sem permissão de execução, o que significa que só dá para usar as linguagens de script que já estão lá, i.e., PHP. PHP é uma linguagem/implementação notavelmente medonha, mas ok, é o que temos. Eu quero um blog, e eu quero agora, e eu quero escrever meus posts no Vim e salvar um txt somewhere para postá-los e ser feliz. Let's do it.
O PHP tem uma (so-called) "feature" chamada "magic quotes". A idéia é: programadores são incompetentes e esquecem de escapar as aspas antes de montar uma query de SQL, então vamos escapar automaticamente qualquer entrada que venha de um formulário. (A noção de montar queries de SQL na mão e escapar strings na mão é uma coisa que strikes me as fundamentally wrong, but I digress.) Acontece que o PHP só faz isso se ele estiver configurado para fazer isso no php.ini. E como (pelo que eu entendo) ele faz o escaping antes de rodar o script, o script não tem a oportunidade de desativar as magic quotes. Conclusão? Eu tenho uma função no blog cujo único propósito é receber uma string e remover os escapes se as magic quotes estiverem ativas, ou retornar a string intacta caso contrário. Lindo, hein?
E as closures. Em JavaScript (é, eu vou usar JavaScript, outra linguagem linda, como exemplo, mas acho que assim será mais compreensível do que o Common Lisp que eu ia usar) podemos fazer coisas do tipo:
function menores_que(n, lista) {
return lista.filter(function(x) { return x<n; });
}
menores_que(5, [2,3,5,7,11]); // Retorna [2,3].
Aqui, passamos uma função anônima para o método filter, que seleciona os elementos da lista que satisfazem o predicado passado como argumento. (Esse método só existe no JavaScript da Mozilla, eu acho.) Note que a subfunção usa o n definido fora dela. Em PHP 5.3 foi introduzida uma feature similar. Porém, na versão PHP, você tem que declarar explicitamente quais variáveis externas serão capturadas pela closure. WTF? Isso é tão ridículo que não sei quem mais poderia ter a mesma idéia. Oh, well. (Pelo menos em C++11 há a opção de dizer "captura tudo e não enche".)
Ok, ok. Eu sobrevivi. 753 linhas de PHP. Até que ficou pequeninho para a quantidade de coisas que o blog faz. O problema é que o código ficou todo gambiarrento, e sempre que eu vou adicionar uma feature é um trabalho medonho, e sempre que eu penso em reescrever do zero (coisa que uma hora ou outra eu vou acabar fazendo, já que eu não consigo ficar cinco minutos editando o código atual sem ranger os dentes) eu lembro que terei que fazer isso em PHP (o que produzirá uma quantidade equiparável de ranger de dentes) e abandono a idéia. Mas terá que ser feito, porque PHP é a única coisa que roda na Inf (e muitos outros lugares). Very well. (Actually, not.)
A última coisa que eu quis adicionar no blog foi uma feature de "Comentários recentes" na barra lateral. A idéia original era simplíssima: quando um leitor posta um comentário, além de criar o arquivinho de comentário no diretório apropriado, criamos também um symlink para o arquivinho em um diretório recent_comments da vida. Se o número de links exceder uma quantidade x, removem-se os links mais antigos. Simples, hã? Só que se eu tento usar a função symlink(), ela simplesmente retorna FALSE e nada acontece. What gives?
Acontece que o tal do Suhosin bloqueia a função symlink() do PHP se a opção base_opendir do PHP estiver ativada. Essa opção serve para limitar de que diretórios os scripts podem abrir arquivos. A idéia é que se o usuário puder usar a symlink(), ele poderia em tese despistar a base_opendir criando um link no diretório local para um lugar de onde o script não teria acesso (e.g., /etc/passwd). Porque o PHP não poderia primeiro resolver o symlink e depois testar se o arquivo está dentro dos diretórios permitidos antes de abri-lo, right? Nem a symlink() poderia verificar se o alvo do link está dentro dos diretórios permitidos e criar ou não o link dependendo do caso, right?
Acontece que aparentemete o PHP verifica o caminho resolvido antes de abrir o arquivo. You see, embora o PHP não possa criar symlinks, eu mesmo posso, por sshfs. Quer dizer que qualquer vulnerabilidade que links arbitrários pudessem causar ainda poderiam ser provocadas por mim. Mas eu testei criar um symlink local para o /etc/passwd, e o PHP se recusa a abri-lo, alegando violação da base_opendir. Quer dizer que mesmo que a symlink() estivesse ativa ainda não haveria vulnerabilidade. Mas ela não está, e isso impede gratuitamente minha implementação simples da feature de comentários recentes. Eu poderia entrar em contato com a administração da rede da Inf e pedir para eles habilitarem a feature. Eu não farei isso por duas razões: (1) a admrede vai me dizer que não vai habilitar nada "por motivos de segurança"; (2) um dos princípios por trás deste blog system é rodar em qualquer lugar que tenha um servidor com PHP, sem depender nem de bibliotecas non-standard nem da boa-vontade de sysadmins, e como o symlink() desativado é o padrão do Suhosin, não posso contar com a utilizabilidade dessa função. Tudo bem, o Unix original não tinha symlinks. Vamos brincar de anos setenta.
(For your enlightening. Midnight rant follows.)
Tendo terminado hoje a "prova" de Tópicos X (embora ainda não a tenha enviado), termina para mim para todos os fins práticos o semestre de 2012/2. Tópicos Especiais em Computação X, a.k.a. Grandes Desafios da Computação, é uma cadeira de 2 créditos que visa apresentar diversas áreas de pesquisa em Ciência da Computação. A maior parte das aulas consiste de uma palestra dada por um professor sobre sua área de pesquisa, no que ela consiste e quais são os desafios atuais que ela tem para resolver, além de dar uma idéia de como funciona a pós-graduação. Em uma dessas aulas, um professor mencionou (com uma certa ênfase) que a pós-graduação "não é mais do mesmo", que a dinâmica das aulas é diferente, que os alunos têm um papel muito mais ativo do que na graduação.
A primeira reação que eu tive diante disso foi uma boa dose de descrença. Talvez alguns professores dêem boas aulas, e os alunos desempenhe um papel mais ativo e autônomo, mas desconfio seriamente que com muitos professores a coisa não seja bem assim.
By the way, quem falou em autônomo? Isso aí brotou da minha cabecinha não-categorial. Só porque os alunos são mais ativos, não quer dizer que eles tenham algum poder de decisão sobre o que aprendem. Disse ainda o camarada palestrante que como não há cadeiras obrigatórias no mestrado, o aluno pode escolher fazer cadeiras apenas nas áreas que lhe interessam. Porém, no caso das cadeiras eletivas da graduação, os fatos de (1) haver um número mínimo de créditos eletivos obrigatórios, (2) não haver cadeiras suficientes em determinados tópicos, e (3) diversas cadeiras existirem apenas "para inglês ver", não sendo oferecidas em nenhum semestre na prática, significam que no geral é inviável fazer todas as eletivas em assuntos de interesse, e não vejo por que isso seria diferente no mestrado.
O segundo pensamento que me ocorreu é, se o mestrado é toda essa maravilha, por que diabos a graduação não é? É para filtrar dos reles mortais os poucos que têm saco de aturar a graduação inteira e ainda têm ânimo de continuar na academia? É por falta de professores (assumindo que uma melhoria exigisse turmas menores, como são no mestrado, proposição da qual eu duvido)? Porque "sempre foi assim"? Porque no final das contas o objetivo da graduação é produzir um diploma que dá ao camarada o direito de ser empregado em lugares que pagam melhor, e não adquirir e construir conhecimento? Todas as alternativas acima?
É nessas horas que eu me pergunto se vale a pena seguir a vida acadêmica. Meu objetivo inicial, logo que eu entrei nesse curso, era me tornar professor e viver uma vida feliz e contente dando aula e fazendo pesquisa. O curso começou a ficar menos-que-excelente pelo terceiro semestre, e lá pelo sexto ou sétimo eu já estava de saco cheio o suficiente para ter vontade de largar a faculdade. Muita gente que eu conheço encheu o saco bem antes; o que me sustentou nesse tempo foi primariamente o fato de que eu me interesso realmente muito por Ciência da Computação, e leio sobre coisas que me interessam fora do curso, o que mantém meu "amor à arte" firme e forte, apesar do curso. Felizmente a parte mais maçante do curso já se foi, e agora só me restam 6 créditos eletivos por fazer (ou 8, se o professor de Tópicos X não gostar das minhas respostas, já que a prova não é lá muito objetiva*) e o TCC (que é trabalhoso, mas pelo menos eu arranjei um assunto que me interessa para fazer ele sobre (e que venha o monstro da gramática me devorar)).
Como se não bastassem os horrores da graduação para desmotivar o sujeito, eu vejo por aí coisas do tipo:
Basically everyone who gets tenure, including me, finds him/herself continuing to get busier every year. Not only do the demands on our time increase, but we can no longer fall back on the convenient selfish excuse “sorry—can’t possibly do that time consuming task while I’m on the tenure track.” The constantly overloaded TODO list gets old, and it also makes it hard to get actual research done. It’s no coincidence that a lot of tenured professors rely on students to do all of the technical work associated with their research programs. Untenured professors not only have more time to do research but also may be reluctant to risk their careers by putting students on too many critical paths.
– Life After Tenure (ênfase minha)
Mais de uma vez eu já li ou ouvi relatos de que os encargos administrativos de um professor tomam tempo suficiente para atapalhar a "pesquisa de verdade". E aí reside um baita de um problema, porque se eu tiver que escolher entre ser professor e desenvolver software, eu prefiro desenvolver software. Na minha concepção inicial do universo, eu não teria que escolher, mas parece que minhas suposições podem estar erradas. Je ne sais plus.
(Não, isso não tem nada a ver com o resto do post.)
Para quem não sabe, antes de entrar para a Ciência da Computação (em 2009) eu cursei um semestre e meio de Letras. Os motivos para isso foram meu interesse por lingüística e a ausência de um curso específico de lingüística em uma faculdade próxima (a faculdade mais próxima com um curso de Lingüística é a Unicamp), o fato de que eu estava de saco cheio de computadores (primariamente porque eu tinha zilhões de problemas com computadores na época, primariamente porque eu tinha uma máquina extremamente capenga, mas também porque viviam me alugando para resolver problemas), e o fato de que eu estava de saco cheio de matemática (graças a um curso de iniciação científica oferecido pelo IMPA para os primeiros dez bilhões de colocados na Olimpíada Brasileira de Matemática das Escolas Públicas, o qual eu abandonei depois de três meses, embora eu estivesse sendo pago para participar). Quaisquer que tenham sido os motivos, eu tomei a decisão de fazer o curso de "Letras – Tradutor Português e Japonês" (porque foi a língua que me pareceu lingüisticamente mais interessante, e não porque eu gosto de animê e mangá, como aparentemente era o caso de todos os outros (cerca de oito) alunos).
Embora algumas cadeiras fossem insuportáveis (e.g., Leitura e Produção Textual), algumas cadeiras eram muito legais (Conceitos Básicos de Lingüística, Japonês I), e embora historicamente eu detestasse de coração o estudo de literatura que se faz no ensino fundamental/médio, até as cadeiras de literatura estavam interessantes.
Até que chegou a primeira prova de Literatura Brasileira A. Eu fiz a bendita prova e tirei um C. Nesse momento eu contemplei a prova, mirei as respostas, e me dei conta de que eu não fazia a menor idéia de por que eu tinha tirado um C, ou o que eu poderia ter respondido diferente para tirar uma nota melhor. Nesse momento eu me dei conta de que se eu não era capaz de determinar o que estava "errado" na prova, meu desempenho no resto do curso provavelmente seria a mesma coisa, já que responder "certo" parecia exigir uma habilidade mágica que não só eu não tinha, como sequer compreendia a natureza da mesma. Nesse momento eu tive um profundo insight: "Que diabos eu estou fazendo aqui?!"
(Fora que o conteúdo de lingüística do curso é um quase nada.)
E foi assim que eu não fiz a segunda prova de Literatura Brasileira A (embora tenha ido às aulas), terminei as outras cadeiras decentemente, no semestre seguinte peguei apenas quatro cadeiras (incluindo uma eletiva, nenhuma relacionada a literatura), larguei todas em setembro para me mudar temporariamente para a casa da minha mãe e estudar para o vestibular, e no ano seguinte entrei para a Ciência da Computação, onde, se muitas das cadeiras são terrivelmente maçantes, pelo menos os critérios de avaliação são largamente objetivos.
O vídeo linkado diz "que voy a hacer" ao invés de "qué voy a ser". Nunca tinha me ocorrido essa interpretação (acentuação notwithstanding). Mas camarada Google diz:
E no entanto os primeiros sites retornados por uma pesquisa por manu chao me gustas tu lyrics favorecem o "que voy a hacer". E agora?
Ontem ocorreu a festinha de aniversário da minha irmã, e conseqüentemente uma reunião familiar. Como em mais de 50% das reuniões desse ramo da família, em algum ponto surgiu uma discussão sobre como as pessoas falam errado hoje em dia. O português "correto", dependendo da fase da lua, inclui:
21 anos de convivência me levaram a crer que discutir é inútil, embora eu ainda me arrisque a fazer um remark ou outro no meio das discussões. Vocês falam latim, pessoas? Esse tal de português correto a que vocês se referem nada mais é do que latim com dez ou quinze séculos de erros acumulados, penso eu comigo mesmo. E esse tal de latim nada mais é do que proto-indo-europeu com dez ou quinze séculos de erros acumulados. Mas eu fico na minha.
Desde pequeno eu observo que os tipos de erros cometidos por cada ramo da família são diferentes. Por exemplo, do lado paterno o para mim fazer (ao invés do para eu fazer do português "standard") é bastante comum. Do lado materno, isso praticamente não ocorre, mas em compensação há uma tendência geral a usar os pronomes retos ao invés dos oblíquos (ele viu nós). O ponto digno de observação é que os erros de cada grupo de falantes são consistentes. E uma vez que línguas nada mais são do que pura convenção, erros consistentes não são exatamente erros.
Convenção aqui é a palavra-chave: uma frase está "correta" se ela segue as convenções estabelecidas entre os falantes. Diferentes situações implicam diferentes convenções, entretanto: as convenções utilizadas para textos formais escritos são diferentes das convenções usadas pela língua formal falada, que são diferentes das convenções usadas na linguagem informal. A língua não é uma unidade uniforme, mas sim é composta por diferentes variantes, ou registros, que são usados conforme a situação. Exigir a presença das marcas de plural na língua formal escrita é perfeitamente válido; exigir que as pessoas pronunciem todas as marcas de plural em conversas informais é ridículo. (No caso da língua escrita em particular, especialmente em textos formais, o conservadorismo lingüístico é útil para garantir que textos escritos hoje possam ser compreendidos daqui a cinqüenta ou cem anos.)
Mas mesmo as variantes formais da língua sofrem variações com o tempo. Ninguém mais usa o vós, por exemplo. O pretérito mais-que-perfeito (eu fizera) está em vias de cair do cavalo também, embora algumas pessoas ainda gostem de usá-lo em textos literários. Hoje em dia há uma contenda quanto ao uso de pronome oblíquo em começo de frase (me parece correto, ao invés de parece-me correto). O pronome oblíquo inicial soa errado aos ouvidos de Portugal, e os gramatiqueiros prescritivistas brasileiros tendem a declarar a construção como inválida. No Brasil, entretanto, o pronome oblíquo inicial é comum na língua falada, mesmo nas variantes formais, e há uma tendência geral a se usar próclise sempre (i.e., colocar o pronome oblíquo sempre antes do verbo), e aparentemente essa é uma tendência já de séculos [citation needed]. Tentar forçar a língua escrita a um padrão estranho a todos os falantes da dita língua (o português do Brasil) é um tanto quanto tosco. É que nem tentar forçar os falantes de português do Brasil a escreverem estou a fazer, ao invés de estou fazendo. (Nesse caso, o português do Brasil é mais conservador, na verdade.)
Conseqüentemente, podemos concluir que daqui a uns duzentos ou trezentos anos provavelmente alguns usos do plural terão caído em desuso. "Mas como vamos viver sem o plural?", ouvem-se os gritos de horror de alguns. Bom, tecnicamente nós já estamos vivendo sem algumas marcas de plural na língua falada há muito tempo, e ninguém sofreu danos deletérios. Além disso, historicamente temos diversas instâncias de perdas de features gramaticais. Já ouviu falar do acusativo? Assim como em português nós marcamos o plural com uma flexão especial dos substantivos, adjetivos e pronomes, em latim havia uma flexão especial que se usava para marcar que uma palavra era o objeto direto de um verbo. Assim, puella poetam videt significava "a menina vê o poeta", mas puellam poeta videt significava "o poeta vê a menina". O -m final que costumava marcar o acusativo (o objeto direto) com o tempo passou de um m perfeitamente audível a uma simples nasalisação da vogal que o precede (de maneira similar, os m finais em português normalmente não são pronunciados como um m "de verdade"), e com o tempo simplesmente se perdeu. Como resultado, marca de acusativo em substantivos e adjetivos em português simplesmente não existe (embora resista em alguns pronomes, e.g., eu vs. me). "Como vamos viver sem acusativo?", ouviam-se os gritos de horror da antigüidade. Exatamente assim, respondemos nós. A marca do objeto direto por flexão deu lugar à indicação pela ordem da frase (i.e., a menina vê o poeta ≠ o poeta vê a menina). E tem funcionado muito bem nos últimos dez séculos. Da mesma forma, a flexão de plural está dando lugar ao plural marcado apenas nos artigos e verbos, e em substantivos e adjetivos em contextos limitados.
"Mas então as línguas estão perdendo itens gramaticais o tempo todo? Daqui a pouco não vai sobrar nada da gramática!", ouvem-se os gritos de horror. Bom, não é bem assim. Ao mesmo tempo em que as línguas perdem features gramaticais, elas também adquirem features novas com o tempo. Por exemplo, na transição do latim para o português, a língua adquiriu um futuro do subjuntivo (quando eu fizer), que não existia em latim e é relativamente raro entre as línguas do mundo. O português também ganhou um igualmente raro infinitivo conjugado (para nós fazermos), que compartilha das mesmas formas do futuro do subjuntivo nos verbos regulares. O futuro do presente original do latim foi perdido e substituído por uma forma composta usando o verbo haver (amar hei (= hei de amar)), e posteriormente a forma composta foi readquirida como um tempo verbal (amarei). (Aliás, é por isso que a mesóclise é possível em português: o pronome pode ser intercalado no verbo porque o verbo é originalmente composto por duas palavras separadas.) O futuro está em vias de se perder de novo (amarei → vou amar), por sinal. É assim que funciona a porcaria.
Uma coisa que me deixa admirado nessa história de variantes lingüísticas é que muitas pessoas simplesmente não têm consciência de que usam mais de uma variante da língua. Ontem, durante a discussão, um dos presentes declarou que falava o português "correto". Só que isso não é verdade quanto a praticamente qualquer falante, se "correto" refere-se ao padrão literário da língua prescrito pelos gramatiqueiros. Ainda que algumas pessoas mais cuidadosas evitem omitir os plurais, a omissão dos -r finais de conjugações verbais (com exceção de pôr, for) é praticamente universal na língua falada, quando não se está dando ênfase ao verbo. O mesmo vale para a substituição de pronomes oblíquos de terceira pessoa por pronomes retos (eu encontrei ele na rua, ao invés de eu o encontrei na rua). Alguns "erros" são tão comuns que raramente são notados, mesmo quando a pessoa está cuidando para encontrar erros. Orações subordinadas são uma fonte particularmente freqüente de desvios:
Pronomes também têm adquirido uns usos curiosos ultimamente. Uma construção que eu vejo ser usada com bastante freqüência na língua falada são coisas do tipo o Instituto de Informática, ele fica no Campus do Vale (com um ele a mais referindo-se ao sujeito que acabou de ser mencionado). Algumas pessoas usam os pronomes de terceira pessoa como pronomes resumptivos (o cara que eu falei com ele). Alguns desses usos me dão coceira no rim, já que por alguma razão eu mesmo não os uso*. É normal, entretanto, que inovações lingüísticas se espalhem gradualmente, e portanto não tenham aceitação absoluta de imediato. Pode também acontecer de elas simplesmente se espalharem entre alguns grupos e não entre outros, produzindo dialetos divergentes.
No más.
[* Eu costumo cometer uma atrocidade diferente e dizer o cara que eu conversei com, roubando uma feature do inglês. Não acho provável que essa construção venha a adquirir uso amplo em português, entretanto.]
Esse fim-de-semana assisti um filmezinho chamado Sucker Punch. O filme pretende ter uma historinha "bonita" com uma moral nobre. Resumo da ópera: mãe morre e as filhas ficam com o padrasto. Padrasto fica fulo da vida porque a mulher não deixou nada para ele no testamento (pode-se vagamente assumir que a morte da mulher é responsabilidade do padrasto), e resolve abusar das filhas. A filha mais velha consegue se safar do cara, o cara tranca a guria no quarto e vai atrás da pequena. A guria escapa pela janela, conjura uma arma do éter luminífero, vai atrás do cara, dá um tiro para matá-lo, erra e mata a pequena. O cara chama a polícia, decidem internar a guria em um sanatório, e o cara suborna o rei do sanatório para fazerem uma lobotomia na guria para ela não contar nada à polícia. O rei do sanatório explica que o homem da lobotomia só aparece dali a uns dias, e enquanto isso a guria fica em tratamento no lugar lá. Essa introdução da história é apresentada em uns cinco minutos de filme, e é basicamente a única parte com alguma complexidade do enredo. A guria é levada a uma sala enorme onde uma mulher realiza algum tratamento psicoterápico maluco. Passam mais algumas cenas do sanatório. Lá pelas tantas, o filme começa a se passar em um mundo paralelo em que a guria está sendo levada para um bordel, onde ela é mantida com umas outras gurias. A sala enorme agora é alguma coisa bar-like com um palco. Muitas cenas depois, a guria vai fazer seu primeiro ensaio como dançarina, e quando começa ela a dançar, somos transportados para um outro mundo paralelo, onde ela entra em um templo pseudo-oriental onde há um mestre, que pergunta o que ela quer da vida. Ela diz que quer cair fora daquele lugar. O velho lhe entrega uma espada e umas armas, e diz que ela precisa de cinco itens para escapar. No mundo do nível anterior, a guria convence as outras a seguir um plano para tentar escapar do lugar. O plano consiste em a guria ficar dançando e distraindo a galera enquanto as outras fazem todo o trabalho sujo. Sempre que ela dança, o filme passa para o mundo de nível 3, onde as ações do plano de fuga correspondem a batalhas e explosões e tiros e dragões e what-not. No fim do filme, o quinto item necessário é a própria guria, que se sacrifica para a única outra guria que sobrou viva a essas alturas conseguir fugir. A morte da guria no nível 2 corresponde à lobotomia no nível 1. Fica claro aí que todos os eventos do nível 2 tiveram alguma correspondência no nível 1, e que uma das gurias de fato fugiu do sanatório. O cara que fez a lobotomia pergunta para a mulher do tratamento psicoterápico por que ela recomendou o procedimento, e ela responde que não recomendou. Nisso descobrem essa e outras tretas do rei do sanatório, ele vai preso, todos comemora. Em paralelo ao começo e ao fim do filme, há uma narrativinha dizendo que "ah, os anjos nos ajudam, mas não lutam por nós, somos nós quem decidimos o nosso destino, blá, blá, blá".
Em muitos aspectos, o filme é O Labirinto do Fauno com menininhas bonitas e explosões.
Essa foi a primeira impressão que o filme me passou. Mas depois de uma análise mais cuidadosa, percebi que há inúmeros paralelos entre as duas histórias. Começando pelo começo. Em ambas as histórias, a protagonista tem um padrasto cruel (no Labirinto do Fauno (LF), o padrasto é um capitão fascista que tortura e/ou mata metade do elenco e maltrata a outra metade). Em ambas as histórias, a protagonista "escapa" do mundo real para um mundo imaginário ou paralelo (no LF, um mundo mágico a la folclore europeu). Em ambas, o objetivo da protagonista é fugir (no LF, para um mundo subterrâneo, onde ela é uma suposta princesa que se perdeu no mundo dos homens). Em ambas, a saga começa com um mestre que dá instruções (no LF, o fauno).
No Sucker Punch (SP), a menina precisa obter cinco itens para fugir. O primeiro item é um mapa. No LF, a primeira coisa que o fauno dá à Ofelia (a protagonista) é um livro que diz o que ela tem que fazer e para onde tem que ir (não é exatamente um mapa, mas é close enough). O segundo item é fogo, que no mundo-nível-2 é um isqueiro. No mundo-nível-3, as gurias têm que entrar em um castelo, cortar a garganta de um dragão e pegar dois cristais que lá se encontram. No LF, a Ofelia tem que entrar em uma árvore moribunda, meter a mão na língua de um sapo gigante e pegar uma chave. No SP, as gurias têm que pegar os cristais sem acordar a mãe do dragão, mas a protagonista resolve testar os cristais dentro do castelo, faz um fogo medonho, acorda a dragoesa e a galera tem que sair correndo para escapar. Pois bem, a próxima missão da Ofelia é entrar em uma sala onde há uma mesa com um banquete preparado, abrir um cofre com a chave, pegar uma faca de lá e levar de volta antes que seu tempo acabe, mas não pode comer nem beber nada do banquete, para não acordar uma criatura muito doida que está no final da mesa. Ofelia come umas uvas da mesa, a criatura acorda e ela tem que sair correndo para escapar. O terceiro item no SP é (adivinhem só?) uma faca, que posteriormente será usada para matar o rei do bordel para conseguir o quarto item... uma chave! No fim do LF, para testar a Ofelia, o fauno a manda buscar seu irmão recém-nascido. Ao chegar com a criança para o fauno, o fauno diz que precisa derramar algumas gotas do sangue de um inocente (o bebê) para abrir o portal para o mundo mágico. Ofelia se recusa a entregar a criança, o fauno diz que então não pode levá-la ao mundo mágico, e desaparece. Nisso o capitão fascista está a perseguindo e a alcança, e lhe dá um tiro. Ofelia morre, e seu sangue é derramado na fontezinha feliz, e ela vai parar no mundo mágico, onde ela é congratulada por sua decisão nobre. No SP, o quinto e último item é a própria protagonista, que se sacrifica para a outra guria fugir.
No SP, os eventos de cada mundo paralelo possuem uma correspondência com os eventos dos outros. No LF, há algumas evidências de que o mundo mágico é o mesmo mundo real (a mandrágora entregada pelo fauno para que Ofelia pusesse debaixo da cama da mãe que está grávida e quase morrendo para curá-la de fato funciona, o capitão a encontra, e a mãe a atira no fogo, após o que a mãe adoece de novo; quando a Ofelia está fugindo do capitão no labirinto do fauno e chega a um beco sem saída, uma passagem se abre a ela, pela qual ela escapa e o capitão a perde; aparentemente Ofelia escapa do quarto pela porta desenhada a giz na parede).
Basicamente, o Sucker Punch tem um enredo bastante superficial, e boa parte da substância da história foi copiada largamente inspirada pelo Labirinto do Fauno. Na verdade, a maior parte do enredo do SP parece servir apenas para prover um ambiente onde menininhas bonitas com pouca roupa realizam coreografias interessantes, em meio a explosões e lutas com espada. Por que a guria se imagina em um bordel, onde todas as guriazinhas usam um quase nada de roupa o tempo todo? Ok, talvez seja o trauma de ter quase sofrido assédio do padrasto. Bom, mas por que diabos no outro mundo imaginário, onde ela literalmente luta para escapar, as gurias também usam roupinhas curtas, e a protagonista em particular usa algo que lembra um uniforme de colegial japonesa com menos pano? Na medida em que o intento do filme era de fato esse ("On the other hand, though it's fetishistic and personal, I like to think that my fetishes aren't that obscure. Who doesn't want to see girls running down the trenches of World War One wreaking havoc?" (palavras do diretor)), pode-se dizer que é um bom filme. Agora dizer que "one interpretation of the film is that it is a critique on geek culture's sexism and objectification of women" (segundo o mesmo diretor, segundo a Wikipédia) é demás. A menos que seja alguma espécie de psicologia reversa: o filme é o alvo de sua própria crítica. [Edit: Yes, it is. Quem diria?]
Fim de papo. Awey.
Passei a vida mantendo uma distância saudável do public static void fucking Java, com exceções esporádicas que ajudaram a reforçar o sentimento. Esse semestre, entretanto, estou fazendo a rica cadeira de Programação Paralela e Distribuída, cujos exercícios de laboratório devem ser todos feitos em Java. Nesses momentos de diversão incomensurável descobri mais uma das maravilhas dessa linguagem: o conceito de checked exceptions.
A idéia é genial: na declaração de um método, é possível adicionar uma cláusula throws exceção, que informa ao compilador que o método pode lançar a exceção em questão, e o programador é obrigado a tratá-la quando chamar o método, ou a declarar que o seu método também pode lançar a exceção. O resultado prático, obviamente, é que enquanto se está testando o programa acaba-se adicionando tratadores de exceção do tipo:
try { do_whatever(); } catch (Exception e) {}
Até que de fato queremos debugar um problema com do_whatever(), e queremos o bom e velho stack trace que acompanha a exceção, mas que está sendo engolido pelo catch vazio. Nesse momento, mudamos o tratador para:
try {
do_whatever();
} catch (Exception e) {
System.out.println(e);
e.printStackTrace();
}
Que é, bem, o tratador de exceções padrão. Não é ótimo ter que escrever você mesmo o tratador de exceções padrão da linguagem?
Além de, de certa forma, matar o propósito das exceções (isolar o tratamento de erros do resto do código), o que os criadores da linguagem aparentemente não conceberam é que enquanto eu estou escrevendo o programa, ele não está pronto. Eu quero poder ir testando o programa à medida em que vou escrevendo, e não quero entupir o código com tratadores de exceção enquanto estou fazendo o código funcionar. De fato, o que eu quero normalmente é não tratar uma exceção, para obter um stack trace. Talvez eu sequer tenha decidido ainda qual a melhor maneira de tratar o erro. (O quê?! Você não tinha um projeto detalhado do programa antes de começar a escrevê-lo? Blasfêmia! Vá vestir sua gravata e volte para os diagramas UML.)
Lisp foi provavelmente a primeira linguagem a incorporar a idéia de que é útil executar programas incompletos, e o Common Lisp provavelmente ainda é a linguagem que faz isso com mais competência. Em (Common) Lisp, chamadas a funções inexistentes, chamadas com número errado de argumentos, tipos diferentes dos esperados, etc., geram erros de execução. Um bom compilador também gera warnings em tempo de compilação ao encontrar esses problemas, mas não impede a compilação e execução do programa. O programador pode então decidir corrigir os erros imediatamente, quando possível, ou executar o programa incompleto para fins de teste. Erros de execução em Common Lisp não encerram o programa, mas abrem o debugger, de onde se pode averiguar e alterar o estado do programa, e erros geralmente são continuáveis, i.e., é possível prosseguir com a execução de um programa após a ocorrência de um erro de execução. Além disso, as implementações oferecem um prompt interativo de onde se pode chamar as funções do programa diretamente, sem necessidade de escrever uma função main para testar funções internas do programa. O resultado é que se pode encontrar e corrigir os problemas do programa à medida em que ele é escrito, ao invés de escrever um código longo e "inteiro" e debugá-lo depois.
C, nesse e em outros quesitos, segue uma filosofia "não ajuda mas também não atrapalha". Boa parte dos erros de tipos geram warnings ao invés de erros. A linguagem não força o tratamento de erros de execução (mas também não lhe diz que eles ocorrem, além da sucinta mensagem Segmentation fault).
Hoje em dia as assim chamadas linguagens de script são mais flexíveis com programas incompletos, e muitas oferecem prompts interativos, embora estes costumem parecer afterthoughts*, especialmente comparados com o Common Lisp. Não matar o programa diante de erros e permitir continuar a execução ainda é uma idéia louca demais para essas linguagens.
Java, entretanto, destaca-se entre as demais linguagens em ativamente impedir a execução de programas incompletos, não por razões técnicas, como em C, mas por filosofia da linguagem. Ironicamente, um dos co-autores da especificação do Java é o Guy Steele, um dos criadores do Scheme, autor do Common Lisp, the Language, e um dos principais membros do comitê de padronização do Common Lisp. A vida tem dessas coisas.
Desculpem o rant. Pretendo que eles sejam esporádicos no blog, e escrever conteúdo mais útil/interessante/informativo a maior parte do tempo. Mas sendo ranting a função primária de um blog, é impossível suprimi-la totalmente. Humanitas precisa reclamar.
E já que chegamos até aqui, vou aproveitar a atmosfera smug-lisp-weenie e fazer uma análise dos prompts interativos das linguagens de script mais populares.
Python: Python é whitespace-nazi o suficiente para reclamar se o código estiver indentado mas não estiver subordinado a nenhuma estrutura de controle (e.g., a primeira linha de código de um programa nunca pode estar indentada). O prompt, obviamente, não é exceção. Como conseqüência, não se pode copiar um trecho interno de uma função e colar diretamente no prompt para testar. Além disso, o prompt interativo prestativamente imprime ... quando espera que um comando de múltiplas linhas seja completado, o que significa que não se pode copiar o trecho de código sem alterações e colar de novo no prompt (afinal seta-pra-cima anda pelo histórico linha por linha, não expressão por expressão) ou no código-fonte.
Ruby: Não é whitespace-nazi, mas compartilha dos outros problemas.
Perl: Segundo o FAQ da linguagem, a maneira típica de usar a linguagem interativamente é entrando no debugger, com um comando do tipo perl -de 42. O debugger não tem suporte a readline (i.e., sem seta-pra-cima). O debugger não imprime o resultado das expressões. Há comandos para imprimir, mas...
DB<1> @a = (1,2,3) DB<2> p @a 123 DB<3> $a = [1,2,3] DB<4> p $a ARRAY(0x209d968)
Perdeu pro GDB, hein? Lamentável.
PHP: A versão linha de comando do php tem um "modo interativo", que consiste simplesmente em ler o código da stdin as usual, mas executar as expressões à medida em que são lidas. Sem prompt, sem histórico, sem impressão das expressões por default. E sim, tem que digitar o <?php antes do código.
JavaScript: Eu ia avacalhar com o JavaScript por costume, mas depois das duas acima é complicado. O prompt do SpiderMonkey usa as conversões de string padrão do JavaScript, que transformam [[1,2,3],[4,5,6]] em "1,2,3,4,5,6", mas pelo menos é fácil de remendar. O histórico é linha-por-linha (aliás, o mísero e ignorado bash anda expressão por expressão no histórico), mas pelo menos o prompt não imprime um prefixo antes das linhas de continuação. E parece que as versões mais novas do SpiderMonkey imprimem os objetos numa sintaxe JSON-like, o que resolve o problema anterior e ganha do <main.Foo instance at 0x00234269> das linguagens acima. É, a coisa tá tão feia que o JavaScript ganhou de todo o mundo. A vida tem dessas coisas.
Copyright © 2012-2013 Vítor Bujés Ubatuba De Araújo
O conteúdo deste site, a menos que de outra forma especificado, pode ser utilizado livremente, com ou sem alterações, desde que seja mencionado o autor, preferivelmente com a URL do documento original.
Powered by Blognir.