Please, use the right terms for “typing”…

Names matter. That’s one of the things that I learned, working multiple years on programming software. When you have something called “integration”, for example, that means different things for different people, that’s a recipe for disaster.

That’s why I get quite triggered when people use Untyped / Typed, Weak / Strong typed, Uni / Multi typed, to describe programming languages – because it means different things to different people, or are simply wrong. So let’s dive into it:

Untyped languages or languages without types are quite rare: Assembly is the most interesting example (there’s literally no types in Assembly: everything is a memory address, byte, word, etc). Some virtual machines’ bytecodes are also untyped. In this case, most languages are typed. Ruby, for example, have types, and you can dispatch different behavior depending on the type of the caller (because it’s a class-based object-oriented language). Clojure is also typed, because you can do type-based polymorphism with protocols using defprotocol and defrecord for example. You can also use deftype, and if there’s a specific command to define types, how can we call it “untyped”?

Weak / Strong typed is a term that’s hard to define. Some people say that it’s when you have pointers, because you can bypass the typing at all; others, when the compiler erases typing at run-time; some say that’s when the language tries to coerce and implicitly convert from one type to another, to try to figure out what you want…

Now, a language that allows you to bypass typing because you have pointers is called “memory unsafe”; if the compiler erases typing information, is called “type erasure”; coercion of course is called “coercion”, and can be “automatic” or “manual” coercion (for example, most languages try to coerce integers to decimals at some point); even the ability to convert between types is controversial: on Ruby and Scala, operators are also methods of the class (and, on Ruby, you can rewrite methods on classes that already exist, so automatic conversion is a user-defined feature) – so, please use the right term.

Unityped means a language that only have one type. I believe only some markup languages enter on this classification. Calling a language that have multiple types as unityped because someone imagined that all these multiple types can somewhat collapse into a single one is, at minimum, strange; and also, again, we do have a term for languages like Javascript, Ruby, Python, Smalltalk, and Clojure.

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.