Elmord's Magic Valley

Software, lingüística, mitologia nórdica e rock'n'roll

Twitter via linha de comando

2013-05-07 14:27 -0300. Tags: comp, unix, web, about

Por falta de coisa mais interessante para fazer, e já que RSS não é exatamente a tecnologia da modinha, estou disponibilizando experimentalmente um feed do blog no Twitter. A continuidade do "serviço" está sujeita à existência de usuários. [Update: Pensando melhor, provavelmente todo o mundo que tem interesse em seguir blogs usa RSS. Enfim, o feed está aí, por enquanto.]

A parte interessante da história é que eu descobri um bocado de clientes de linha de comando do Twitter no processo. Dos que eu experimentei, o que melhor me satisfez foi o t. (Eu experimentei mais outros dois clientes: o TTYtter, um cliente interativo pra lá de bizarro, mas com mil features e aparentemente fácil de estender; e o twidge, que aparentemente não suporta UTF-8. Existem dúzias de outros clientes, como uma pesquisa no Google revela.)

Os poderes mágicos do t derivam do fato de ele ser particularmente conveniente de usar em scripts. Um exemplo extraído da documentação:

Favorite the last 10 tweets that mention you

t mentions -n 10 -l | awk '{print $1}' | xargs t favorite

É possível instalar o t pelo RubyGems, através do comando gem install t. Antes de instalá-lo, certifique-se de que você tem instalado o Ruby e o RubyGems (pacotes ruby, ruby-dev e rubygems no Debian/Ubuntu; não ter o ruby-dev é um problema comum).

Uma vez instalado, é necessário executar t authorize, para realizar o processo de registro da aplicação no Twitter e de autorização do acesso da aplicação à sua conta. Você pode executar t sem argumentos para ver uma lista dos comandos disponíveis. Para mais informações, dê uma olhada no README na página do projeto.

(Quem me contou foi essa página.)

4 comentários

Culinária para os Totalmente Perdidos #1: Miojo com molho de atum/guisado

2013-05-06 05:31 -0300. Tags: cook, home

Isso aqui é tão simples que praticamente não conta como receita, mas dada a freqüência com que eu ouço gente dizer que come o Miojo puro (ou ainda, com aquele temperinho maligno (shudder)), talvez este post possa ser útil.

Ingredientes

O molho

Atum edition: Abra a lata de atum e despeje fora o óleo/água. Despeje o atum em uma panela e deixe cozinhar por cerca de um minuto, mexendo ocasionalmente.

Guisado edition: Despeje um pouquinho assim de óleo (cerca de 5 colheres de sopa) em uma panela e deixe aquecer por uns 30 segundos. Despeje o guisado e deixe cozinhar por uns três minutos, ou até que a carne não esteja mais vermelha, mexendo ocasionalmente.

Em ambos os casos: Feitos os passos acima, despeje o molho pronto sobre a coisa toda e misture, e deixe cozinhar por cerca de dois minutos, mexendo ocasionalmente. Enquanto o molho cozinha, você pode adicionar o orégano (umas três colheres de chá, ou o quanto seu coração disser), se desejar. (Na minha experiência, o orégano fica melhor com atum do que com guisado.) Está feito.

Rendimento: o suficiente para duas porções de massa (veja adiante). Mesmo que você só vá fazer uma porção de massa, se optar pelo atum, é melhor fazer a quantidade "inteira" e guardar o que sobrar, pois atum estraga depois de aberto se não for cozido.

A massa

Use de ¾ a 1 tablete de massa, dependendo do grau de fome, para cada pessoa. (Para referência: 1 tablete = 125g; 1 miojinho = 80g). Ferva água suficiente para submergir o miojo. Despeje o miojo na água e deixe cozinhar por 5 minutos (sim, cinco; aquela história de "pronto em 3 minutos" funciona para o miojinho, mas nem tanto para o miojão), ou até que a consistência lhe agrade. Despeje a água fora e misture a massa com o molho. Divirta-se.

Observações

Você pode fazer a massa e o molho em paralelo e ganhar tempo, ou fazer primeiro a massa e depois o molho e ganhar uma panela a menos para lavar.

Há quem diga que não se deve derramar o óleo do atum na pia, pois provoca entupimento e caos e destruição. Ao invés disso, deve-se coletá-lo e entregá-lo em um daqueles lugares míticos em que se coleta óleo. (Imagino eu que derramar o óleo em uma garrafa e colocá-lo no lixo também seja uma alternativa razoável.)

2 comentários

#123

2013-05-02 23:20 -0300. Tags: random, life, mind, ramble

Caro mundo,

Ao invés de estar aproveitando meu tempo de uma maneira produtiva, resolvi passar o final do meu dia lendo o Hyperbole and a Half desde o primeiro post. Por mais improdutivo que seja, não posso dizer que foi uma má decisão. Além disso, ler certas coisas me fez pensar que morar nessa casa com o chão todo torto e que está começando a ficar úmido com a proximidade do inverno e que em breve vai começar a verter água, ao mesmo tempo em que caracóis começam a invadir a casa, até que não é algo tão ruim assim. O tempo está com cara de tempestade iminente, o que significa que meu 3G vai começar a se arrastar como os recém-mencionados caracóis, o que pode dificultar minha continuada leitura do recém-mencionado blog, mas enfim. (A concretização da tempestade, por sua vez, pode levar à falta de luz na rua em que se localiza a recém-mencionada residência pela qual eu acabo de expressar renovado apreço, rua esta com uma infraestrutura elétrica menos que invejável. Mas enfim. O tempo está bonito, pelo menos.)

(As a sidenote, se por acaso alguém estiver preocupado com o sumiço da Allie no final de 2011, saiba que ela deu sinais de vida no Reddit em março de 2012. Eu fiquei contente quando encontrei isso, anyway. [Update: She's back! Good timing, huh?])

(Como se diz "sidenote" em português? "Preterlóquio?" (Estou surpreso pela total ausência de resultados na minha busca no Google por "preterlóquio". Considerem a palavra criada (ainda que, talvez, não necessariamente com o mesmo exato sentido).))

Mas não é sobre nada disso que eu vim falar hoje. O que eu vim falar aqui originalmente é sobre o design de shells. Lembram que eu escrevi um post quatro meses atrás dizendo que estava querendo escrever um shell? Pois bem, obviamente eu não fiz isso, mas nesse meio tempo eu tive idéias. (Se me pagassem para ter idéias de software de aplicabilidade questionável eu estaria com a vida ganha. Ou não.) Na verdade eu agora fui olhar o respectivo post e descobri que ele é muito maior do que eu me lembrava, de tal maneira que eu já nem sei se vale a pena escrever outro post sobre o assunto. Quem sabe assim eu resolvo criar vergonha na cara e de fato implementar as idéias, ao invés de ficar discutindo o quão fantasticamente legais elas são. Na verdade meu objetivo original era pedir sugestões, então talvez até houvesse um ponto em escrever o post, mas não sei mais. Se alguém quiser dar sugestões anyway, sinta-se à vontade.

Ao invés disso, eu vou falar de outra coisa: vou falar do fato de que os seres humanos se acostumam com as coisas e com o tempo passam a perceber qualquer situação em que se encontrem como algo dado e corriqueiro. Não, isso não é novidade nenhuma; você já se acostumou com essa idéia também. Mas às vezes o módulo de assumptions da minha cabeça tem um lapso de funcionamento e eu tenho um choque de realidade. Por exemplo, estava eu hoje à tarde debruçado sobre a mesa da sala da monitoria tentando dormir (já que normalmente não aparece ninguém lá para pedir ajuda e é difícil fazer qualquer coisa produtiva por lá, pois é difícil se concentrar com o barulho (mas não dormir, you see (embora eu não tenha conseguido dormir de fato (so far este blog contém 1083 pares de parênteses, por sinal, sem contar trechos de código entre tags PRE, mas isso não vem ao caso no momento)))). Sem sucesso em minha tentativa de dormir, levanto e resolvo sair para ir ao banheiro (leia-se: pretexto para caminhar um pouco). Em um estado semi-acordado, começo a andar pelo corredor para a rua. Nesse momento eu olho ao redor e penso: "WTF? I'm in the fucking Instituto de Informática? Na Universidade Federal do Rio Grande do Sul? Que viagem!" Não só estou no fucking Instituto de Informática, como também no final do curso. Especificamente, o curso termina em dois meses se eu me pilhar de terminar o TCC neste semestre (estrategicamente, entretanto, isso não tem vantagem nenhuma; é um semestre de RU a menos). How mad is that? E ainda por cima eu estou morando sozinho? Eu tenho uma casa só pra mim? Sou eu que pago as contas? Eu posso fazer whatever the hell I please da minha vida? Por que diabos ninguém tinha me contado isso antes?

E é isso, galera. A moral é que às vezes a gente precisa de uns tapas na cabeça para ela ir para o lugar certo. (Não digo "voltar para o lugar certo" porque às vezes ela nunca esteve no lugar certo.) Agora, se vocês me permitem, eu vou continuar lendo Hyperbole and a Half até dormir em cima do teclado, já que eu descobri há meia hora atrás que não vou ter aula amanhã.

5 comentários

Diru tuj, kiom estas la batalpovo de Kakarotto?

2013-04-28 23:52 -0300. Tags: esperanto, random, img

Estas pli ol ok mil!!!

Não, eu não tenho nada melhor para fazer (um TCC, por exemplo).

[P.S.: Tecnicamente era para ter um "ĝi" no começo da frase, eu suponho, mas não teria o mesmo impacto.]

3 comentários

Gravando áudio e eliminando ruído com o SoX

2013-04-26 19:52 -0300. Tags: comp, unix, audio, mundane

O SoX (SOund eXchange; pacotes sox e libsox-fmt-all no Debian) é uma biblioteca e um programa de linha de comando que permitem converter entre diversos formatos de arquivo de áudio, opcionalmente aplicando filtros. A sintaxe básica do comando sox é:

sox [opções-globais]
    [opções-de-formato] entrada1
    [[opções-de-formato] entrada2 ...]
    [opções-de-formato] saída
    [filtros ...]

Por exemplo, para gravar do microfone (usando ALSA) em um arquivo WAV:

sox -t alsa default -t wav blabla.wav

(Use Control-C para terminar a gravação. Tecnicamente o -t wav pode ser omitido, já que o sox é capaz de deduzir o formato do arquivo pela extensão.)

Um par de filtros particularmente interessante é o noiseprof/noisered, que permitem eliminar ou reduzir ruído constante de fundo. Isso é feito em duas etapas. Primeiro, executa-se o sox com o filtro noiseprof [profile.txt] sobre uma "amostra de silêncio", i.e., um trecho de áudio que consista apenas do ruído de fundo, de maneira a produzir um profile de ruído. Você pode capturar o "silêncio" do microfone ou de algum outro arquivo que consista apenas de silêncio (a opção --null pode ser usada no lugar do arquivo de saída, já que estamos interessados apenas no profile de ruído):

sox -t alsa default --null noiseprof profile.txt

sox algum-arquivo-que-consista-apenas-de-silêncio.wav --null noiseprof profile.txt

Alternativamente, você pode selecionar um trecho de um arquivo com o filtro trim início [duração] e usá-lo como fonte de silêncio:

# Seleciona o intervalo de de 1s até 2.5s. Aqui usamos '-t alsa default' como
# saída para podermos ouvir se o trecho selecionado de fato corresponde a "silêncio".

sox entrada.wav -t alsa default trim 1 1.5 noiseprof profile.txt

Se o nome do arquivo de profile for omitido, o sox escreve o profile na stdout.

Gerado o profile de ruído, podemos usar o filtro noisered [profile.txt [quantidade]] para remover o ruído do arquivo completo. quantidade é um número entre 0 e 1 indicando a quantidade de ruído que deve ser removida. Quanto maior o número, mais ruído será removido – e mais não-ruído também. Experimente com números pequenos (e.g., 0, 0.05, 0.1, etc.) primeiro.

sox entrada.wav saída.wav noisered profile.txt 0.05

Se você tem um microfone problemático, você pode querer guardar o arquivo de profile para usos futuros (assumindo que o padrão de ruído produzido seja sempre o mesmo).

Se o arquivo de entrada para o noisered não for especificado ou for -, o sox lê o profile da stdin. Assim, você pode combinar o profiling e a redução em um pipeline:

sox entrada.wav --null trim 0 1 noiseprof | sox entrada.wav saída.wav noisered - 0.05

Para mais informações, consulte a manpage do sox.

2 comentários

Underground revolutions

2013-04-20 02:48 -0300. Tags: about

O blog system foi completamente reescrito.

Se você não percebeu a diferença, a operação foi um sucesso.

(Caso contrário, deixe seu bug report nos comentários (assumindo que os comentários estejam funcionando).)

O código-fonte será publicado assim que algumas bagunças forem eliminadas (ou assim que alguém pedir, o que vier primeiro).

[Update (23/04/2013): Bagunças não foram eliminadas. O código está disponível.]

3 comentários

So many parens

2013-04-17 17:17 -0300. Tags: comp, prog, lisp

Pode-se dividir as pessoas em dois grupos, segundo sua reação ao serem apresentadas a features novas em uma linguagem de programação:

(Na verdade o que provavelmente existe é um continuum de quanta justificativa é necessária para provocar a reação "whoa, que legal" em uma dada pessoa, but I digress.) O que acontece aí é que eu (que estou no primeiro grupo, mostly) freqüentemente acho complicado pensar em um exemplo de uso de uma feature que convença alguém do segundo grupo de que a feature é interessante. Por exemplo, a pessoa me pergunta "mas por que Lisp tem tantos parênteses?", e eu respondo "Macros!", e a pessoa "why macros?", e eu "code transformation!", e a pessoa "why code transformation", e eu "what do you mean, why?".

Pois, agora acho que encontrei um exemplo decentemente convincente. Meu TCC consiste, entre outras coisas, em desenvolver uma linguagem de programação e integrá-la ao ambiente de programação DrRacket. Para isso, estou implementando a linguagem em Racket, um descendente de Scheme, uma linguagem da família Lisp. Dentre as inúmeras bibliotecas que acompanham o Racket, estão a parser-tools/lex e parser-tools/yacc. Essas bibliotecas implementam funcionalidade equiparável aos famosos programas lex e yacc, que geram analisadores léxicos e sintáticos, respectivamente, a partir de arquivinhos de regras.

A diferença, entretanto, é que as parser-tools são implementadas como macros em Racket, de maneira integrada com o resto da linguagem. Por exemplo, ao invés de usar um programa separado que lê um arquivo meio-em-C, meio-em-lex e gera um arquivo em C, a parser-tools/lex provê uma macro lexer que, quando compilada, produz uma função que recebe uma stream e devolve a próxima token encontrada na stream. Algo do tipo:

(define example-lexer
  (lexer
    [expressão  valor-a-retornar]
    [expressão  valor-a-retornar]
    ...))

O parser funciona de maneira análoga. As macros, assim, permitem estender a linguagem com recursos sintáticos novos, sem que se tenha que usar ferramentas externas para fazer transformações de código (que potencialmente exigem reparsear o texto do programa, ao contrário do que acontece com as macros, que já recebem o programa pré-parseado como argumento). A vantagem da sintaxe uniforme (i.e., so-many-parens) é que os novos recursos adicionados mantêm a mesma cara do resto da linguagem, e que o parser do Lisp (que executa antes de a macro ser chamada) pode fazer o seu trabalho sem se preocupar com a semântica dos objetos que está parseando.

A conseqüência dessa integração é que o threshold a partir do qual vale a pena escrever uma transformação de código ao invés de fazer as coisas na mão é muito mais baixo em um Lisp do que em uma linguagem convencional. Por exemplo, certa vez eu estava escrevendo um typechecker/interpretador para uma linguagem simples. Logo que eu comecei a escrever, percebi que seria uma boa eu usar pattern matching para testar com que tipo de expressão o interpretador tinha se deparado. Por exemplo, ao invés de escrever algo do tipo:

;; Avalia a expressão 'expr' no ambiente de variáveis 'env'.
(defun evaluate (expr env)
  (cond 
    ;; Se a expressão for do tipo (+ x y), devolve x+y.
    ((eq (first expr) '+) (+ (evaluate (second expr) env)
                             (evaluate (third expr) env)))
    ;; Se for (if t x y), avalia o teste e a sub-expressão correspondente.
    ((eq (first expr) 'if) (if (evaluate (second expr) env)
                               (evaluate (third expr) env)
                             (evaluate (fourth expr) env)))
    ...))

eu queria poder escrever algo do tipo:

(defun evaluate (expr env)
  (match-case
    ((+ x y) (+ (evaluate x env) (evaluate y env)))
    ((if test then else) (if (evaluate test env)
                             (evaluate then env)
                           (evaluate else env)))
    ...))

Em 17 linhas (não muito bonitas, mas só porque eu não estava muito preocupado com isso quando as escrevi) de Common Lisp, eu implementei uma macro match-case e segui escrevendo o programa. Se ao invés disso eu tivesse que escrever um programa externo para transformar o código, provavelmente não teria valido a pena o esforço.

#<eof>.

9 comentários

One man's gambiarra is another man's technique

2013-04-17 14:52 -0300. Tags: comp, prog, ramble

Certa feita (e de repente o "fecha" do espanhol não parece mais tão estranho), não me lembro mais em que contexto nem para quem, eu mostrei um código deste tipo com listas encadeadas em C:

for (item = list;
     item && item->value != searched_value;
     item = item->next) ;

Que tanto quanto me constasse, era a maneira de se procurar um valor em uma lista em C. Para minha surpresa na época, a pessoa disse que isso era gambiarra. (Eu dificilmente escreveria isso com um while, porque eu tenho uma propensão terrível a esquecer o item = item->next no final do while. Ou será que eu tenho essa propensão por não estar acostumado a fazer esse tipo de coisa com while? But I digress.)

Uma situação similar foi quando eu mostrei para alguém na monitoria de Fundamentos de Algoritmos que dava para usar "tail-recursion com acumuladores" para iterar sobre uma lista. Algo do tipo:

(define (média lista)
  (média* lista 0 0))

(define (média* lista soma conta)
  (cond [(empty? lista) (/ soma conta)]
        [else (média* (rest lista) (+ soma (first lista)) (+ conta 1))]))

Que, novamente, é a maneira padrão de se fazer esse tipo de coisa em uma linguagem funcional (talvez com a definição de média* dentro do corpo de média, ao invés de uma função externa, mas whatever), e novamente a pessoa viu isso como uma "baita gambiarra". Provavelmente, o código imperativo equivalente (com atribuição de variáveis para manter a conta e a soma) é que seria visto como gambiarra por um programador Scheme.

Outro item de contenda é usar x++ em C para usar o valor atual de x em uma expressão e incrementá-lo na mesma operação (que é, bem, exatamente a definição do operador). Ok, usar um x++ perdido no meio de uma expressão grande pode ser fonte de confusão. Mas algo como:

var1 = var2++;

ou more likely:

item->code = max_code++;

não deveria ser nenhum mistério para quem conhece a linguagem.

A impressão que eu tenho é que as pessoas consideram "gambiarra" qualquer coisa feita de uma maneira diferente do que elas estão acostumadas. Eu mesmo já fui vítima desse efeito. No terceiro semestre eu escrevi um "banco de dados" em C (basicamente um programa que aceitava queries em uma linguagem facão, mantinha uns arquivos seqüencias e montava uns índices em memória) para o trabalho final da disciplina de Classificação e Pesquisa de Dados. Como o conteúdo dos arquivos binários era determinado em tempo de execução pelas definições das tabelas, o programa continha um bocado de casts, manipulações de ponteiros e outras "curiosidades" do C no código. Até então, tinha sido o programa mais complicado que eu tinha escrito. Durante um bom tempo, quando o assunto surgia, eu costumava comentar que esse código era "cheio de gambiarras" e coisas de "baixo-nível". Um belo dia, uns dois ou três semestres depois, eu resolvi dar uma olhada no código, porque eu já não lembrava direito o que ele fazia de tão mágico. Para minha surpresa, minha reação ao olhar as partes "sujas" do código foi algo como "pff, que brincadeira de criança". (E para minha surpresa, as partes "sujas" me pareceram bastante legíveis.)

(Um ponto relacionado é que quando estamos ensinando/explicando alguma coisa, devemos nos lembrar que o que nos parece óbvio e simples pode não o ser para a pessoa que tem menos experiência no assunto, mas esse não era o tema original do post.)

Agora dando uma olhada nesse código de novo, lembrei de uma outra coisa que eu tinha pensando quando o tinha revisto pela primeira vez: que certos trechos do código poderiam ter sido simplificados se eu tivesse usado um goto fail; da vida em pontos estratégicos. O que nos leva ao próximo tópico...

Considered harmful?

Entre muitos nesse mundo da programação existe um culto irracional às Boas Práticas de Programação™. Não me entenda mal; muitas técnicas e práticas ajudam a tornar o código mais legível e fácil de manter. O problema é quando as "boas práticas" se tornam regras fixas sem uma boa justificativa por trás.

Um exemplo é a proibição ao goto. A idéia básica é: "Alguns usos do goto produzem código ilegível; logo, o goto não deve ser usado." Isso é mais ou menos equivalente a "facas cortam os dedos; logo, não devemos usar facas". Ok, usar uma faca para desparafusar parafusos quando se tem uma chave de fenda à mão não é uma boa idéia. Mas usar uma chave de fenda para passar margarina no pão também não é. Verdade que em linguagens de mais alto nível do que C (com exceções e try/finally e labeled loops e what-not) é extremamente raro encontrar um bom motivo para se usar um goto; mas em C, há uma porção de situações em que um goto bem utilizado é capaz de tornar o código mais simples e legível.

Outro exemplo é o uso de TABLEs em HTML. O fundamento por trás da "regra" que "proíbe" certos usos de TABLE é evitar que TABLEs sejam usadas apenas para layout, com coisas que não têm a semântica de uma tabela. So far, so good. Mas no post (que eu nunca mais encontrei) pelo qual eu fiquei sabendo sobre "tableless tables" (i.e., o uso de CSS para aplicar o layout gerado pelas TABLEs do HTML a outros elementos), lembro que um indivíduo tinha postado um comentário semi-indignado dizendo que "usar CSS para simular uma tabela é só uma tabela disfarçada, e não deve ser feito". Ou seja, o camarada internalizou a noção de "usar TABLEs é errado", mas não o porquê.

Outra manifestação do "culto" são coisas do tipo:

Q: O que acontece se eu converter um ponteiro em inteiro e de volta em ponteiro?

A: Isso é uma péssima prática de programação e você não deveria fazer isso.

que eu vejo com alguma freqüência no Stack Overflow, i.e., o camarada não responde a pergunta, e ao invés disso se limita a repetir o mantra "Não Deve Ser Feito".

A freqüência com que eu vejo esse tipo de coisa me preocupa um pouco, na verdade. Acho que o princípio por trás disso é o mesmo que está por trás de zoar/condenar/excluir as pessoas que possuem algum comportamento "non-standard". Mas isso é uma discussão para outro post.

Appendix A

17.4: Is goto a good thing or a bad thing?

Yes.

17.5: No, really, should I use goto statements in my code?

Any loop control construct can be written with gotos; similarly, any goto can be emulated by some loop control constructs and additional logic.

However, gotos are unclean. For instance, compare the following two code segments:

do {                            foo();
        foo();                  if (bar())
        if (bar())                      goto SKIP;
                break;          baz();
        baz();                  quux();
        quux();
} while (1 == 0);               SKIP:
buz();                          buz();

Note how the loop control makes it quite clear that the statements inside it will be looped on as long as a condition is met, where the goto statement gives the impression that, if bar() returned a nonzero value, the statements baz() and quux() will be skipped.

Infrequently Asked Questions in comp.lang.c

_____

(O título do post é uma paráfrase de uma paráfrase de uma expressão idiomática.)

12 comentários

To tweet or not to tweet

2013-04-07 22:41 -0300. Tags: life, comp, web, privacy

Dracula: "I'm all screwed"

Richter: "I am the instrument of your doom"

Dracula: "Perhaps not... not yet"

Richter: "What!?!?!"

???: "Richter! You killed my father! Prepare to die!"

Richter: "ALUCARD!!!"

Alucard: "You can't know... you'll never know how it feels..."

* TUM *

Richter: "NOOOOOOOO!"

– Castlevania, Hélio's edition

Há pouco mais de um ano eu abandonei o Twitter (well, not quite; eu só parei de postar lá, na verdade) por conta de eles terem vendido o acesso à base de tweets para umas empresinhas de mineração de dados. Há pelo menos metade desse tempo eu venho remoendo essa decisão.

Assumptions

Na época eu usava o Twitter com "tweets protegidos", i.e., apenas as pessoas que eu autorizei que me seguissem podiam ver os meus tweets. Eu assumia assim que apenas uns poucos conhecidos veriam o que eu estava postando.

Não é bem assim que a coisa funciona. Embora tweets protegidos não sejam retweetáveis, nada impede alguém capaz de ler um tweet de copiá-lo e retweetá-lo na mão. Retweets são uma feature fundamental do Twitter; não faz muito sentido contar com que algo postado no Twitter não vá ser retweetado. Proteger os tweets não melhora muito a situação.

Abandonemos, pois, a noção de que existe "publicidade seletiva" no Twitter: assumamos que "o que você diz no Twitter pode ser visto no mundo inteiro instantaneamente" (palavras dos termos de serviço, as it happens). E por "o mundo inteiro", leia-se o mundo inteiro. Na época da matrícula da UFRGS nesse ano eu vi alguns retweets da @ufrgsnoticias que provavelmente não estavam nos planos dos indivíduos retweetados e que eu fiquei cogitando comigo mesmo se não poderiam causar algum problema para os mesmos. Essa "falta de privacidade" é, me parece, uma propriedade fundamental do serviço Twitter, não um erro da companhia Twitter que o fornece. Assim (me parece), não faz sentido condenar o Twitter por esse tipo particular de falta de privacidade, mas tão-somente aprová-la ou não (e utilizar ou não o serviço de acordo).

(Essa falta de privacidade na verdade é uma propriedade compartilhada com blogs e páginas pessoais. No Twitter isso é um pouco mais acentuado pela facilidade de retweetar posts alheios, mas não é fantasticamente diferente. Essa "publicidade fundamental" é diferente do vazamento de informações pessoais para terceiros que não é fundamental para o serviço e não é do interesse do usuário. Mais sobre isso adiante.)

Ok, tweets são públicos. "Tweet privado" é praticamente uma contradição em termos. Aceitemos esse fato e tomemos por princípio que o Twitter só serve para postar coisas que não nos importamos de compartilhar com o mundo (e.g., links para coisas interessantes, recomendações de filmes/livros, etc.). Entendido isto, podemos seguir usando o Twitter com a consciência limpa.

Heh, não

Faltam dois problemas a considerar. O primeiro é o uso que se faz dessa informação além da mera publicação mundial. Isso inclui a venda ao acesso da base de tweets para as empresinhas de data mining, que foi a causa original do meu desgosto pelo Twitter.

Na verdade, o Twitter sempre vendeu o acesso a tweets, mesmo antes desse incidente; a diferença é apenas que o Twitter costumava limitar o acesso aos tweets dos últimos trinta dias. (O fato de que eles já brincavam de vender tweets antes não torna o ato de vender o acesso à base inteira nem mais nem menos ético, mas vamos adiante.)

O segundo problema são as outras informações que caem nas mãos do Twitter além dos tweets, e que uso o Twitter faz delas. Vamos por partes.

A miserable little pile of non-secrets

Pois, o Twitter vende, e sempre vendeu, o acesso a (porções da) base de tweets. Esses tweets são públicos para início de conversa*. A diferença entre baixá-los você mesmo e comprar o acesso é que as APIs do Twitter impõem certos limites na busca de tweets (e.g., aparentemente existe um limite de 1500 tweets nos resultados de buscas por termos), e que provavelmente a base é oferecida em um formato mais conveniente de manipular. (* Tweets protegidos são outra história. Eles vivem em um limbo questionável: a política de privacidade jamais menciona "tweets protegidos", então pelo menos para mim não está claro se eles são considerados informação pública (e conseqüentemente comercializável), ou se estão inclusos entre os dados pessoais que o Twitter diz não vender (o que não impede que o Twitter seja comprado e com ele seus dados, but I digress).)

A possibilidade de data mining, assim, pode aumentar com o fato de que o acesso à base de tweets é comercializado, mas ela não deixa de existir sem essa comercialização. Na verdade, a Internet inteira é alvo de data mining. Google (a organização) e outros mecanismos de busca já podem facilmente explorar toda informação pública na Internet, independentemente do seu consentimento. A diferença de postar no Twitter é facilitar a vida do Twitter e parceiros, mas postar em qualquer outro local público da web (como o identi.ca, ou seu blog pessoal) tem o mesmo risco.

É uma propriedade da Internet que toda informação pública é (em geral) facilmente acessível. Uma conseqüência disso é que coisas que antes eram muito difíceis (e.g., catar todas as notícias sobre um certo tópico ou pessoa nos jornais dos últimos N anos) agora são viáveis, e, junto com todas as vantagens que isso proporciona, vêm certas conseqüências negativas para a privacidade das pessoas. A sociedade vai ter que dar um jeito de se adaptar a isso, mas não é um problema do qual se possa escapar trocando o serviço em que essas informações serão publicadas (assumindo que se pretenda publicar essas informações para quem quer que as queira ler).

Fica a questão de se é ok o Twitter ganhar dinheiros vendendo acesso aos meus posts sem me pagar nada. Essa questão é sugerida como um exercício para o leitor.

The actual secrets

O segundo problema são os outros dados além dos tweets. Esses dados podem ser divididos em duas classes: os dados "inevitáveis", i.e., aqueles que o Twitter necessariamente obtém a partir do uso do serviço; e os dados "evitáveis", i.e., aqueles que você pode evitar mandar com um pouco de cuidado.

Os dados inevitáveis incluem:

Os dados evitáveis incluem:

Fica a questão de se é "certo" usar um serviço que coleta dados que você acha que ele não deveria coletar só porque você consegue burlar a coleta. A resposta depende de quão idealista você está se sentindo hoje.

Outros comentários

Uma desvantagem de usar um serviço centralizado para publicação de informações (e.g., Twitter, Blogger, Wordpress, Facebook (ok, o Facebook tem inúmeros outros problemas, but I digress)) é que os "dados inevitáveis", tais como logs de acesso, ficam concentrados com uma única organização. Mesmo na arquitetura atual da Internet, em que acessar um serviço implica contar-lhe onde você está e possivelmente outros dados, a situação não é tão ruim se os dados estão espalhados entre vários servidores, o que dificulta sua exploração. (Seu provedor de acesso continua com um bocado de informação, entretanto.)

Por outro lado, uma rede social é mais útil quando um grande número de pessoas a usa; essa é uma vantagem de "todo o mundo" usar o Twitter, ao invés de cada um "roll their own" microblog. Porém, em teoria nada impede que cada um rolle seu own microblog e todos funcionem de maneira integrada, desde que eles usem um protocolo comum de comunicação.

µ.

Conclusão

A conclusão é que talvez eu volte a usar o Twitter no futuro próximo. Ou não.

3 comentários

Against Intellectual Monopoly

2013-04-04 15:12 -0300. Tags: freedom, book, copyright

In late 1764, while repairing a small Newcomen steam engine, the idea of allowing steam to expand and condense in separate containers sprang into the mind of James Watt. He spent the next few months in unceasing labor building a model of the new engine. In 1768, after a series of improvements and substantial borrowing, he applied for a patent on the idea, requiring him to travel to London in August. He spent the next six months working hard to obtain his patent. It was finally awarded in January of the following year. Nothing much happened by way of production until 1775. Then, with a major effort supported by his business partner, the rich industrialist Matthew Boulton, Watt secured an Act of Parliament extending his patent until the year 1800. The great statesman Edmund Burke spoke eloquently in Parliament in the name of economic freedom and against the creation of unnecessary monopoly – but to no avail.1 The connections of Watt’s partner Boulton were too solid to be defeated by simple principle.

Once Watt’s patents were secured and production started, a substantial portion of his energy was devoted to fending off rival inventors. In 1782, Watt secured an additional patent, made “necessary in consequence of ... having been so unfairly anticipated, by [Matthew] Wasborough in the crank motion.”2 More dramatically, in the 1790s, when the superior Hornblower engine was put into production, Boulton and Watt went after him with the full force of the legal system.3

During the period of Watt’s patents the U.K. added about 750 horsepower of steam engines per year. In the thirty years following Watt’s patents, additional horsepower was added at a rate of more than 4,000 per year. Moreover, the fuel efficiency of steam engines changed little during the period of Watt’s patent; while between 1810 and 1835 it is estimated to have increased by a factor of five.4

After the expiration of Watt’s patents, not only was there an explosion in the production and efficiency of engines, but steam power came into its own as the driving force of the industrial revolution. Over a thirty year period steam engines were modified and improved as crucial innovations such as the steam train, the steamboat and the steam jenny came into wide usage. The key innovation was the high-pressure steam engine – development of which had been blocked by Watt’s strategic use of his patent. Many new improvements to the steam engine, such as those of William Bull, Richard Trevithick, and Arthur Woolf, became available by 1804: although developed earlier these innovations were kept idle until the Boulton and Watt patent expired. None of these innovators wished to incur the same fate as Jonathan Hornblower.5

Ironically, not only did Watt use the patent system as a legal cudgel with which to smash competition, but his own efforts at developing a superior steam engine were hindered by the very same patent system he used to keep competitors at bay. An important limitation of the original Newcomen engine was its inability to deliver a steady rotary motion. The most convenient solution, involving the combined use of the crank and a flywheel, relied on a method patented by James Pickard, which prevented Watt from using it. Watt also made various attempts at efficiently transforming reciprocating into rotary motion, reaching, apparently, the same solution as Pickard. But the existence of a patent forced him to contrive an alternative less efficient mechanical device, the “sun and planet” gear. It was only in 1794, after the expiration of Pickard’s patent that Boulton and Watt adopted the economically and technically superior crank.6

The impact of the expiration of his patents on Watt’s empire may come as a surprise. As might be expected, when the patents expired “many establishments for making steam-engines of Mr. Watt's principle were then commenced.” However, Watt’s competitors “principally aimed at...cheapness rather than excellence.” As a result, we find that far from being driven out of business “Boulton and Watt for many years afterwards kept up their price and had increased orders.”7

In fact, it is only after their patents expired that Boulton and Watt really started to manufacture steam engines. Before then their activity consisted primarily of extracting hefty monopolistic royalties through licensing. Independent contractors produced most of the parts, and Boulton and Watt merely oversaw the assembly of the components by the purchasers.

In most histories, James Watt is a heroic inventor, responsible for the beginning of the industrial revolution. The facts suggest an alternative interpretation. Watt is one of many clever inventors working to improve steam power in the second half of the eighteenth century. After getting one step ahead of the pack, he remained ahead not by superior innovation, but by superior exploitation of the legal system. The fact that his business partner was a wealthy man with strong connections in Parliament, was not a minor help.

Was Watt’s patent a crucial incentive needed to trigger his inventive genius, as the traditional history suggests? Or did his use of the legal system to inhibit competition set back the industrial revolution by a decade or two? More broadly, are the two essential components of our current system of intellectual property – patents and copyrights – with all of their many faults, a necessary evil we must put up with to enjoy the fruits of invention and creativity? Or are they just unnecessary evils, the relics of an earlier time when governments routinely granted monopolies to favored courtiers? That is the question we seek to answer.

Against Intellectual Monopoly

O livro completo está disponível para download. É compridinho (ainda estou no começo), mas vale a pena.

3 comentários

Main menu

Posts recentes

Tags

comp (71) life (26) unix (26) prog (25) random (22) about (18) mundane (18) lang (17) mind (13) web (13) img (10) rant (9) privacy (8) bash (7) esperanto (7) ramble (5) pldesign (5) conlang (5) misc (4) home (4) book (4) freedom (4) copyright (4) lisp (4) music (3) kbd (3) politics (3) film (3) security (2) poem (2) physics (2) worldly (2) editor (2) android (2) network (2) cook (2) c (2) academia (2) wrong (2) php (2) perl (1) pointless (1) mestrado (1) shell (1) audio (1) kindle (1)

Elsewhere

Quod vide


Copyright © 2012-2014 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.