Sunday, January 4, 2009

"Variáveis" em Erlang

Um outro ponto muito importante para entendermos Erlang é o conceito de variáveis, este é muito diferente do que nós estamos acostumados. Vejam:

As variáveis são estruturas para basicamente, guardarmos um valor e tornar possível que nós o recuperemos depois. Exemplo:
1> X = 272727.
272727
Primeiro nós guardamos um valor em "X" e depois ele nos mostra "272727". Atente que todas as variáveis devem começar com uma letra maiúscula.

Agora, vamos recuperar o valor inserido:
2> X.
272727
Portanto, "X" contem um valor e nós podemos fazer uso:
3> X*X*X.
19683
Os exemplos acima são simples, porem expressam perfeitamente que em Erlang as variáveis tem um conceito análogo ao da Matemática, quando você associa um valor com uma variável, está fazendo uma "afirmação de um fato": esta variável tem este valor (ponto).

No entanto, se você tentar inserir um novo valor para a nossa velha variável "X", terá um erro brutal, como este:
4> X = 1234.
=ERROR REPORT==== 11-Sep-2006::20:32:49 ===
Error in process <0.31.0> with exit value:
{{badmatch,1234},[{erl_eval,expr,3}]}
** exited: {{badmatch,1234},[{erl_eval,expr,3}]} **
Para explicar é necessário fazer duas colocações importantes a respeito de "X = 1234.":
  • Primeiro, "X" não é uma variável, ao menos não como nós a encontraríamos em outras linguagens de programação;
  • Segundo, "=" não é um operador de atribuição;
Esta é provavelmente uma das áreas mais difíceis de entender, para quem é novo em Erlang (eu também sou).

Variáveis não são variáveis:

Em Erlang variáveis tem uma única atribuição, e assim como este conceito sugere, um valor só pode ser alterado uma única vez! Se você tentar mudar este valor, você receberá um erro fatal (como mostrado pouco acima). A variável que teve seu valor alterado é chamada "bound-variable" (pode ser traduzido como "variável-vinculada"). Todas as variáveis começam como "unbound" (desvinculadas), até que uma chamada como "X = 1234." atribui um valor ao elemento "X". Note que antes de ter um vínculo estabelecido, "X" poderia ter qualquer valor, porem, depois disso, ela terá o mesmo valor para sempre (até o final da execução).

A este ponto você deve estar pensando o porque chamar este elemento de "variável", e dá-se por dois motivos:
  • Eles são variáveis, porem, só pode ter seu valor alterado uma única vez;
  • Eles se parecem com variáveis em outras linguagens convencionais de programação, então é normal que uma linha de código com o padrão "X = ..." seja familiar ao conceito;
Na verdade, "=" é um operador para "pattern-matching" (correspondência de padrão), o qual comporta-se como um operador de atribuição quando "X" está "unbound" (desvinculado), ou seja, apenas uma única vez durante a vida de uma variável.

Finalmente, o escopo de uma variável é a unidade léxica no qual ela foi definida. Se "X" é utilizado em um bloco de uma função, então, este não será válido fora deste bloco. Em Erlang não existem variáveis de contexto global ou privado, nem mesmo será reutilizada em diferentes blocos de uma função. Se "X" ocorrer em diferentes funções, então serão variáveis diferentes, porem com um mesmo nome, e, provavelmente, com valores diferentes atribuídos em cada escopo.

Bibliografia:

Programming Erlang (Joe Armstrong)

Sunday, December 21, 2008

Erlang II

Näo gosto muito de dar exemplos extremamente técnicos, como o artigo abaixo, mas acredito que é necessário mostrar um pouco da tipagem e do "feeling" de Erlang, depois do post anterior.

Erlang Shell:

Parece-nos um pouco de modismo atual, mas todas as linguagens de programação interpretadas tem um shell para testar os comandos, mas o fato é que esta pratica remonta de muitos anos, a exemplo do Erlang Shell:
$ erl
Erlang (BEAM) emulator version 5.6.3 [source] [smp:2] \
[async-threads:0] [kernel-poll:false]

Eshell V5.6.3 (abort with ^G)
1> 27*2.
54
2>
BREAK: (a)bort (c)ontinue (p)roc info (i)nfo (l)oaded
(v)ersion (k)ill (D)b-tables (d)istribution
a
Acima segue um exemplo bem simples de como este shell se parece, também um exemplo de uma operação matemática, veja que os padrões para este tipo de ação é equiparado a todas as outras linguagens, o único exemplo, de destaque de Erlang, é que todas as intruções terminam com um ponto (".").

Módulos e Funçoes:

Vamos começar com um exemplo para nos acostumarmos um pouco com a tipagem de Erlang, devo dizer que a primeira vista ela não é das mais fáceis, porem, ela privilegia a fluidez deste tipo de software, lembre-se de que será necessário um período de adaptação.

Abra um arquivo com nome de "teste.erl" (sim, a extensão é importante), e acrescente o seguinte conteúdo:
-module(teste).
-export([double/1]).
double(X) ->
2 * X.
Feito isso, vamos chama-lo dentro do Erlang Shell, atente que o shell deve ser chamado no mesmo diretório que você criou o arquivo acima:
$ erl
1> c(teste).
{ok,teste}
2> teste:double(27).
54
Após o comando "c(teste)." o interpretador faz a leitura dos fontes e o compila, gerando um executavel em RAM, logo em seguida ele já está pronto para ser utlizado, sabemos disso através do retorno "{ok,teste}".

Toda a declaracao de módulos em Erlang é feita com a instruçao "-module().", atenção ao detalhe de ser iniciado com "-" e sempre finalizado com ".". Neste exmplo o mais importante é a instrução "-export([double/1]).", esta deixa disponível o método "double" o qual espera um parametro, por isso a presença do "/1" na instrução. Sem o "export" o método "double" só estaria disponível dentro do módulo "teste".

Outro retorno dos comandos acima é a criação do "teste.beam", este é o resultado do código Erlang compilado há pouco:

$ file teste.beam
teste.beam: Erlang BEAM file

Bibliografia (Links):

Wikipedia (http://en.wikipedia.org/wiki/Erlang_(programming_language));
Erlang Getting Started (http://www.erlang.org/starting.html);

Tuesday, November 18, 2008

Introdução a Erlang

Introdução:

Erlang é uma linguagem de programação de propósito geral, focada em concorrência e sistemas de tempo real. Esta linguagem foi criada pela Ericsson para suportar sistemas tolerantes a falhas, de tempo-real e ininterruptas. Estes requisitos, na época de sua criação até os nossos dias, é algo muito ousado. Mesmo hoje, temos dificuldades em fazer aplicações com estas características e por este motivo, voltamos um pouco no tempo e queremos reaproveitar conceitos que foram forjados pela prática e obter o melhor resultado possível com as ferramentas atuais.

Concorrência e "Actor Model":

Para concorrência Erlang segue o modelo matemático de atores... Para explicar, vamos criar uma metáfora atribuindo a cada processo determinadas capacidades ou características, neste consenso seria possível para um ator: tomar decisões locais, criar mais atores, enviar mensagens, determinar seu modelo de respostas, entre muitos outros. O "Actor Model" foi concebido em 1973 por Carl Hewitt, Peter Bishp e Richard Steiger. Este modelo foi inspirado por leis da física e influenciou fortemente linguagens de programação, por isso, para realmente entender Erlang, tenha estes conceitos em mente.

Processos e Troca de Mensagens:

A criação e manipulação de processos é algo trivial para Erlang, onde, threads são consideradas de difícil manipulação e inseguras, em muitos sentidos. Para driblar todos estes problemas, intrínsecos de threads, Erlang propõe uma arquitetura formada basicamente por processos (característica também dos SOs unix-like), intercomunicando-se por troca de mensagens ("Message Passing"). Esta é realizada sem usar nenhum tipo de memória ou variáveis compartilhadas, tornando cada processo uma instância independente também seu modelo de comunicação é assíncrono. Cada processo tem algo comparavel a uma fila de mensagens, recebidas de outros processos que ainda não foram devidamente tratados.

Com o uso do "Actor Model" podemos perceber um pouco do que nos é possível usando Erlang: ter uma série de pequenas partes do nosso programa assumindo ações e "tomando" decisões. Podemos abstrair parte deste conceito pensando em uma fábrica, ou linha de produção, na qual, cada colaborador faz uma parte das rotinas e repassa tratamento a diante, podemos também atribuir as figuras dos inspetores e gerentes, com o papel de atentar ao processo como um todo, orientando as melhoras e corrigindo pequenos problemas em tempo de execução.

Escalabilidade:

Outra face incrível de Erlang é a facilidade para fazer uma aplicação horizontalmente escalável, ou seja, podemos dividir os processos de Erlang por vários servidores distintos, e caso seja necessário, adicionar mais um servidor e, simplesmente, dividir a carga entre eles, o único requisito, é ter a Virtual Machine de Erlang instalada. Este modelo vai deixar as partes da nossa aplicação espalhadas, porem, os processos continuam a se comunicar da mesma forma, e com a mesma facilidade, mesmo estando em máquinas separadas. Esta feature reduz drasticamente a complexidade de manutenção.

Links:

http://www.erlang.org
http://www.erlang.org/doc/getting_started/part_frame.html
http://en.wikipedia.org/wiki/Erlang_(programming_language)
http://en.wikipedia.org/wiki/Message_passing
http://en.wikipedia.org/wiki/Real-time_computing

Saturday, October 4, 2008

Why Perl

Há alguns anos atrás eu precisava de uma boa ferramenta para concentrar anti-spam, anti-vírus, e muitas outras funções, dentre as possíveis escolhas eu elegi o Amavisd-new, por ser um projeto maduro e com referencias fortes. E, em um determinado momento eu estava cercado por situações nas quais eu não encontrava saída, mesmo nas listas de discussão e documentação, então, senti-me "obrigado" a ler os fontes. Inicialmente foi uma das piores experiências da minha vida, o software é todo escrito em Perl (claro!) e na época tinha mais de 18 mil linhas de código... Porem, foi também, uma das melhores oportunidades da minha vida profissional! Vou explicar o porque.

Para quem não tem muita experiência com a linguagem, Perl é um tanto quanto complicado, pois tem uma estrutura bastante diferenciadas e utiliza elementos que não são auto-explicativos. Ou seja, sem conhecer a linguagem eu não poderia entender como aquele software trabalha.

Comecei então a procurar um bom artigo ou tutorial sobre introdução e na maioria deles eu era redirecionado às manpages. Na época me parecia estranho aprender uma linguagem de programação através de suas manpages, pois eu nunca havia pensado nisso. No entanto, segui o conselho e comecei: "$ perldoc perl". Devo admitir, tudo o que você precisa, quer ou terá necessidade estão em suas manpages, e todo o conteúdo está mais do que bem explicado, cheio de exemplos e textos adicionais. Sem dúvida, as manpages do Perl são mais do que suficientes.

Perl é uma linguagem extremamente poderosa e madura, criada por Larry Wall em 1987 com o enfoque de ter recursos para processamento de texto, foi principalmente influenciada por C, Shell Script, AWK, Sed e Lisp, hoje, Perl encontra-se na versão 5.10, e está presente em quase todas as plataformas.

Afinal, Porque Perl?
  • Com mais de 20 anos de idade esta linguagem está mais do que consolidada no mercado, hoje é praticamente impossível ver um sistema operacional unix-like sem o seu interpretador, e mais, sem ter dezenas de scripts para as mais variadas funções, escritos em Perl;
  • É o canivete-suíço das linguagens de programação pois, comprovadamente, é flexível e adaptável;
  • Sua sintaxe é inspirada em linguagem C (ANSI), então, é simples, direta e prazerosa de escrever;
  • Reúne as listas de Lisp, os Arrays Associativos do AWK e as Expressões Regulares do Sed, ou seja, o melhor destes mundos com inúmeras outras inovações;
  • Também suporta estrutura de dados complexas, First Class Functions (construção de novas funções em tempo de execução), Closures, Orientação a Objetos, bem como a mistura de vários paradigmas, fica a critério do programador, e muito muito mais;
  • Toda a liberdade ao desenvolvedor, possibilitando escrever instruções complexas em poucas linhas de código (quanto menos linhas de código menos bugs);
  • É rápido e produtivo, pois provê ao programador todas as ferramentas necessárias para colocar os seus anseios em prática;
  • "There is more than one way to do it";
  • CPAN, um repositório com milhares de módulos Perl, largamente utilizados, e conseqüentemente, testados pela comunidade;
  • Liberdade. Não te prende à burocracia, e subentende de que o desenvolvedor tem consciência do que faz e quer liberdade para isso;
Porem é necessário deixar claro que Perl é uma linguagem voltada às soluções e meios para atingir os objetivos, e, não necessariamente voltada a quem vai desenvolver estas soluções, ou seja, ela vai exigir dos programadores conceitos e disciplina, na minha opinião, isso é muito bom nos dias de hoje.

Links:

Tuesday, September 23, 2008

Greylisting

A pratica dos spams na internet chegou aos seus limites. Temos de um lado profissionais capacitados "vomitando" milhões de mensagens indesejadas; para os que não sabem, é muito complexo enviar uma grande quantidade de mensagens, exige muita experiência, técnica para burlar os filtros e RFCs; de outro, pessoas recebem estes emails e, definitivamente, compram produtos que lhe são oferecidos, desta forma, enviar spams é algo lucrativo.

Muitas são as maneiras de tentar impedir esta pratica, um delas é a Greylisting (http://en.wikipedia.org/wiki/Greylisting), a qual consiste em, basicamente, validar um email através das tentativas de envio, partindo do pressuposto: os "spammers" não tentam enviar uma mensagem mais de uma vez. Dá-se porque o lucro vem da quantidade de mensagens entregues, então este sujeito tenta entregar milhares de mensagens e não quer ficar perdendo preciosos milesegundos, não há (em uma porcentagem considerável dos casos) re-tentativa. Porem, servidores de e-mails convencionais, tentam entregar novamente em quatro horas.

Deste cenário vem as práticas de Greylisting, validar uma mensagem antes da sua entrada, e apartir dos dados colhidos (histórico), como re-tentativas, origem (ou até origens), destinatários e muitos outros, definir se este email, bem com a sua origem, é valida ou não e se poderá ser entregue das próximas vezes.

Devemos reconhecer, a idéia é muito boa e temos ótimas ferramentas para implementa-la, portando, é um recurso considerável. O errado está na forma como algumas empresas o fazem, nestas é aplicado Greylist pra todos, sem distinção. Agora, imagine-se do outro lado, você, um cliente ou um fornecedor, e seu email só será entregue com um delay de possivelmente quatro horas... Muito próximo do inaceitável.

Porem, você pode lembrar-me de que há a Whitelist!

Mas esta é para os endereços que você já conhece. E quanto aos endereços que você
nunca recebeu mensagens, são válidos e tem um propósito nobre?

Então Greylist é bom mas não deve ser usado?!

A resposta é sim, deve ser utilizado.

A utilização da Greylist não pode ser política padrão, senão, podemos julgar de forma errônea as novas mensagens, deve ser um filtro adicional para o nosso anti-spam, ou seja, é recomendável aplicar Greylist para os servidores de SMTP que nós não conhecemos, e, temos uma séria suspeita. Por exemplo:
  • Redes da Coréia, e alguns outros países asiáticos;
  • Redes no qual sabemos que são conhecidamente de "spammers", na sua maior parte, leia-se ADSL;
  • IPs que estão em blacklists públicas, e por motivos comerciais, não podemos simplesmente descartar;
  • IPs que já tiveram ocorrências esporádicas de spams, ou qualquer outro tipo de mensagem indesejada;
  • Entre muitas outras possibilidadades.
Atente que a Greylist é uma ferramenta muito útil e que deve estar correndo lado-a-lado às regras de negócios de sua empresa, ou seja, você deve ter em mente quais são os lugares de onde são esperadas novas mensagens e quais os lugares pouco confiáveis. Apartir destes pontos definir a sua estratégia.

Sunday, September 21, 2008

Hello World

Já faz um bom tempo que a iniciativa de ter um blog, ou alguma oportunidade de disponibilizar conteúdo e idéias, me passa pela cabeça, e finalmente, está aqui a iniciativa! Já fiz artigos para alguns sites, participação em podcast, e outras coisas, agora chegou a hora de ter um "blog".

O que eu quero passar é conteúdo relacionado aos conceitos de programação, ou seja, tudo o que um programador, faz (ou deveria fazer), pensar, usar e, conseqüentemente, abrir uma margem para discutirmos sobre estes assuntos. E por ter certeza de que nenhum programador é completo (para não dizer "competente") sem ter plenos conceitos de sistemas operacionais, também vai ter muitas coisas relacionadas aos unix-like e projetos open-source. Em todo este processo não pretendo me prender ao "como fazer" (how-tos em geral) mas sim ao porque.

Ainda não sei a freqüência de publicação dos posts, vamos ver como as coisas vão fluir ;-).

Todos os comentários e críticas são muito bem vindas.