Pseudo Associative

Random thoughts on software development

2 notes

Some thoughts on Clojure vs Go

Neither Go nor Clojure are object oriented in the sense that they provide implementation inheritance. With Go you can create what it essentially classes without inheritance. Created with keyword “struct” in Go. These “classes” can used wherever an interface is required if a subset of the classes methods match all the methods defined in the interface.

In similar fashion Clojure has what is called a data type created with keyword “defrecord”, which is similar to a Go “class” in that it does not support inheritance. But while a Go “class” automatically implement any interface  which is a subset of its methods, in Clojure you have to specifically list which interfaces a Clojure “class” implements:


(defprotocol Payroll
  (paycheck [emp hrs]))

(defrecord HourlyEmployee [name rate]
  Payroll
  (paycheck [emp hrs] (* rate hrs)))

(defrecord SalariedEmployee [name salary]
  Payroll
  (paycheck [emp hrs] (/ salary 12.0)))

In Go listing implemented interfaces is neither possible nor needed:


type Payroll interface {
  paycheck(hrs int)
}

type HourlyEmployee struct {
  name string
  rate float
}

func (emp HourlyEmployee) paycheck(hrs int) float {
  return emp.rate * hrs
}

type SalariedEmployee struct {
  name string
  salary float
}

func (emp SalariedEmployee) paycheck(hrs int) float {
  return emp.salary / 12.0
}

Since Clojure doesn’t really have methods per say, you can’t define other protocols with the same function names. That would just override the meaning of that function. This should not necessarily be interpreted as Clojure being less flexible then Go here. Clojure has a number of different ways to dispatch a function call based on the type or value of the arguments.


(defmulti paycheck :type)
(defmethod paycheck ::hourly-employee [emp]
  (paycheck [emp hrs] (* rate hrs)))

(defmethod paycheck ::salaried-employee [emp]
  (paycheck [emp hrs] (/ salary 12.0)))

I am not going into the details but we assume here that emp is hash table with a :type key. Multimethods allow dispatch on multiple arguments. However given two existing unrelated classes A and B, you can define an interface C in Go which covers a subset of methods in both A and B and then you can define a function f(obj C) which can do similar processing of some instances of A or B. This approach is a bit more involved in Clojure. You would probably have to define a new set of multimethods which in effect would represent interface C. These functions would have to forward to the correct function for A or B.

Beyond this Go starts falling short of the flexibility of Clojure for building abstractions since Clojure is a LISP and thus supports powerful means of abstraction like macros. There is nothing remotely similar in Go.

Go on the other hand is more capable when it comes to low level tuning of your application. Memory layout of datatypes can be controlled in detail which is not possible in either Java or Clojure. This is quite important given that cache is increasingly important to the performance of applications. In Go it is easy to place elements accessed together close in memory so that they are likely to be pulled into the cache at the same time.

IMHO that means Go is more poised to take over areas traditionally dominated by C/C++, while Clojure will be fighting in areas currently dominated by Java, C# or script languages, like enterprise systems. E.g. Go wasn’t designed to be used for game engines but I can imagine if a game engine developer had to chose they’d chose Go over Glojure, simply because they want much more low level control over their resources. In other respects they are overlapping in appeal. At Google there seems to be C++, Java and Python mainly used. For most tasks Python will simply be much quicker to use. When more performance is needed Java or C++ is used, which requires longer development time. Go appeals to those who want Python like ease of programming with C++ like performance. But Clojure gives Java like performance for those who want Python like ease of programming. Well, not entirely true but it can be tuned to get close and it is in perhaps most respect more powerful and faster to develop in than Python.

Who will succeed? Clojure advantages:

  1. Part of the huge Java ecosystem.
  2. Support more powerful abstraction mechanism.
  3. Functional programming is gaining momentum and developers might see it as crucial that their next programming language supports this paradigm.
  4. Support for REPL based development. Basically this means you can interactively develop a program. Clojure like any LISP gives you a sort of command line shell were you can write clojure code and test calling individual functions. You can load a file with clojure code into the shell and call individual functions to test them or redefine some of the function while the program is running.

Go advantages:

  1. Syntax which is much more familiar to most developers. And we know this has been very important for the success of languages in the past.
  2. More options for performance fine tuning (memory layout).
  3. Imperative programming paradigm is better known and understood by the majority of developers.
  4. Huge organization behind it (Google).
  5. A very easy to understand concurrency model. Clojure also has great support for concurrency. Probably better in many ways, because it gives more options and is a functional language. However goroutines used for concurrency in Go is just dead simple to get started with.

I love LISP’s but my prediction is that both Go will become bigger than Clojure eventually. Simply because I don’t know of any time where a language with unusual syntax became a big success. Smalltalk, LISP, Objective-C etc never became big successes, mainly due to their unfamiliar syntax IMHO. I am guilty of this myself. I looked at Objective-C very early on when I had started learning C++ and rejected it almost immediately because I thought the syntax looked so weird. As a young developer I confused complexity of language with syntax. I had the crazy idea that C++ was somehow a simpler language to understand than Objective-C, because it looked more like C. This seems to be a common fallacy.

  1. assoc posted this