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…)

We need a better way to write SQL

For some time now, we’ve been working with SQL to communicate with database systems. What we learned in these years is that SQL is not a good way to query data, and I’m going to explain why.

SQL should be a standard way of querying data, but most programmers have learned (probably the hard way) that most of databases implement SQL in a different way. What is means in practice is that any time we need to change databases we will face lots of incompatibilities and queries that simply won’t work as we expect. But this is only the beginning of our problems…

We tried lots of ways to solve this kind of problem, one of them migrating to ORMs. But, ORMs in fact solve a different problem – the one that relational databases work with row-column structures, and our programming languages use objects, hash-maps, records, and other richer ways of representing data. Ruby’s ActiveRecord was a huge step forward, promising us to deliver value simplifying our relational-object mapping, but in the end we faced the same problems – incompatible queries, SQL fragments being thrown in the code, and in the end, we ended up with another huge kind of problems – performance, complexity, and separation of concerns problems (a single ActiveRecord mapping is responsible for validation, for queries, and to define business logic). Even worse, the Arel promise (a complete library to abstract every possible SQL query) was underused – it’s now an internal library to ActiveRecord, it doesn’t really have a stable public API, and in every minor version, something changes in a bizarre and incompatible way.

So, I’ve started a simple project named relational. In the beginning, it was just a playground to learn Scala. But, right now, and faced with modern problems (I’m working with Clojure, and it doesn’t really have a good way to query relational databases – Korma is incomplete in multiple ways, HoneySQL doesn’t really delivers what I want, and other libs are just wrappers around string queries), I’m implementing a version of Relational in Clojure, and the reason I’ve started working on it is kinda simple…

SQL isn’t a standard.

Okay, if we just want to query all data from a single database, inner-joining with other, just listing the fields, it’s completely fine. Add SQL functions and pagination, and we’re in a pinch – for instance, the standard way of limiting the result to just 100 rows is:

SELECT * FROM table FETCH FIRST 100 ROWS ONLY

I don’t know a single person who wrote this kind of query, simply because almost no database supports the standard – in PostgreSQL, MySQL and Sqlite, it’s written as:

SELECT * FROM table LIMIT 100

In Oracle, it is

SELECT * FROM table WHERE rownum < 100

In Microsoft SQL Server, it is

SELECT TOP 100 * FROM table

And don't even start with GROUP_CONCAT or other strange SQL functions…
(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…)

Mudanças no Blog

Esse será um post rápido sobre pensamentos aleatórios e alguns desabafos. Nos anos que tenho esse blog, percebi que as coisas não são fáceis para quem quer trabalhar seriamente com desenvolvimento de software. Primeiramente, o mercado brasileiro ainda é muito atrasado e engessado nos antigos paradigmas – analista, desenvolvedor, e Read 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…)

Minha estadia no Nubank

Ultimamente eu tenho estudado muito de programação funcional, principalmente em Clojure. E nada melhor para estudar uma linguagem do que se aventurar num emprego em que se usa ela, certo? 

Foi assim que eu fiz o processo seletivo no Nubank. E passei, e comecei a trabalhar em maio.

Muitas coisas foram diferentes para mim nessa pequena jornada. A primeira empresa em que o atendimento ao cliente está muito próximo do dia a dia, a primeira empresa com muitos funcionários, a primeira empresa que opera com muito investimento, a primeira empresa que usa intensivamente micro serviços, e a primeira empresa em que eu, de fato, fui demitido (e não que eu pedi demissão). 

Apesar de tudo, eu já tinha meus planos de sair. Mas isso não vem ao caso, nem vem ao caso as circunstâncias que levaram ao acontecido. O importante é o que fica, e as coisas que eu aprendi. 

Pela primeira vez na vida eu trabalhei com microserviços, e pela primeira vez eu consegui ver a vantagem real de uma linguagem funcional nesse processo. Há muito tempo atrás, no mundo de Ruby, uma implementação chamada Maglev prometeu entregar persistência de objetos Ruby completos, inclusive exceptions. O Maglev mesmo nunca foi muito utilizado, mas essa ideia de persistir exceptions e sessions e depois reproduzir o bug simplesmente pegando a session e replicando os passos que causaram o erro ficaram na minha mente. 

Quando eu trabalhei com microserviços, era exatamente isso que eu fazia – cada ponto de entrada em um serviço era um conjunto de dados, e como a maior parte das coisas era imutável, se algo dava erro a mensagem era rejeitada, e depois podíamos simplesmente chamar o mesmo entrypoint com a mesma mensagem, e garantir que a mesma exception ocorreria. Se fosse algum erro de comunicação com banco de dados ou com outro entrypoint, nada de errado ocorreria – e aqui entra a segunda coisa diferente.

Para suportar todas essas características, todos os entrypoints tinham que ser indepotentes – ou seja, se uma mesma mensagem fosse enviada para ele duas, três, ou quatro vezes, o entrypoint se compraria como se tivesse recebido apenas uma. O importante aqui é não depender de um id de mensagem ou qualquer coisa assim – é importante que a mensagem inteira seja responsável por ser indepotente.
(more…)

Quick post – Motorola não carrega

​Um dia desses o celular de minha esposa, um moto G segunda geração, ficou se bateria e desligou. Até aí, tudo normal. 

O problema é que deixamos ele carregando a noite inteira e com o carregador original, e no dia seguinte, um Led branco estava piscando e nada do celular carregar. Detalhe interessante que eu nem sabia da existência desse Led… basicamente, esse é um quick post para recuperar um Android nesse caso. 

O primeiro ponto é que isso é normal em androids da Motorola. Parece um bug que eles não corrigiram até hoje. A solução (tanto para Motorola como qualquer outro celular Android) é entrar no modo fastboot

No caso da Motorola, faz-se isso segurando o botão de ligar junto com o de baixar volume por uns 5 a 10 segundos. Especificamente no meu caso, eu segurava os dois botões por uns 10 segundos depois soltava apenas o botão de ligar (mantendo o baixar volume apertado), e aí ele iniciava o fastboot

Esse modo é bem simples – ele tem meia dúzia de informações sobre o Android, e você pode selecionar as diversas opções usando os botões de volume e confirmar com o botão de ligar o Android. Mas na verdade, para recuperar um Android nessa situação, você vai querer conectar ele na saída USB de um computador – no plug na tomada não funciona.

Feito isso, na tela do fastboot, aparecerá uma informação de battery low, charging. Deixe assim por pelo menos uma hora, e só depois reinicie o celular. 
(more…)

Empregos, Linguagens, e Identidade

Quando eu comecei esse blog, eu dei o subtítulo de “diário de um rubyista”. Quase imediatamente eu mudei para “diário de um desenvolvedor de sistemas”, e agora estou mudando de novo.

Existe um motivo pra isso, assim como existe um motivo para um monte de coisas que fazemos e que não nos damos conta. Conforme o tempo foi passando, muitas coisas mudaram na minha vida pessoal e profissional, e me fizeram repensar minha própria identidade.

Talvez esse pareça ser um assunto muito filosófico pra um blog técnico, mas de qualquer maneira, acho importante que ele seja mencionado. Eu conheço muita gente que se deixa definir pela linguagem que usa. Há vários blogs online que, por exemplo, se recusam a aceitar críticas da sua linguagem preferida, de seu framework, num nível que parece irracional. Na verdade, Martin Fowler já falou sobre isso num artigo simples chamado keep your identity small. E é sobre isso que eu vou falar.

Muitas coisas aconteceram desde que comecei a escrever nesse blog – a ideia original dele era divulgar coisas interessantes, intermediárias para avançadas, para um público que fala português – e esse último detalhe é importante também. Por que meus subtítulos do blog foram “diário de um rubyista”, quando não era esse o intuito do blog, é algo que eu não sabia dizer – até agora.
(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…)