30 de agosto de 2011

Clojure Kōan

Kōans são histórias, diálogos ou questionamentos muito utilizados na filosofia zen-budista e que o seu significado só pode ser atingido pela intuição, e não puramente pelo raciocínio lógico. De tão malucos fascinantes, acabaram sendo incorporados à cultura hacker, como no diálogo abaixo:
Um dia, quando Sussman era um calouro e estava programando no PDP-6, Minsky sentou-se ao seu lado.
— O que você está fazendo? — perguntou Minsky.
— Estou treinando uma rede neural randômica para jogar o jogo da velha — Sussman respondeu.
— E porque a rede é randômica? — perguntou Minsky.
— Eu não quero que ela tenha conceitos prévios sobre como jogar — disse Sussman.
Minsky então fechou os olhos.
— Para quê você está com os olhos fechados? — Sussman perguntou ao seu professor.
— Para que a sala fique vazia.
Naquele momento, Sussman alcançou a iluminação.
Fonte: Some AI Koans
Neste exemplo cômico, apesar de mostrar a forma de pensamento da tradição budista, o questionador tem respostas para suas perguntas, mas não é o que acontece frequentemente com os Kōans tradicionais. O mais comum é que aquele que questiona descubra as respostas por conta própria. Mas o que isto tem a ver com linguagens de programação?

Acontece que alguns grupos de desenvolvedores foram iluminados e resolveram compartilhar este caminho rumo ao nirvana, criando os koans da programação. Clojure Koans segue toda esta filosofia descrita acima, onde o objetivo é alcançar o conhecimento máximo de Clojure de forma semelhante à metodologia TDD (Test Driven Development) exceto que os testes já estão prontos =D. O que você precisa fazer é executar o script principal e a medida que os erros forem aparecendo, você irá abrir o arquivo que corresponde ao teste atual e preencher os espaços responsáveis pela falha nos testes, de modo a fazer o teste passar.

Da forma que são feitos os koans, você consegue aprender da linguagem sem precisar ficar lendo tutoriais vagos e egoístas e ainda filosofa um pouco. Vamos começar então, o nosso caminho de iluminação:

"Instalando"

Coloquei instalando entre aspas porque em Clojure, geralmente não se instala nada, só se configura. Mas, primeiramente é preciso baixar aqui o Clojure Koans, quando fizer o download e extrair a pasta existem várias formas de executar o software: usando o comando script/run, usando lein repl ou pelo eclipse. Eu prefiro usar o leiningen, por facilitar muito a vida do programador, então usei o comando lein deps, para atualizar as dependências do projeto, mas também mudei um pouquinho o meu project.clj:

(defproject functional-koans "0.4.1"
:description "The functional koans"
:dependencies [[org.clojure/clojure "1.3.0-beta2"]
               [fresh "1.0.1"]
               [jline "0.9.94" :exclusions [junit]]]
:dev-dependencies [[swank-clojure "1.4.0-SNAPSHOT" :exclusions [org.clojure/clojure]]
                   [lein-eclipse "1.0.0"]]
:repositories {"sonatype-oss-public" "https://oss.sonatype.org/content/groups/public"})

Caso também queira utilizar o eclipse, depois de executar lein deps, execute lein eclipse e importe o projeto para a IDE.

Executando

No Eclipse, selecione com o botão direito o arquivo path_to_enlightenment.clj, depois navegue em Run as > Clojure Application, quando a REPL abrir, digite (run). Independente da IDE, ao executar o script um erro acontecerá:

E também será indicado o caminho para o arquivo que causou o erro, neste caso <dir>\clojure-koans\src\koans\equalities.clj. É aí que a jornada começa, as frases "dicas" aparecem no maior estilo Koan-budista, sem dizer realmente o que se deve fazer, mas dando uma pasta vaga, instigando sua intuição a procurar resolve-lo.

Se você entendeu a filosofia, você sabe o que deve ser feito, senão eu conto: basta ir até o arquivo especificado e modificar o script de modo que o teste passe. Simples assim:

Assim que o arquivo equalities.clj é salvo, o teste é executado novamente, e como era de se esperar, uma nova meditação aparece:

E agora só continuar o ciclo: meditar-corrigir-aprender. Por mais que pareça bobo, principalmente no começo, esta abordagem traz um conhecimento profundo da linguagem. O fato de agir intuitivamente na correção dos erros e após corrigir, entender o real significado do teste feito, agrega muito conhecimento.

2 de agosto de 2011

Clojure + Leiningen + Eclipse

A primeira grande dificuldade de se aprender uma linguagem é encontrar um bom ambiente de desenvolvimento. Não há IDEs específicas para Clojure, ainda. Mas, alguns plugins de IDEs conhecidas tem se destacado, há plugins para: NetBeans, Eclipse, IntellijIdea, Emacs, TextMate e etc. Hoje irei focar no ambiente Eclipse, que no Windows parece se destacar.

Leiningen

Leiningen é uma ferramenta bastante parecida com o Maven (Java). Nesta ferramenta é fácil criar um projeto, com uma estrutura de pastas predefinidas e também gerenciar dependências (bibliotecas .jar).

A primeira coisa é ir a este site https://github.com/technomancy/leiningen e realizar o download. O classpath deve conter a variável %JAVA_HOME%, indicando a instalação do Java.
No Windows é preciso executar o script lein.bat que irá realizar o download do jar necessário para o caminho C:\Documents and Settings\<seu usuário>\.lein\self-installs, caso algo dê errado, faça o download do jar leiningen-1.5.2-standalone.jar e crie a variável de ambiente LEIN_JAR.

Após baixar o leiningen e configurar o classpath, já é possível executá-lo através da linha de comandos. A ferramenta possui alguns comandos, basta digitar "lein help" na linha de comando para ter uma lista completa:


Para treinar o Clojure, basta digitar "lein repl", que o REPL do Clojure irá abrir e você já pode testar o poder da linguagem:


Para criar um novo projeto, faça "lein new projeto", a seguinte estrutura de pastas será criada:

Para quem já está acostumado com o Maven, já entendeu a estrutura, mas não há segredo, basicamente foram criados dois ambientes: o de desenvolvimento e o de testes. Dentro da pasta "src/projeto" há o arquivo "core.clj", que corresponde ao arquivo inicial, ou principal do projeto, assim como em "test/projeto/test" há um outro arquivo de mesmo nome para testes.

Na raiz do projeto há o arquivo "project.clj", que é utilizado pelo Leiningen para organizar as dependências do projeto, é preciso adicionar a biblioteca "lein-eclipse" para adicionar comandos que fazem o eclipse entender a estrutura criada como um projeto, para isto modifique seu project.clj para:

(defproject projeto "1.0.0-SNAPSHOT"
  :description "FIXME: write description"
  :dependencies [[org.clojure/clojure "1.2.1"]
                 [org.clojure/clojure-contrib "1.2.0"]]
  :dev-dependencies [[lein-eclipse "1.0.0"]])

Depois disto, dentro da pasta "projeto", execute "lein deps", para fazer o download da biblioteca.
E depois disto, execute "lein eclipse", agora o projeto já pode ser importado para o eclipse.

Eclipse

No Eclipse (aqui estou usando a versão 3.6), instale o plugin CounterClockWise da seguinte forma: Vá em Help>Install new software>Add
E digite:
Name: Clojure Plugin
Location: http://ccw.cgrand.net/updatesite
Marque a opção "Clojure Programming" e conclua a instalação.
Após instalar o plugin e reiniciar o Eclipse, vá em File>Import>Import Existing Projects into workspace e importe o seu projeto criado anteriormente.

Pronto, agora já está tudo configurado e você verá a mesma estrutura de pastas:


Pronto! Seu ambiente está configurado. Vamos testar escrevendo uma função simples:

(ns projeto.core)

(defn ola
([] "Olá mundo!")
 ([nome] (println (str "Olá " nome ))))

A função acima imprime "Olá mundo!" na tela caso nenhum argumento seja passado, e imprime "Ola <nome>" caso o nome seja informado como parâmetro.
Para executar a função, vamos iniciar uma sessão REPL (Read-Eval-Print Loop), que é o ambiente interativo do Clojure, isso pode ser feito de duas formas:

Leiningen (Comando "lein repl")
Eclipse (Botão direito do mouse>Run as > Clojure Application), isto irá abrir um console, onde é possível digitar a função e analisar os resultados:

29 de julho de 2011

Introdução ao Clojure



Clojure é uma linguagem LISP moderna que tem por vantagem rodar na Java Virtual Machine (JVM).
Lisp, para quem não conhece é uma família de linguagens funcionais de programação que tem como alguns destaques:
  1. Poucos tipos de dados (geralmente apenas listas)
  2. Avaliação preguiçosa (lazy evaluation) - funções são avaliadas apenas quando preciso
  3. Suporte à concorrência facilitado
Quem não está acostumado com o jeito LISP de desenvolver pode estranhar um pouco, ainda mais quando se vem de linguagens imperativas ou orientadas a objeto. Mas, Clojure se destaca um pouco e consegue chamar mais a atenção de programadores de outras linguagens, principalmente de desenvolvedores Java, devido a facilidade com que se pode utilizar códigos Java de dentro de um código Clojure.

Mas, não é só por isto que Clojure se popularizou e tem conquistado cada vez mais desenvolvedores ao redor do mundo. Rich Hickey criou a linguagem em 2007 após uma pesquisa rigorosa em linguagens de programação e com o intuito de evitar muitas das limitações impostas pelo gerenciamento de estados feito pelas linguagens OO. Explico: Clojure nasceu para lidar com o problema da concorrência (um dos grandes assuntos da atualidade devido às aplicações em nuvem) e faz isto de uma forma tão transparente que o desenvolvedor não precisa se preocupar com deadlocks, na verdade o programador não precisa se preocupar muito com isto, a linguagem já trata isso por trás da sua API.

Clojure é uma linguagem compilada, porém dinâmica e a sintaxe quase não existe, um tradicional "hello world" por exemplo fica assim:
(println "Hello World")
A função println aqui nada mais é que a execução do método System.println() do Java. Note os parênteses, típicos das linguagens LISP (Lots of Irritating Single Parentheses), no começo estranha-se a quantidade deles que é preciso escrever, mas o interessante é que não é preciso digitar mais nada! A sintaxe é praticamente só esta: escreva tudo entre parênteses e voilà.

Outro aspecto importante a ser mencionado é que Clojure é uma linguagem para quem é preguiçoso ágil, mas, para conseguir esta agilidade é preciso entender a sua filosofia. É preciso quebrar a cabeça algumas vezes tentando resolver problemas do jeito OO de ser até conseguir pensar de modo funcional, e para quem não está acostumado, realmente dá um grande trabalho.

Existem muitos outros aspectos da linguagem que devem ser abordados e/ou aprofundados como a imutabilidade das variáveis, as estruturas de dados em Clojure (maps, vectors, lists etc.), a interoperabilidade com Java, as estruturas adaptadas para concorrência etc. Enfim, há muito o que se falar ainda, esta é apenas uma breve introdução à linguagem.