quarta-feira, 12 de novembro de 2014

O Zen na Programação - Parte I: O Zen

Primeiro: O que é o Zen?
Eu não sei o que é Zen e quem fala que sabe está menos esclarecido que eu. Há livros e cartas de monges de mais 500 anos atrás, mas a palavra zen não tem sentido.

O que não é Zen:

  • Está longe de ser uma religião.  Seja você um evangélico ou budista fanático, o Zen jamais vai negar a divindade na qual vc acredita.
  • Não é um adjetivo nem uma competição, não existe eu sou mais zen que vc e muito menos eu estou zen. A música da Anitta portanto está toda errada, mas artistas tem licença poética
  • O que existe no Zen é o aperfeiçoamento contínuo, a prática, a iluminação e a libertação da mente. O ato mais mundano como varrer o chão é uma oportunidade de exercício espiritual.
A foto da estátua do Buda em meu blog não está aí por mera coincidência e não significa que eu sou budista. Sidarta Gautama, o Buda foi o símbolo da iluminação uma pessoa que foi extremamente mundana mas transcendeu essa condição. Ele não nasceu perfeito, mas se elevou cada vez mais à iluminação. Se ele realmente se fundiu ao Universo ou encontrou o Criador já é outra história que pouco me interessa.

Mas iluminação ou perfeição não é um fim, é uma caminho. E o exercício de uma atividade é a oportunidade de se tornar um exercício espiritual e elevar seu grau de iluminação. Não importa se vc era um samurai ou mestre de chá do Japão feudal ou um programador no século XXI, todos tem uma ferramenta em comum, a Mente.
A mente pode ficar presa (detida) em um único lugar a mente do Samurai pode ficar presa à sua espada. Mas se ela está presa à espada o Samurai não vai para lugar nenhum quando chega a espada do inimigo.
Assim também é a mente presa em conceitos, fica neles detida e não se move. A mente fica presa por causa dos julgamentos, rotulações de coisas ou pessoas. Pelo menos eu ao invés de julgar algo como ruim ou bom, certo ou errado eu prefiro pensar no propósito de que tal ação vai me servir ou se vai me atrapalhar no futuro.
Assim é o erro daqueles que se masturbam em idéias de filósofos, a mente deles acomodou-se na ignorância pois a realidade jamais pode ser de todo capturada em conceitos porque ela está sempre se mudando. Mas igualmente estúpido é se considerar mais esclarecido ou conhecedor da verdade ainda que vc tenha razão, sua mente fica presa ao conceito de estar certo e por isso igualmente está acomodada à ignorância. E obviamente vc vai esquecer porque estava certo ou porque essa era sua opinião. Erro que eu cometi durante essas campanhas políticas.
A mente portanto deve ser libertada especialmente nesta era de grandes inovações, a mente não pode ficar presa em conceitos, deve fluir, se não se mover fica para trás, todos avançam exceto você.

Essas são minhas palavras, tenho muitas outras mais, elas refletem minha opinião. Mas palavras são estáticas e por isso nenhuma delas o fará melhor na arte zen ou o tornará mais iluminado(a) pois elas não trilharão o caminho para você, somente você pode percorre-lo. A única coisa que elas fazem é mostrar que existe um caminho e sua mente deve ser permitida a percorre-lo, ela é sua única bússola para a iluminação. E de modo algum pense se vc está mais ou menos iluminado que alguém pois isso é um conceito e só o atrasará.

Essa foi a primeira parte, a próxima será sobre o que diabos isso tem a ver com programação.

domingo, 9 de novembro de 2014

Programação Funcional - Por-quê agora?

Primeiro vamos analizar a pertinência da pergunta.





Este é o endereço original da imagem em tamanho natural.

De fato a primeira linguagem funcional da história da humanidade foi o cálculo-λ proposto por Alonso Church em 1938, mas por motivos tecnológicos e práticos essa linguagem nunca teve um compilador construído para ela (confiem em mim, mesmo que existisse um compilador λ vcs não iam querer programar nessa linguagem). Mas a sintaxe  de aplicação de função foi tomada de emprestimo por Lisp, 20 anos depois, essa sim foi a primeira linguagem funcional compilada da história.

Então a primeira parte da pergunta é porque havendo uma linguagem funcional desde 1958, foi preferido o uso da programação imperativa? E a resposta está ilustrada abaixo, chama-se máquina de Von-Neumann.

É essa arquitetura da qual se baseiam todos os dispositivos processadores digitais transistorizados, em resumo todos os aparelhos eletrônicos deste século. Desde a central eletrônica de automóveis passando por celulares e desktops até supercomputadores.
Então temos mais duas dúvidas, porque Von-Neumann vingou e porque está em uso até hoje?
Simplesmente porque é a arquitetura mais fácil e barata de se implementar por semi-condutores, o material de que é feito o processador que se encontra dentro do dispositivo do qual vc lê este artigo. Mesmo sendo possível realizar fisicamente outros conceitos de máquinas processadoras Von-Neumann dominou tanto que seria financeiramente inviável a sua substituição.
E o que a programação imperativa tem a ver com Von-Neumann? Tudo!
Um programa de uma máquina de Von-Neumann é uma sequência de passos, a unidade de controle busca (fetch) as instruções da memória, as decodifica (decode)  a unidade lógico-aritmética (ULA) as executa (execute) e armazena (store) o resultado na memória. Os dados usados pela ULA no mesmo ciclo ficam numa memória ultra-rápida (mais que o cache) chamada banco de registradores de uso geral. De grosso modo são eles que determinam o comprimento de bits da máquina (32 ou 64 bits geralmente) porque esses registradores frequentemente armazenam endereços de memória.
Há várias sofisticações na arquitetura das CPUs dos grandes fabricantes (Intel e AMD) como pipelines, previsores de branch e muitos outros, mas tudo o que eles fazem é aumentar o número desses ciclos por segundo (throughtput). O ciclo é o mesmo há mais de 50 anos.

As linguagens imperativas nada mais são que abstrações desse conceito da máquina de Von-Neumann. As implicações mais importantes desse paradigma são:

  1. Variáveis representam endereços de memória (principal ou RAM) contendo valores arbitrários e esse valor pode mudar no ciclo seguinte.
  2. Um programa é uma sequencia de instruções que geralmente são vários ciclos.
Para um programador criando programa dentro de um sistema de único núcleo processador (single-core) isso é muito conveniente pois há vários algoritmos que aproveitam dessas propriedades e diminuem o número de operações. E por haver um mapeamento biunívoco entre a arquitetura Von Neumann e as linguagens imperativas é fácil escovar os bits (giria que se refere à técnica de otimização baseado no funcionamento da máquina que executa o programa). 

Agora fica a última dúvida:
O que aconteceu para que a programação funcional ganhasse tanta atenção só agora (+/- depois de 2006)?
Isso aconteceu:







Os núcleos (core) continuam realizando o bom e velho ciclo Von Neumann mas o paradigma imperativo tornou-se um grande estorvo à arquitetura multi-nucleo. Porque agora para um programa sequencial em que a ordem dos passos é tudo e cada passo pode depender do anterior, dividir as rotinas entre as várias unidades de processamento disponíveis é algo extremamente complicado.
Existe sim a programação concorrente dentro do paradigma imperativo, com os conceitos de tarefas, threads e outros que permitem a divisão se um programa em vários segmentos (threads) e vários métodos de sincronização entre eles. O problema é que essa sincronização gasta preciosos recursos do sistema operacional e pode levar a uma condição em que um segmento A espera o segmento B terminar alguma tarefa mas ao mesmo tempo o B está travado esperando o A finalizar outra tarefa, esse intertravamento é conhecido por deadlock e é uma de várias complicações da programação concorrente.
A verdade é que há tantos fatores a se tratar para a devida sincronização na programação concorrente,  que ela se torna algo muito improdutivo, limitado somente a aplicativos em que o desempenho é de longe o fator mais relevante. Mas porque não podemos dividir o programa em várias tarefas assíncronas e independentes?
Porque na programação imperativa uma variável pode ter um valor diferente, logo um dos núcleos pode modificar uma variável e outro poderia depender dessa mesma variável entretanto com o valor antigo. Essa variável (da qual depende mais de uma unidade de processamento) é um estado compartilhado e é um grande empecilho à divisão de uma tarefa ou programa entre vários processadores.

E porque a programação funcional resolveria esse impasse?
Porque no paradigma funcional:

  • Variáveis são como na matemática, seu valor é fixo
  • Um programa é uma associação de várias computações (funções, que por sua vez podem ser associações de outras funções ou das mesmas), embora isso é feito também na programação imperativa, há uma tremenda diferença: na programação funcional a ordem dessas computações não importa
Claro que há toda uma ciência para trazer os efeitos acima e conseguir que o programa se comporte da maneira desejada (leia-se da maneira que o usuário final ou cliente espera e pela qual ele pagou). Essa ciência é a programação funcional e será descrita de forma mais elaborada nos próximos artigos