Planet Antipodas

A(x) = − x

Hasking

Comments off

Today I’ve decided to learn Haskell and improve my skills on Functional Programming.

The first thing I did were create a new word: “Hasking”, that is the join of Hacking + Haskell.

I’m having so much fun doing some hackings and silly jokes this weekend.

Novidades

Comments off

Caramba, faz bastante tempo que não posto nada por aqui.

A primeira novidade é que temos uma nova antipoda: Anne Kelly

Acho que é legal também mantê-los informados a respeito do que anda acontecendo na minha vida.

Estou trabalhando atualmente na Ci&T Business Agility uma empresa que acredita em Lean IT e que aplica SCRUM em todos os seus projetos. Para mim, RUP addicted, foi uma grande mudança no modo de pensar e trabalhar.
Diga-se de passagem, estou adorando a experiência e acho que devia ter experimentado Agile antes. =P

Na semana passada participei do TDC 2010. O evento foi simplesmente incrível! O que mais me agradou foi o painel sobre linguagens de programação no .NET Framework / Mono e o lado B com os hackers do projeto Monobrasil.

Depois do evento, o que ficou foram as metas de estudo, dentre elas:

  • Melhorar meus skills de Boo e aprender melhor como utilizar as syntactic macros para extender a linguagem
  • Estudar matemática discreta e linguagens funcionais (Estava estudando Erlang, mas me recomendaram estudar Haskell)
  • Estudar Lógica Bayesiana

Aguardem novidades!

Memoization

Comments off

A memoized function "remembers" the results corresponding to some set of specific inputs. Subsequent calls with remembered inputs return the remembered result rather than recalculating it, thus eliminating the primary cost of a call with given parameters from all but the first call made to the function with those parameters. - Memoization

Memoiwhat?!

Foi isto o que eu pensei quando eu li essa palavra. Definitivamente eu já havia visto ela antes mas, como nunca tinha visualizado um exemplo prático, acho que eu nunca havia realmente entendido o conceito. Minha inspiração e busca pela técnica veio deste post do Elemar Jr.

Bom, de acordo com o Wikipedia, Memoization é uma técnica de programação que visa diminuir o tempo de execução de chamadas de função através da memorização dos resultados de chamadas anteriores.
Talvez seja difícil visualizar isto apenas com palavras mas, te garanto que os exemplos abaixo irão facilitar e MUITO o entendimento.

Exemplo

O primeiro exemplo que eu trago é o da série de Fibonacci. O exemplo é bem didático e de certa forma, acadêmico. Sinta-se a vontade (na verdade, faça isto) para copiar o conteúdo e colar no Visual Studio para ver o código rodando.

O primeiro código mostra a nossa classe e seu método main. Eu, particularmente, apenas criei um console application para brincar com o código.

public class Memoizer
    {
        static long g_Steps;
        static void Main(string[] args)
        {
            for (int i = 0; i <= 45; i++)
            {
                g_Steps = 0;
                Stopwatch sw = Stopwatch.StartNew();
                int fib = FibonacciWithoutMemory(i);
                sw.Stop();

                Console.WriteLine(
                    "Fibonacci({0}) = {1:###,###,###,##0} [{2:###,###,###,##0} steps] [{3:0.###} seconds]",
                    i, fib, g_Steps, (float)sw.ElapsedMilliseconds / 1000);
            }

            Console.ReadLine();
        }
}

Explicações sobre o código:

  • O g_steps é o nosso contador de passos executados na série. Temos um loop que irá calcular o valor da série dado o valor de i que varia de 0 a 45. Um contador irá contar o tempo gasto para executar a série, que é recursiva.

Vamos agora ao nosso primeiro método que não utiliza Memoization:

static int FibonacciWithoutMemory(int n)
        {
            g_Steps++;

            if (n < 2)
                return n;
            else
                return FibonacciWithoutMemory(n - 1) + FibonacciWithoutMemory(n - 2);
        }

O exemplo é bem simples. Caso n seja menor que 2, o retorno é o próprio n. Caso contrário, a soma do valor corrente é a soma dos valores anteriores, ou seja, valor corrente = (valor da posição corrente - 1) + (valor da posição corrente - 2).

Esta é a imagem da execução do nosso código:

Usando de exemplo o Fibonacci(40), temos que o último valor gerado pela série é 102.334.155 em [331.160.281 passos] levando [5,425 segundos].
É possível notar que, o número de passos de Fibonacci(40) é exatamente a soma de passos do Fibonacci(39) + Fibonacci(38).

Outra coisa a se notar é que a partir do Fibonacci(25) a complexidade aumenta pois, os tempos agora estão levando mais que 0 segundo para serem executados.

Baseado no nosso conhecimento, sabemos que o resultado de (45) = (44) + (43), correto? Então vamos à solução.

Trocando processamento por armazenamento

Como assim? Bom, no fundo, é nisso que a técnica se baseia. Todo contexto deve ser levado em consideração, é claro, mas acho que armazenamento (desde que não seja em disco) não é tão caro e, neste exemplo, será MUITO mais rápido do que processamento.

Vamos fazer uma pequena mudança por aqui. Vamos trocar no nosso método main esta chamada.
Ao invés de:

int fib = FibonacciWithoutMemory(i);

Usaremos:

int fib = FibonacciWithMemory(i);

Agora adicionamos uma variável e um novo método:

       static Dictionary<int,int> g_results = new Dictionary<int,int>();

        static int FibonacciWithMemory(int n)
        {
            g_Steps++;

            if (n < 2)
                return n;
            else
            {
                if (g_results.ContainsKey(n)) return g_results[n];
                var result = FibonacciWithMemory(n - 1) + FibonacciWithMemory(n - 2);
                g_results.Add(n, result);
                return result;
            }
        }

Simples explicação por aqui:

  • Utilizamos g_results para armazenar os valores calculados. Antes de executar a recursividade, buscamos no dicionários se aquele valor já foi preenchido. Aqui estamos matando todo o processamento das chamadas anteriores pois, elas estão armazenadas no dicionário.

Aqui é a imagem do nosso método otimizado:

O que devemos levar em consideração neste exemplo:

  • Todos os valores são retornados abaixo de 1 milisegundo.
  • O número de passos necessários será sempre 3 (depois dos valores 0 e 1).

O algoritmo agora é O(1), no entanto, ele traz as seguintes consequências:

  • O algoritmo agora usa memória que só será liberada quando o AppDomain for liberado. O uso da memória é O(n).
  • Embora usar o Dictionary facilite o trabalho, ele talvez não seja a melhor solução porque ocupa mais memória do que o número de itens que ele contém.
  • Considerando soluções com acessos simultâneos, o Dictionary não dá garantia de thread-safe.

Há uma possível solução para este problema conhecida como closure (fica para o próximo post).

Exemplo pratico de Memoization

Lembro que houve um problema em um sistema onde, pareando com o Glauco, chegamos à solução de um problema de performance utilizando Memoization. O código ficou bem legal e bem funcional no contexto. Não tenho mais acesso ao código, no entanto, tenho algo bem parecido que pode dar uma idéia:

static void Main(string[] args)
        {
            var mf = MemoizeMe<int,int>(FunctionThatIsCalledALotOfTimes);

            mf(3); //demora 3 segundos pra executar
            mf(3); //executado na hora
        }

static int FunctionThatIsCalledALotOfTimes(int value)
        {
            System.Threading.Thread.Sleep(value * 1000); // aqui viria algo com processamento absurdo
            return (value * 1000);
        }

static Func<T,R> MemoizeMe<T,R>(Func<T,R> function)
        {
            Dictionary<Func<T,R>, Dictionary<T,R>> cache = new Dictionary<Func<T,R>, Dictionary<T,R>>();

            return delegate(T input)
            {
                if (!cache.ContainsKey(function))
                {
                    cache.Add(function, new Dictionary<T,R>());
                    cache[function][input] = function(input);
                }
                else
                {
                    if (!cache[function].ContainsKey(input))
                        cache[function].Add(input, function(input));
                }

                return cache[function][input];
            };
        }

Outras linguagens

Enquanto os exemplos demonstrados foram em C#, eu busquei um pouco de Memoization em outras linguagens de programação.
Ruby tem um módulo de memoization no seu core.
Haskell faz isto automaticamente para otimizar suas chamadas.
Common Lisp tem uma biblioteca pronta pra utilizar.

Novo blog

Comments off

Hello new world!

Hackeando GLib e GObject e me deparei com o seguinte pacote do Debian: libgtk2.0-cil-dev .

Me perguntei na hora: “Que diabos é esse cil que está ai no meio?”

Dei uma pesquisada e encontrei a Debian CLI Policy

Se você é programador, acho que vale a pena dar uma lida e entender o que é, e principalmente o que não é ‘.NET”.

Muitas vezes coisas sem explicação acontecem em nossa vida, seja profissional ou pessoal. Entendo isto como a idéia que o Universo não quer que isto aconteça, logo, não adianta tentar porque NÃO vai acontecer. No entanto, continuamos tentando e quem sabe, iremos vencer em algum momento?

Pensando nisto, li a frase de um amigo no google talk e ri muito. E não é que o Universo está vencendo mais uma?

Programming today, is a race between software engineers striving to build bigger and better idiot-proof programs, and the Universe trying to produce bigger and better idiots. So far, the Universe is winning.

Valeu meu dia, Cunha.

Pra começar a explicar este tópico "polêmico", devemos dar nome aos bois.

No caso, quem é o time?
Bom, quando começamos a tentativa de aplicar XP na equipe, eu, Glauco e Rodrigo trouxemos mais a tona este conceito de time. Éramos em torno de 9-11 pessoas todas em uma mesma sala, mas não agíamos em equipe. Não éramos um time, apenas marionetes na empresa.

Queríamos saber o que cada um estava fazendo, como estava fazendo e como podia melhorar. Queríamos sentar e discutir soluções, resolver problemas todos juntos e pra isto tinhamos que ter uma equipe em que todos eram contribuidores para o crescimento e gerenciamento da equipe.

Bom, começamos melhorando o nosso ambiente de trabalho e o nosso quadro de atividades teve um dia atípico, rs..
Quadro das Desavenças
Infelizmente, o quadro teve que ser apagado por problemas com as influências externas.

Este foi apenas um dos "baby steps"¹ que decidimos tomar. Começamos a praticar pair programming, temos slides prontos para explicar e aplicar TDD e até começamos a montar um ambiente com CI.

Acredito que a decisão mais importante que tomamos foi trazer o cliente como parte da equipe. Temos feito feedback constante e entregas o mais rápido possível. Desta forma, temos recebido feedback agradável e começamos a receber um pouco dos frutos desta nossa mudança, ganhamos dois outros projetos (pequenos, mas é o que a empresa quer, né?) e acredito que temos mais pela frente.

(Recomendo: http://improveit.com.br/xp/)
Bom, parece o paraíso, né?

Agora vamos nomear as influências externas. Este é um nome bem genérico, afinal, tudo e todos fora da equipe é visto como externo. A diferença está na palavra influência.
Pra começar, voltamos à idade da pedra e tivemos boa parte da nossa internet cortada. Não foi apenas a gente, toda a empresa na verdade, só que isto gera um desconforto geral pois, nem todos são robôs que trabalham 8hr por dia sem parar, né? Como que eu poderia vir aqui e desabafar um pouco, perdendo aí 20-30 minutos do meu dia mas, aliviando minha mente e me relaxando pra queimar mais neurônios? Este foi apenas um exemplo, eu estou constantemente no GTalk tirando dúvidas e também perguntando a outras pessoas as minhas dúvidas.

Enfim, esta influência veio de dentro da própria empresa, o que é pior ainda. Infelizmente a empresa ainda tem uma visão muito pequena do mundo que existe ao redor e que 99% do mundo hoje vive conectado.
Outro tipo de influência que tem sido muito ruim é a distribuição da equipe através da necessidade dos gerentes. É um projeto X começar a pegar fogo que começa a mover o pessoal de seus projetos e atrapalha o andamento do antigo projeto. Daqui a pouco, ele vai começar a pegar fogo e este é um ciclo que nunca irá terminar.

Pra finalizar esta história, eu e o Glauco chegamos a um consenso: Empresas que só se importam com dinheiro, estão fadadas a ter profissionais que também só querem dinheiro no final do mês sem se preocupar se o seu código um dia será lido por outra pessoa.

E este é um desabafo pra ver onde é que a nossa equipe irá parar desta forma. Infelizmente, eu só tenho desacreditado. E acredite, a gente ainda persiste, mas índio não tem muita chance contra cacique, certo? No entanto, ainda estamos na luta e vamos continuar até que nos tirem todas as forças, rs..

Bom, só pra finalizar, por favor não entenda influências externas apenas como algo de ruim para a equipe. Se deixei esta impressão, não foi por mal. Há também o Mulino Pizzeria que nos injeta uma boa dose quase que diária de Serotonina.

Avante equipes, código bem escrito já! rs..

¹ Aqui não é exatamente o conceito de baby steps, foi só uma maneira de ligar a idéia do XP com a nossa equipe.

Para reflexão

Comments off

Agora a pouco o senador Cristovam Buarque postou uma frase em seu Twitter, a qual, acredito que todos os brasileiros deveriam ler:

“Brasil ficou entre 8 melhores do mundo no futebol e ficou triste.É 85º em educação e não há tristeza.”

@Sen_Cristovam

A um tempo atrás (13/05/2010 para ser mais exato) fui a uma palestra da Microsoft com o Glauco e por falta de tempo não postei na época.

O encontro foi guiado pelo Luciano Conde, arquiteto de soluções e Markus Christen, arquiteto de infraestrutura, ambos da Microsoft. Foi uma boa troca de experiência.

Fiquei muito satisfeito em ter ido e digo que fiquei muito impressionado com o quanto a Microsoft tem se aproximado da comunidade.

Esta impressão de aproximidade não é recente, eu acompanho o blog de pessoas que trabalham dentro da Microsoft, que fazem parte do time de desenvolvimento do Visual Studio, .NET Framework e até do ASP.Net e eles tem recebido muito feedback da comunidade, justamente porque eles trazido isto a comunidade.

Resumindo um pouco o passado, a Microsoft era a maior (e talvez a única) potência no mundo no desenvolvimento de software e sistemas operacionais. Era notável (e ainda é) pela quantidade de PCs rodando Windows e pacotes do Office instalados. Por muito tempo, estes foram os cargos chefe da empresa, que hoje investe em muitas outras áreas.

Logo após isto, nós vimos as pessoas em prol de sistemas operacionais livres e que hoje é possível ver o sucesso da união de conhecimentos diferentes e mesmo desejo. E este foi só um exemplo.

Tendo em vista, eu trago a frase, "se você não pode contra eles, junte-se a eles". Tenho visto como a empresa tem aceitado mais feedback para seu crescimento, e parte do encontro foi isto, eles buscavam este feedback das pessoas e empresas do que a Microsoft estava fazendo de errado, o que estava faltando, aonde eles não atuavam ou, onde não traziam ganho competitivo (aguardem que mais pra frente irá vir um post relacionado a isto).

Bom, um pouco mais sobre a palestra então, ou pelo menos o que eu lembro. Nos mostraram o portfolio de serviços da atuação da Microsoft (mais específico no slide 16) e é bem interessante. Trouxeram à tona também muito fortemente que Arquitetos de Infraestrutura devem estar presentes juntos aos Arquitetos de Desenvolvimento e realmente fazer parte da equipe, seja qual for a aplicação.

O mais importante que foi mostrado, para mim, foi o Windows Server App Fabric que na época ainda estava sendo finalizado. O App Fabric vai ser um "add-on" para que o IIS finalmente seja um servidor de aplicações. Ele deve permitir maior facilidade na construção e gerenciamento de aplicações web. Para quem lembra do Velocity, então, ele foi integrado e agora se chama App Fabric Cache.
Para aplicações distribuidas, ele permitirá um gerenciamento muito maior para os serviços WCF e WF. Vale a pena entrar no site e buscar um pouco mais sobre o App Fabric. É o que eles mais indicaram como o "futuro" das aplicações web.

Bom, isto é o que eu consigo lembrar por agora. Para você que leu até aqui, como prêmio eu estou disponibilizando o que foi apresentado na palestra.