Arc

February 11th, 2008 § 10 comments § permalink

Arc’s Out:

Arc is still a work in progress. We’ve done little more than take a snapshot of the code and put it online.

Como eu sou famoso e anunciamos há um bom tempo, resolvi colocar a porcaria da versão no ar assim mesmo.

Why release it now? Because, as I suddenly realized a couple months ago, it’s good enough.

É uma porcaria mas minha fama vai garantir muita cobertura mesmo que o código seja um desastre. Pode ter certeza que muita gente vai falar bem.

I worry about releasing it, because I don’t want there to be forces pushing the language to stop changing.

Eu não vou mexer mais. E se você for otário o bastante para querer usar, lembre-se que não tem suporte, não tem documentação. Em suma, se vire.

Which is why, incidentally, Arc only supports Ascii. MzScheme, which the current version of Arc compiles to, has some more advanced plan for dealing with characters. (…) But the kind of people who would be offended by that wouldn’t like Arc anyway.

Como eu não entendo lhufas sobre qualquer outra conjunto de caracteres que não seja meu precioso ASCII–que foi o único que eu aprendi quarenta anos atrás, não vou implementar nada nisso. Na-na-ni-na-não. Ah, e foi por isso que o Yahoo! reescreveu o meu programa todo de novo. Losers!

Why? Because Arc is tuned for exploratory programming, and the W3C-approved way of doing things represents the opposite spirit.

Eu também não tenho a menor idéia de como essas tecnologias e padrões modernos como XHTML e CSS funcionam e não vou aprender. E tenho raiva de quem sabe também. Aliás, eu já expliquei porque o Yahoo! teve que reescrever o programa que comprou de mim?

Tables are the lists of html. The W3C doesn’t like you to use tables to do more than display tabular data because then it’s unclear what a table cell means.

Eu já disse que não entendo nada de HTML?

So experience suggests we should embrace dirtiness. Or at least some forms of it; in other ways, the best quick-and-dirty programs are usually quite clean.

Olhe! Um lixão! Vamos nos divertir?

Arc tries to be a language that’s dirty in the right ways. It tries not to forbid things, for example. (…) For now, best to say it’s a quick and dirty language for writing quick and dirty programs.

Eu perdi tanto tempo com essa porcaria e é justo que o mundo compartilhe a minha dor. Basic, prepare-se. Agora é a vez do Arc.

Akismet operando

February 11th, 2008 § 0 comments § permalink

Habilitei o Akismet no blog porque o número de comentários spam está aumentando muito.

Já reparei, entretanto, que ele andou engolindo alguns comentários que normalmente teriam passado pela moderação do WordPress. Como o Akismet não envia um e-mail avisando de moderação–ou pelo menos não achei onde isso fica no mesmo–é provável que esses comentários demorem um pouco mais para aparecer. Em todo caso, se o seu comentário demorar demais, mande um e-mail para mtblog (arroba) reflectivesurface.com e eu resolvo.

Pão de Cast S02E04 – Iárru!

February 11th, 2008 § 0 comments § permalink

Semana de pós-carnaval e um novo Pão de Cast para ajudar a curar a ressaca de tanto que os ouvintes vão berrar depois de nossas opiniões insanas. Agora de volta com o Luiz Rocha depois da saída honrosa do Luiz Pedra. :-)

Os assuntos discutidos são:

Divirtam-se!

Fim de carreira

February 10th, 2008 § 6 comments § permalink

Chegando nos trinta é inevitável pensar sobre a carreira e sobre os rumos futuros da vida profissional. Agora que eu estou envolvido plenamente na minha empresa, a carreira da empresa e a minha própria carreira estão meio que se misturando e pensar no futuro de uma implica necessariamente em relacionar os rumos prováveis que as duas seguirão.

Ironicamente, quando eu comecei a minha carreira de programação, eu não tinha a menor vontade, idéia ou planos para estar na posição em que estou, mais administrativa do que técnica no dia-a-dia. E, embora eu seja obrigado, por força daquilo que quero e pretendo fazer, a me desenvolver nesse sentido, eu fico me questionando sobre como isso impacta o meu futuro como programador.

Programação é uma coisa engraçada. É um das profissões que degradam com a idade. Não que o programador ou analista perca a sua velocidade ou proficiência. É mais uma percepção do mercado de que programadores jovens são mais capazes de produzir com a velocidade desejada e exercer as longas horas teoricamente necessárias. Obviamente, isso tudo é simplesmente um efeito do passo rápido da tecnologia e facilmente controlável em termos técnicos mas poucas empresas percebem ou aceitam isso.

A minha idéia, quando entrei no mercado, envolvia vinte cinco anos de carreira. Ou seja, começando com aproximadamente vinte anos (comecei mais cedo na verdade) e parando por volta dos quarenta em cinco. Não por não gostar de programar, mas por preferir uma estratégia de saída mais controlada. Embora me atualizar nunca tenha sido um problema e eu–pelo menos até onde percebo–continuo atualizado dentro da áreas nas quais trabalho, a minha vontade era uma finalização formal de carreira que partisse de mim.

Como ainda faltam quinze anos para isso–considerando que eu vou ultrapassar os vinte e cinco anos previstos–ainda há um bom tempo pela frente para decidir o que fazer com a empresa e com o impacto que isso vai ter nessa meta.

Trabalhar do outro lado da equação tem vantagens enormes, é claro, e isso pode significar uma coisa bem diferente daqui a alguns anos se os planos atuais continuarem a se desenrolar de maneira apropriada. No momento, entretanto, eu confesso que a carreira de Letras me parece mais agradável.

Enfim, por enquanto é uma questão de vamos ver no que dá. Mas eu ainda me surpreendo como as guinadas aparecem no caminho inesperadamente e você se vê em uma posição totalmente diferente da que esperava. No momento, não estou achando nada ruim as perguntas que eu estou sendo obrigado a me fazer.

Correndo (ou não) com o leopardo

February 9th, 2008 § 8 comments § permalink

Tudo bem, esse foi um péssimo título. Desconsidere.

Acabei de instalar o Mac OS X 10.5, vulgo Leopard, na minha máquina e confesso que não estou tendo muito sucesso no começo. Depois de todas atualizações, configurações, e por aí vai, o resultado é que o processo de boot está bem mais lento, o wirelesss está falhando esporadicamente, e o Quicksilver demora décadas para iniciar.

Em contrapartida, o XCode 3 é uma ferramenta incrível, as adições ao sistema são bem interessantes e o Safari está turbinado. Estou ainda configurando tudo do jeito que gosto mas imagino que vou precisar de reinstalar uma segunda vez para realmente deixar tudo legal depois de estragar completamente a instalação. Se bem que nesse ponto meu pragmatismo pode falar mais alto e eu posso acabar deixando tudo como está.

De qualquer forma, vamos ver se tanto hype escutado nos últimos tempos sobrevive à realidade do dia a dia.

OpenID e os gigantes

February 7th, 2008 § 2 comments § permalink

A notícia de hoje, que eu só vi agora depois de ficar quase todo o dia enfiado em um projeto e sem acesso, é que os grandes nomes da indústria–Google, Microsoft, Yahoo!, IBM e Verisign–entraram para a OpenID Foundation. Considerando que essas empresas representam a maior parte dos usuários de sistemas múltiplos onde um signon único seria mais do que interessante, parece que o OpenID realmente vai decolar esse ano.

É claro que, como já tinha sido comentando em um Pão de Cast passado, de todos os implementadores acima, somente o Google já permite que alguns de seus serviços sejam acessados com uma identificação externa, ou seja, funciona como um relying party que, afinal de contas é o motivo da história toda. Enquanto as empresas insistirem em somente fornecer o provimento de identidades, a confusão entre os potenciais usuários só aumentará.

Mesmo assim, o fato de que todas essas empresas estão procurando fazer parte de iniciativas de portabilidade já é uma enorme mudança que eventualmente vai representar o fim de muitos jardins fechados na Web.

Conceitos de Programação: Big O Notation

February 7th, 2008 § 8 comments § permalink

Este é o terceiro artigo em uma série sobre conceitos de programação. O primeiro falava sobre Lazy Evaluation e como simular isso em uma linguagem sem suporte nativo ao conceito de uma forma simples mas funcional. O segundo falava sobre Tail Recursion e como aproveitar isso em linguagens que implementam a característica.

Antes de começar o artigo, um aviso: o tratamento que eu estou dando aos assuntos aqui é informativo, com a intenção de incentivar os leitores que desconhecem ou querem aprender sobre o assunto em questão a procurar mais sobre o assunto. Como tal, podem existir erros nos mesmos, derivados da minha própria incompreensão de alguns pontos. Nesse caso, como sempre, a parte de comentários está aberta. Aceito tanto sugestões como correções. Isso vale para todo e qualquer artigo da série. Dito isso, podemos continuar.

Neste terceiro artigo, vamos falar um pouco sobre Big O Notation, ou Notação O, que, em teoria da computação é usada para descrever como o tamanho da entrada fornecido a um algoritmo qualquer afeta os recursos que o mesmo utiliza, sejam estes de memória ou tempo de execução.

Conhecer esse tipo de informação sobre um algoritmo é a base de qualquer otimização que possa ser feita sobre o mesmo. Não só para entender como o mesmo opera em termos de eficiência geral mas também para decidir corretamente quando for necessário sacrificar alguma aspecto de performance ou complexidade em favor de outro. Isso vale tanto para uso de CPU, memória como para rede, disco e qualquer outro recurso similar.

A Notação O, na verdade, é uma classe inteira de notações. Nesse artigo vamos cobrir somente uma parte no que tange à análise de complexidade de um algoritmo.

Complexidade versus performance

Antes de prosseguirmos, uma distinção deve ser feita aqui.

Performance é uma medida de quanto dos recursos disponíveis um algoritmo usa. Isso depende tanto do código quanto da máquina onde o mesmo está rodando.

Complexidade, por outro lado, é como o algoritmo escala, ou seja, o que acontece quando mais e mais dados são passados ao mesmo? Complexidade afeta performance, obviamente, mas o converso não é verdadeiro.

Sendo assim, a Notação O descreve a complexidade do algoritmo e não sua performance. Isso será visto mais adiante com um exemplo.

Entendendo a notação

Como mencionado acima, o principal objetivo da notação O, no que tange à descrição de complexidade de um algoritmo é explicar de maneira sucinta como o tamanho do problema afeta o número de operação necessárias para executar o mesmo. Operações podem ser atribuições, comparações, cálculos númericos, leituras, escritas, e assim por diante, tomadas em unidade.

A notação não descreve o número exato de operações, mas está interessada em casos específicos de operação. Em outras palavras, ela é igualmente válida para descrever o melhor caso, o pior caso, ou o caso médio de um algoritmo qualquer.

Para um dado problema, podemos ter as seguintes situações comuns:

Constante: O(1), ou ordem 1
Isso significa que o uso de recursos é constante seja qual for o tamanho da entrada. Obviamente, esse é o melhor nível de complexidade possível.
Linear: O(n), ou ordem n
Isso significa que o uso de recursos é proporcional ao tamanho da entrada.
Logarítmico: O(log n), ou ordem logaritmo n
Isso significa que o uso de recursos varia em proporção logarítmico ao tamanho da entrada.
Quadrático: O(n2), ou ordem n ao quadrado
Isso significa que o uso de recursos varia em proporção exponencial ao tamanho da entrada.

Para colocar isso em contexto, alguns exemplos:

  • Determinar se um número é par ou ímpar é O(1)
  • Encontrar um item em uma lista ordenada por busca binária é O(log n)
  • Resolver o problema do caixeiro viajante por força bruta é O(n!)

A importância da escolha

Para entender a importância da escolha correta de implementação, podemos usar um exemplo concreto:

O famoso Quicksort, em seu caso típico é O(n log n). Em seu pior caso, O(n2). Isso para tempo de execução. É claro que isso depende de uma implementação correta do mesmo, mas em qualquer implementação correta, essa é a complexidade.

Em termos de uso de memória, porém, para um implementação correta é sempre O(n log n), a menos que a execução seja in-place, caso qual o uso de memória é O(1). Em outras palavras, uma mudança de implementação aqui, mesmo correta, pode ter uma impacto enorme em um dos recursos usados pelo algoritmo.

O caso converso também é verdadeira para a escolha. Há momentos em que você deve saber balancear as expectativas. Se você descobre que o seu algoritmo é O(n3) e que existe uma forma de transformá-lo em O(n2) mas que isso vai tomar um ano e tornar o código incompreensível, não faz muito sentido ganhar com a redução por maior que ela aparentemente seja.

Digo aparentemente, porque você pode descobrir que para o tamanho de sua entrada, a complexidade não faz diferença. Se o seu conjunto de entrada é distribuído demais para que o algoritmo caia no melhor caso, faz sentido explorar o pior caso, por exemplo.

O que não é trivial

Obviamente, a equação que determinada a eficiência pode expressar qualquer relação. Entretanto, ela não usa constantes ou termos de ordem inferior porque para à medida que n aumenta, o impacto desses termos se torna insignificante. Para entender isso, considere o Bubblesort, um dos piores algoritmos possíveis para ordenação (quase um Bogosort):

A implementação trivial em Ruby é a seguinte:

def bubblesort(*items)
  loop do
    swapped = false
    for i in (0..items.size - 2)
      if items[i] > items[i + 1]
        items[i], items[i + 1] = items[i + 1], items[i]
        swapped = true
      end
    end
    break unless swapped
  end
  items
end

Essa implementação é O(n2). Você pode reparar que ela gasta n * (n + 1) passagens em média, ou seja, O(n2 + n), o que é o mesmo que dizer O(n2).

Agora, suponha que a implementação seja melhorada:

def bubblesort(*items)
  l = items.size - 1
  loop do
    swapped = false
    l -= 1
    for i in (0..l)
      if items[i] > items[i + 1]
        items[i], items[i + 1] = items[i + 1], items[i]
        swapped = true
      end
    end
    break unless swapped
  end
  items
end

Você verá que agora o algoritmo faz a metade das comparações, porque para antes de chegar aos números que já foram ordenadas. O número de operações agora é n + (n-1) + (n-2) + … + 1, que dá n(n + 1) / 2. Como demonstrado acima, entretanto, isso ainda é O(n2).

A razão é que a entrada ainda influencia exponencialmente a execução. Se você introduzir computar o número de computações feitas verá que esse número cresce exatamente da forma descrita na notação.

Com isso em mãos, uma forma rápida de descobrir quão bem um algoritmo escala é plotar a equação que determina sua complexidade. O crescimento do gráfico mostra isso de forma bem visual. A ordem é:

Determinando complexidade

A maneira de determinar complexidade é verificar quantas operações simples o algoritmo precisa fazer antes de terminar sua execução.

Tome os loops abaixo, por exemplo:

for i in (0..n)
end

for i in (0..m)
end

A complexidade do primeiro é O(n) e a do segundo é O(m). A de ambos é O(n + m), que é o mesmo que O(max(n, m)).

Veja agora o caso abaixo:

for i in (0..n)
  for j in (0..n)
  end
end

A complexidade agora é O(n * n), ou O(n2).

A maioria dos casos pode ser estimada igualmente, verificado as condições que limitam cada caso. Na pior das hipóteses, é possível instrumentar a função e depois lançar os resultados em um programa que gere um gráfico do resultado colhido. Veja o resultado do pior caso da ordenação descrita anteriormente:

Computações versus Itens

Conclusão

Saber estimar ou pelo menos procurar a complexidade de um algoritmo é fundamental para qualquer programador. Qualquer tipo de otimização mais pesada é irrelevante sem isso. O maior problema está no fato de que certas otimizações são contra-intuitivas como demonstrado acima. Entender as variações se torna, então, a necessidade mais premente para otimizar de maneira adequada.

Obviamente, em muitos casos, uma otimização simples pode ser suficiente para os propósitos do código. Mesmo assim, uma análise um pouco mais profunda pode render benefícios inesperados.

Conspirações

February 6th, 2008 § 5 comments § permalink

Como diriam os nossos avós, um é normal, dois é coincidência, três é conspiração. Essa história dos cabos cortados no Oriente Médio está ficando cada vez mais estranha.

Os primeiros dois sofreram algum tipo de dano não especificado no último dia do mês passado. Primeiro se pensou que âncoras de navios passantes tivessem tido alguma coisa a ver com a história mas agora não se sabe mais se isso é verdade. O terceiro e o quarto apareceram danificados menos que uma semana depois e hoje apareceu um quinto para completar a bagunça. As grandes empresas, segundo as notícias, voltaram ao ar rapidamente usando rotas de backup mas o resto da população, obviamente, não tem a mesma sorte.

Com cinco cabos atendendo a uma região muito complicada tendo problemas em um período tão curto, a metralhadora de teorias malucas está dominando os blogs e mídia tradicional. Seguindo os links, as teorias são cada vez mais loucas: os tradicionais homenzinhos verdes; os Estados Unidos; o Irã, cuja velocidade de acesso parece ter melhorado durante o problema; e por aí vai.

Para uma análise mais séria, entretanto, vale a pena a leitura e comentários do Steve Bellovin. Pelo que ele diz, a causa deve ser comum porque os problemas estão acontecendo em cabos bem próximos. Eu estou curioso para ver o que vão dizer em definitivo, seja lá quem é responsável pelos tais cabos. Se tudo sumir sem explicação, aí é que vai ser realmente curioso.

Por outro lado, vai ver que isso tudo não passa de uma enorme cascata de eventos Murphy. :-)

Planeta Superfície Reflexiva

February 5th, 2008 § 3 comments § permalink

Depois de tanto ouvir o Sam Ruby falar em seu projeto Venus, resolvi experimentar e criar uma instalação para mim. O resultado é o Planeta Superfície Reflexiva que agrega todos os feeds que eu leio em um único “rio de notícias”. Gostei da forma como ficou e eventualmente isso pode até substituir o meu uso do Google Reader.

Uma parte interessante do Planeta é a descoberta automática de memes no que eu estou lendo. Isso permite prestar mais atenção ao que muita gente está lendo e comentando no momento. Outro bom efeito colateral foi perceber quais blogs assinados estão inativos ou com feeds redirecionados ou coisas similares.

Eventualmente eu quero experimentar com uma planeta secundário com os feeds de comentários dos blogs também para ver no que dá.

Obviamente, sendo esses os meus próprios feeds de interesse, imagino que não vão ser de muita utilidade para os outros. Mas, no caso raro de alguém se interessar, o período de atualização é de duas em duas horas. No momento, a propósito, como eu acabei de instalar, itens antigos estão aparecendo na frente de outros mais novos mas isso se resolve em alguns ciclos de atualização.

Elegendo eleitores

February 5th, 2008 § 0 comments § permalink

Hoje é a Super Terça-Feira nos Estados Unidos, o dia em que o maior número de estados americanos seleciona os delegados que votarão na indicação dos candidatos de seus partidos. Entre os países ditos democráticos, os Estados Unidos provavelmente possuem o mais estranho sistema indireto de eleição onde, apesar de existir voto individual, a eleição é realmente para eleger os eleitores.

Eu estou acompanhando com curiosidade as eleições desse ano mais por causa dos candidatos democratas do que por qualquer outra coisa. Vai ser interessante testar a disposição americana agora em escolher entre um negro e uma mulher para o candidato democrata e depois testar isso contra o candidato republicano.

Para quem também está interessado, o blog O Biscoito Fino e a Massa vai cobrir ao vivo os eventos de hoje.

Where am I?

You are currently viewing the archives for February, 2008 at Superfície Reflexiva.