There’s a little Haskell in your Javascript

This may seem a little strange, but althrough Javascript is a dynamic language, with very loose typing (automatic convertions, equals signs that only works on arrays/numbers/undefined/nil), lots of things that are “falsy” by default, with the new promise-based approach of Javascript, the language is borrowing some very interesting concepts from Haskell.

And yes, this is a great thing. And yes, this will probably change the way we program.

Let’s begin by talking about Javascript, and its new features. Old async-javascript code was probably like this:

some_io_function(function(result) {
  find_name_in_db(result.person_id, function(name) {
    console.log(name);
  })
});

Now, it’s like this:

some_io_function()
  .then((result) => find_name_in_db(result.person_id))
  .then(console.log)

And, with new ES6 features:

async () => {
  var result = await some_io_function();
  var name = await find_name_in_db(result.person_id);
  console.log(name)
}

Now, what does this have to do with Haskell? Multiple things, but the most important: Functors!
(more…)

Clojure, reflection, and performance/memory issues

Right now, I’m working in a game project in Clojure. I don’t really know how it will turn out, but for now I’m just trying to learn a better way of making games.

While working in this project, I found out that my game was consuming a lot of memory. I’m using play-clj library, and I know that it creates a lot of small objects for each render cycle, so that was my first guess.

So, I plugged in a VisualVM in my running game to understand what was happening. In the beginning, nothing seemed to make sense: the heap grew, then was released, the correct and normal cycle of any Java application. Then, I tried a memory profiling and a memory dump. Then, things became interesting.

There were a lot of float[] objects popping up, as I would expect – play-clj uses floats to position elements on the screen, and all the time I found myself trying to coerce doubles to floats. But there was something even stranger there was consuming a lot of memory: instances of java.lang.Method.

For those who don’t know, Clojure interoperability with Java relies on reflection when it can’t resolve a type. To resolve a type means that Clojure can be certain that, at run time, that a specific identifier will be a specific type. So, for the following code:

(ns example.core)

(defn sum-abs [a b]
  (Math/abs (/ a (float b))))

(defn only-abs [a]
  (Math/abs a))

The first method call will use reflection because it knows that the result of a sum will always be a float. The second one has no idea if it will be called with a number or not, so it relies on reflection. It may seem strange, as we’re calling Math/abs, but remember that in Java we can have different methods with the same name, differing only on type signature.

So, to resolve the type, we’ll need type hints. But first, we can test if our code is using reflection using lein check.
(more…)

Atom Packages with ClojureScript

One of the best things in Clojure (and ClojureScript) is that you can design your code connected in a live environment – so, your auto-complete abilities reflect exactly what’s running right now. Then, you can evaluate code with real data, to catch bugs or just test things. Then comes Atom, an editor that, in my opinion, is one of the easiest editors to create plugins (packages), using technologies we already know – mostly, HTML, CSS, and JavaScript. To program with Clojure, you can use proto-repl – an awesome package that, combined with ink, allows us to run clojure code and display right on the editor, Light Table style.

But then I became greedy and wanted more. I created clojure-plus, a package that extends proto-repl to be able to work with multiple projects, specially when these projects are not configured to be “refresh-friendly” or something. Most of the things I have in clojure-plus are simple helpers that I found missing in proto-repl, at least in the beginning.

But, after that, I began to work professionally with Clojure. And then, most of the projects had some kind of “strangeness”, mostly because everyone was using InteliJ with Cursive – a lot of people I knew didn’t even run the code, with exception of midje tests. So, I changed my package to work around these “strangeness”, and after a while, I saw that I was creating a big mess of code. Then, came ClojureScript support, and things became even more complicated… so, came the idea to port my package to ClojureScript, and after trying several things (Figwheel, Ajom, and other packages) I discovered that they could not solve my problems. The only one that worked, with restrictions, was Weasel, but then with some hacks things worked fine. So, here are the steps to make things work:
(more…)

Configurando Clojure com Atom

Bom, numa postarem anterior eu mostrei meu workflow com Clojure e Atom. Nesse post, farei um passo a passo bem mais detalhado.

A primeira coisa a se fazer é instalar, no sistema operacional, o Java SDK e o Leiningen. Isso torna possível rodar Clojure e ClojureScript no sistema operacional. Agora, vamos ao Atom.

As novas alterações do meu plug-in clojure plus trazem um suporte preliminar a ClojureScript também, usando o piggieback. Na verdade, qualquer biblioteca é possível, já que o plug-in permite que você defina um comando que abriria um console ClojureScript. Mas mais sobre isso mais tarde.

Atom e Profiles

Dentro do Atom, instale o proto-repl, clojure-plus, lisp-paredit e clojure-language. O primeiro plug-in faz a ponte entre o clojure e o editor, o segundo traz funcionalidades interessantes, o terceiro faz edição estrutural (se você quiser, claro), mas principalmente corrige a indentação de código Clojure quando se digita enter (o Atom tem uma regra genérica que não funciona em LISPs).

Enquanto esses plug-ins instalam, é hora de configurar seu profile. Em Clojure usando Leiningen (ou lein para os íntimos – demora muito digitar o nome completo) há um arquivo de profiles em seu diretório home. Esse arquivo define bibliotecas e plug-ins que sempre ficarão ativos em qualquer circunstância e em qualquer código que se esteja digitando. Desnecessário dizer quão poderoso é isso, certo? Basicamente, bibliotecas ficam disponíveis para todos os projetos, mesmo os que não a usam, em qualquer circunstância. Aqui vale um pequeno desvio:

Em Clojure, há muitas bibliotecas que não servem exatamente para serem usadas no código – basicamente, o uso delas é refatorar código (como o refactor nrepl), debug (como o sayid), autocomplete (como o compliment), etc. O que vamos fazer é adicionar o refactor-nrepl e o proto-repl no projeto. O proto-repl, na verdade, é só o agrupamento do compliment e do clojure.tools.nrepl, então se você quiser pode adicionar essas bibliotecas individualmente (bom caso algum bug numa delas esteja corrigido numa versão mais recente).

O seu arquivo de profiles vai ficar dentro do diretório home, subdiretório .lein, no arquivo profiles.clj. Se nem o arquivo nem o diretório existirem, crie-os. Logo, seu arquivo /home/seu-usuario/.lein/profiles.clj ficaria assim:

{:user {:plugins [[refactor-nrepl "2.2.0"]]
        :dependencies [[slamhound "1.3.1"]
                       [proto-repl "0.3.1"]
                       [com.billpiel/sayid "0.0.10"]]}}

As dependências do slamhound e do sayid não tem uso ainda, mas estou pensando em integrá-las num futuro próximo ao clojure-plus, logo é bom mantê-las.

Nesse ponto, seu editor está pronto para ser usado. Você pode instalar também o plug-in parinfer, que infere parênteses a partir da indentação – muito útil, na minha opinião, mas devido a algumas semanticas provavelmente você vai querer usar o parinfer em conjunto com o paredit. Eu uso os dois juntos quando trabalho com Clojure.

Configuração dos plug-ins

Eu não gosto dos plug-ins que definem atalhos para mim, logo eu não defini nenhum atalho para o clojure-plus. O proto-repl, em compensação, define uma centena de atalhos, bem como o lisp-paredit. Eu costumo entrar em “View Installed Packages”, e dentro do proto-repl e do lisp-paredit eu removo os keybindings (de-selecionando o check Enable da área Keybindings de ambos os plugins). Agora, você provavelmente vai querer um atalho para mudar o modo “strict” do paredit, e atalhos para clojure. Então, abra seu arquivo de keymap, e vamos adicionar alguns. Nesse caso, eu vou adicionar keybindings compostos – “ctrl+espaço” vai ser o principal, e podemos usar outra tecla pra fazer o que queremos (ou seja, se você quiser se conectar no REPL, basta apertar “ctrl+espaço” e logo depois digitar “c”):
(more…)

Meu workflow em Clojure

Há algum tempo postei sobre LightTable e Clojure, e embora minha opinião sobre essa nova forma de programar não tenha mudado, algumas coisas infelizmente mudaram bastante. A primeira foi o esquema de plug-ins do LightTable. Ele tem poucos plug-ins úteis, e alguns dos que existem não funcionam com as versões Read more…

Clojure, gentilmente

Nos últimos posts eu percebi que me empolguei um pouco no assunto Clojure. Então, esse é um post para tentar começar com a linguagem, ao invés de tentar entender detalhes. Vou atualizar os outros posts para indicar que esse é o primeiro da série, apesar de estar por último…

Clojure é uma linguagem baseada em LISP. Isso, pra muita gente, significa parênteses intermináveis e sintaxe horripilante. Mas não é bem assim.

Os parênteses são um desafio, um degrau. Então ignore-os por enquanto. Use um editor com suporte ao parinfer – Atom ou LightTable. Acho que o vim também. Isso vai tratar de manter os parênteses em sincronia, baseado na indentação, e também de forçar você a entender a indentação de Clojure. A partir daí, é entender por que esses parênteses existem. Então vamos lá:

Em LISPs, ou seja, em Clojure, parênteses nunca são opcionais. Nunca. Então nem tente resolver seu código com “vou tentar colocar um parênteses aqui” porque não vai funcionar. Você sempre abre um parênteses quando você vai chamar uma função ou special form, ou macro. A soma, multiplicação, divisão e subtração (+ * / e -, respectivamente) são funções. Concatenação de strings (str) também, bem como map, reduce, split e join. Já o if não é uma função – é uma special form, bem como fn* (retorna uma nova função) e def (define novas variáveis, que os LISPs gostam se chamar de símbolos). E o or, o and, e o defn são macros. Para poder usar todos eles, sem exceção, você tem que abrir um parêntese.

Primeiros passos

Para somar 4 números, abrimos um parêntese e o primeiro elemento é a função da soma. Ou seja:

(+ 5 3 9 7)

Isso vai somar os quatro números. Normalmente deixamos grudado ao parêntese a função que vamos rodar.
(more…)

Clojure e simplicidade

AVISO – me empolguei um pouco nessa postagem, para uma introdução mais gentil, verifique o post após esse.

Qualquer linguagem baseada em LISP, como Clojure, tem o mesmo problema: as pessoas falam de como a linguagem é fantástica, como ela revoluciona como você programa, até o momento em que você resolve entender por que. Aí você estuda a linguagem, aprende uma ou outra coisa, e não entende porque as pessoas falam tão bem dela.

Esse ciclo se repete várias vezes, e várias vezes, e você nunca entende o motivo das pessoas falarem tão bem. Até um dia em que você finalmente entende – e é aí que você vira uma dessas pessoas que falam bem, mas ninguém mais entende por que.

Clojure é, basicamente, um LISP que roda sobre a JVM. Porém, diferente de common LISP, Clojure possui duck typing – LISP não. É essa foi a primeira realização – tipagem dinâmica não implica em duck typing.

Ruby, JS, e Clojure possuem métodos (ou keywords, ou funções) que rodam sobre qualquer tipo que atenda aquele protocolo. for element in array, por exemplo, roda em Ruby e JS da mesma maneira para Arrays, ou para Objects (em JS) ou Hash, Set, para Ruby. Em Ruby, é porque todos implementam o método .to_a. Já em Clojure, o nth serve para pegar um elemento de uma coleção qualquer, seja ela uma List ou Vector, usando (nth ["some" "elements"] 1). E como é isso em Common LISP? Bom, se for uma List, usa-se: (nth 1 '("some" "elements")). Se for um Vector, com (aref (vector "some" "elements") 1). E assim por diante (o que quer que isso signifique nessa situação, já que nem posicionamento dos parâmetros nem nome das funções é consistente).

A segunda coisa interessante de Clojure é a sua “sintaxe”, ou na verdade, ausência de sintaxe. Na prática, a sintaxe não existe – você programa definido diretamente as S-Expressions, como se fosse uma lista de comandos. Por exemplo:

; uma definição de uma função
(defn sum-ages [people]
  (reduce + (map :age people)))

; uma definição de uma lista
`(defn sum-ages [people]
   (reduce + (map :age people)))

A segunda expressão, apenas pela presença de um “quote”, torna-se uma lista. O primeiro e segundo elementos são Symbol, o terceiro elemento é um Vector que contém outro Symbol, e o quarto elemento é outra List: (reduce + (map :age people)), e assim as coisas continuam. Symbols, em Clojure, serão convertidos em sintaxe mais cedo ou mais tarde, então defn será clojure.core/defn, e chamará a função, símbolo, ou special-form desse nome mais cedo ou mais tarde. E isso é uma coisa fantástica pelos motivos que veremos a seguir. Mas o primeiro deles é bem óbvio: você não tem códigos – apenas dados. E como a linguagem é composta de dados, podemos manipulá-la, moldá-la, e alterá-la com macros. Além disso, Clojure é uma linguagem muito simples – ao contrário por exemplo, de Ruby, aonde a linguagem é complexa, mas programar nela é simples, em Clojure a linguagem é simples, mas programar nela é um pouco mais complicado.

E o motivo, por mais absurdo que pareça, é que nós, programadores, aprendemos a programar de forma errada
(more…)

Programação funcional, imutabilidade, e previsibilidade

O post de hoje é uma introdução à programação funcional, para podermos entrar finalmente em Clojure. Mas antes disso, vamos falar sobre como aprendemos a programar na faculdade, em cursos, e em todos os lugares. Vamos falar de “orientação a objetos”, principalmente, e vamos falar sobre “abstração”. A programação, como sabemos, é um exercício total de abstração – ao fazer um software, temos apenas um objetivo – fazer com que um trabalho, que provavelmente seria realizado de forma ineficaz ou manual, torne-se automático. Parece uma super-simplificação, mas é verdade. Processadores de texto substituem máquinas de escrever, editores de imagem automatizam vários trabalhos de restauradores, pintores, e desenhistas, e sistemas de folha de pagamento substituem o trabalho de vários matemáticos, contadores, etc. A profissão de todos continua válida – apenas simplificamos um pouco (ou MUITO!) o trabalho deles. E o nosso trabalho, de programadores, é simplificado com linguagens mais modernas, nas quais se escreve menos e se sub-entende mais. E para isso, precisamos aprender a escrever nessas linguagens. E aí entram os cursos, ou a faculdade.

Basicamente, aprendemos a programar nesses cursos, ou na faculdade, pensando em orientação a objetos. Para muita gente, essa é a única maneira sadia de se programar – afinal, orientação a objetos é o paradigma que representa melhor o mundo real, uma frase que muito se ouve. E essa frase é verdadeira, mas com uma pegadinha muito difícil de encontrar: o mundo real é um lugar complicado.

Esse será um post grande, portanto, está dividido em partes. Falaremos sobre a imprevisibilidade, depois mutabilidade e imutabilidade, e na última parte teremos exemplos em Ruby e Clojure sobre trabalhar com dados mutáveis e imutáveis.
(more…)

Clojure, LightTable, e uma nova forma de programar

Esses últimos meses tenho estudado Clojure, ClojureScript, e me entendendo com o ecosistema de tudo isso. Mas sobre a linguagem fica para outro post. Por hora, vamos a uma frase famosa: A language that doesn’t affect the way you think about programming, is not worth knowing, ou Uma linguagem que não afeta a forma que você pensa sobre programar, não vale a pena aprender. Essa frase, de Alan Perlis, mostra muita coisa do que eu penso antes de aprender uma nova linguagem, e vai explicar muito ao aprender sobre Clojure.

Antes de mais nada, vejamos como as linguagens evoluíram – C++ e Java são linguagens orientadas a objeto. Ruby, Python, e Scala também. Mas vejamos como usar uma lista em Java: abrimos o Java, numa IDE lenta como o Eclipse (que precisa de instalação, etc), importamos a lib…. qual lib mesmo? Bom, entramos num Javadoc, procurarmos a lib…. isso em C++ é pior ainda, já que em Java, pelo menos a IDE completa automaticamente os métodos (e algumas vezes, até os imports) pra nós.

Em Scala e Ruby? Abrimos o console, criamos uma lista, atribuímos a uma variável e digitamos: variable., seguido de alguns tabs e o console completa para a gente. Esse é o poder de um REPL (Read-Eval-Print-Loop, ou console, IRB, etc), e o REPL muda completamente a forma de escrever, explorar, entender e até mesmo de pensar em programação. Precisamos um dado no banco de dados? Entramos no REPL, digitamos User.create!(login: “foobar”), e voilá – temos um objeto criado. Não precisamos criar uma tela de cadastro para criar esse dado, não precisamos abrir o gerenciador do banco, etc.

Isso, com Clojure, é elevado ao limite.

(more…)

Alguns meses com CoffeeScript

Recentemente, resolvi testar o editor Atom… Mas isso eu já falei em outro post.

O que eu vim falar agora é sobre CoffeeScript, e a forma como eu tenho programado recentemente envolvendo Javascript.

Estando no mundo Rails, é bem comum a gente acabar usando as ferramentas que o Rails nos disponibiliza. Embora seja uma boa idéia no começo, há uma tendência a ficarmos meio “engessados” numa única tecnologia. Então, resolvi começar um projeto meio ousado de fazer uma UI inteira em HTML + CoffeeScript, sem a intervenção do Rails, e por hora, nem sequer com backend. Talvez eu fale sobre isso num post futuro, mas especificamente agora quero falar de Coffee.

Eu nunca gostei de CoffeeScript, na verdade, por causa da idéia de “indentation-based”. Outra coisa do Coffee é que ele basicamente não faz milagres – tudo no fim das contas é Javascript, e é essa a parte difícil e chata de entender.

(more…)