Atom packages with ClojureScript – upgraded

Last time I talked about plug-ins in atom with ClojureScript, I was using Weasel. Since then, I tried figwheel but it never worked as good as I wanted.

Then, I’ve decided to try shadow-cljs. Also, with shadow, we can build a node library instead of a “generic node application”, and this helped a lot in my current tests. So, right now, I’m going to show how I am developing the next version of Clojure Plus plug-in, and what to expect in the future.

Also, I must add that this is so far the best experience ever on creating Atom packages, so I’ll probably stick with ClojureScript for every future package too (I just need a way to make atom’s spec tests work better with ClojureScript – I’m thinking about using a helper library or something).

Preparation

First, you’ll use atom to create a package. It doesn’t matter if you produce a CoffeeScript or Javascript version, because we’ll delete all source files.

On package.json, we’ll modify the entrypoint: on the key "main":..., we’ll write "main": "./lib/main".
(more…)

Understanding Ruby’s Awesome Nested Set

Recently, I saw people migrating from Awesome Nested Set to Ancestry. The reasons are simple – Ancestry is very simple, it just need a new string field in your table, and it’s easier to reason about. So, why should I even consider to use an alternative?

The answer is simple, and I’m going to quote H. L. Mencken: For every complex problem there is an answer that is clear, simple, and wrong.

And the reason that using Ancestry is a bad idea is simple: it doesn’t reflect good design. It treats a single field as a multi-valored column that keeps the ancestry of your object. This means that there’s no way to fetch all records AND their parents in a single query, or fetch all records AND their children, because we need to split the string (ruby-side) and then create a query (also ruby-side). So, in this post, I’ll show some tricks of what we can do with Awesome Nested Set, or even beter, how does it implements the tree pattern (and why it calls it a “set”, not a “tree”).

First, when we think about categories and sub-categories, we think like this:

But this is, in fact, a terrible way of representing trees in SQL. So, the alternative, is to transform it in a group of sets: Parent 1 (P1, for short), is a super-set containing subsets C1 and C2 (Children 1 and Children 2, for short). Each of the children have its own grandchildren, so C1 is a super-set containing G1, and C2 is a super-set containing G2 and G3.


(more…)

Clojure with SQL databases

There are times when a specific piece of technology captures my attention in such a way that I feel the need to study more, and do things with it. Since I began to study Clojure, and after two jobs working with it, I’m still in love with it – I think it matches what I expect in a language most of the time, and also matches my repl-driven-development workflow.

So why I’m not considering it for new projects? Even personal ones?

When I need to prototype something really fast, I end up going for Ruby, with Sinatra (sorry rails, but you’re a terrible choice for me). I saw that in my last project, I worked with Sequel, postgresql, and Sinatra. For tests, I used VCR and recorded the external api calls that I had to make.

Well, I could probably prototype a simple VCR that would record a specific function call in Clojure. Sinatra, I could use Compojure. As for Sequel… Or ActiveRecord, for that matter…

There are a few libraries that can be used to communicate with SQL: Korma, that doesn’t support select ... for update and have some implicit connection problems and other issues, HoneySQL that interprets Clojure maps and converts then to SQL, and lots of other libraries that simply ask you to write your query and then, somehow, call then for you. I didn’t care too much for the later, after all, if I want to write queries I prefer to not depend on a library that does it to me – I know that there are people that don’t like to have SQL in the middle of the code, but I don’t see any problem with it.
(more…)

Don’t be a Copperfield

After a year and a half working in other languages, I’m back to Ruby. And, one of the things that I was amazed at Clojure is how simple things were.

Back to Ruby, I’m really surprised on how people overcomplicate things.

There’s no perfect language, nor perfect community of languages. In Clojure, there are fewer abstractions, which is not exactly a good thing – if you, let’s say, just want to create a simple page to show data from a database, you’ll find it extremely tedious to do it in Clojure, where in Ruby/Rails it’s just a few lines of code away. Ruby’s moto is “programmer happiness”, and this reflects in every library that they write.

But this kind of higher abstraction pays off with time. At least where I live, working with Ruby means working with Rails almost all the time. There are no “big competitions” for Rails or ActiveRecord (Sequel is a close one, but at the time of this post, AR have 10 times more downloads than Sequel), and other web frameworks are mostly “Rails-like”. But what bugs me most is “magic”.
(more…)

Two new libraries in Clojure

Last week, I was looking to some old code I wrote in my last job and my spare time. Then, I’ve decided to publish two new libraries for Clojure and ClojureScript.

One is Paprika, available in Clojars at version 0.1.0-SNAPSHOT.

The other is Check, also available in Clojars (but at version 0.0.1-SNAPSHOT).

The reason for the early publishing is to push forward some simple libraries to fix a simple problem that I had while working with Clojure: the absence of abstractions.
(more…)

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