Yan Han's blog

On Computer Technology

15 Jun 2014

Announcing: cljs-nusmods (alpha release)

Update Dec 2017: This project is long dead. And it will stay dead. Like a lot of things I have built in the past, this is one of those things that I eventually just lost interest in. And in this case, eventually is just a few short months.

Like many other posts that have become irrelevant over time, I am keeping this one for old time’s sake.

I’ve been a long time fan of functional programming, and it is my pleasure to announce the alpha release of cljs-nusmods, a project I’ve been working on for the past 2 months during my free time. You can probably deduce from its name that it is powered by ClojureScript. I’ve made it a goal to release this alpha version by 15 June 2014, but by the time this blog post is done it’ll be 16 June. Lol.

Working demo: http://cljs-nusmods.pangyanhan.com

Github repository: https://github.com/yanhan/cljs-nusmods

For those of you know NUSMods, cljs-nusmods will seem eerily familiar. In fact, cljs-nusmods is based on NUSMods, and tries to mimic it as much as possible. I’d like to thank Beng for making his NUSMods project open source and for creating the NUSModsAPI project; this project would very likely not be possible without your great contributions to open source and to the NUS student population.

That said, I’ve tried as much as possible not to look at the implementation of NUSMods. As such, if one digs into the innards, the implementation of both will likely look very different.

Why another NUS Timetable Builder

Let’s just say that everyone has things that he/she wants to do in their life. To me, writing this piece of software is one of them. I also needed a project to work on, after all it’s the best way to learn a new language, and I’m very bad at coming up with original ideas. This project seems to be a right fit - it’ll be eventually doable (since someone has already done it), yet be very challenging at the same time.

Why ClojureScript?

cljs-nusmods is purely a personal project, with the explicit aim of using ClojureScript for a front end web application. So you might ask, why ClojureScript?

First of all, I’ve been dealing with JavaScript for a while and I honestly do not like the language. Despite its widespread use and availability, I only use it when I have no choice (such as when working on someone else’s projects) or for writing small programs involving a lot of JSON manipulation, where it is clearly the language of choice.

Some of you may argue that JavaScript is not that bad if you only use the good parts, and yes, it is not that bad, but it is not that good either. There is an increasing use in JavaScript over these few years, and despite its flaws as a language, an ecosystem of libraries are out there that make things a lot better. Despite all the nice libraries out there, whenever I write JavaScript code, I just feel that things do not have to be this way; they can be a lot better. What if I could get the goodness of JavaScript (huge ecosystem of libraries) without using the language?

In fact, that is no longer a fairy tale. The rise of JavaScript has seen the rise of programmers who like me, do not like JavaScript, yet have to use it; but unlike me, they are so highly skilled, they can make a computer generate the JavaScript for them by writing a program that takes a different input language and outputs JavaScript - a compiler. Enter the world of JavaScript alternatives.

I’ve been looking at JavaScript alternatives for a while; there are lots of them. Among the more promising ones (based on what little I’ve read) are:

Nope, CoffeeScript is not one of those alternatives I considered. In fact, I’d rather use JavaScript than CoffeeScript.

If you look at the list above, Fay and Elm are both Haskell based languages. In fact, it was most probably this article on the Haskell wiki, The JavaScript Problem, that sowed the seeds of my rebellion against JavaScript, and eventually culminated in cljs-nusmods.

I’m a rather big fan of functional languages, so that leaves out Dart and TypeScript. I didn’t have a good experience with OCaml from a class I’ve taken, and while I’ve tried a bit Scala and am a fan of types in general, Scala is quite the beast of a language. So only one of the Haskell JS derivatives and ClojureScript remains.

If I were sufficiently confident, I’d go ahead with one of the Haskell JS derivatives. However, I’ve had a shaky experience with Haskell - having learnt the language on and off for several years, not using it much, and finding it rather hard to use in production settings. The Haskell JavaScript alternatives also feel rather unstable and incomplete to me - I wanted to do something “real”

On the other hand, Clojure is sufficiently close enough to the Lisp family of languages to not pose such a big barrier, since the first programming course I took at NUS was taught using Scheme. I still remember writing a lot of Scheme code for that course on pen and paper; it was one of the very few languages that I wouldn’t mind doing that. Of course, those were very simple programs compared to things I’m dealing with now; but still, Scheme has always felt like a simple language to me.

Clojure is a modern Lisp, and takes a very functional approach to things. Furthermore, ClojureScript supports the use of JavaScript libraries, with great wrapper libraries such as jayq available. It uses the Google Closure Compiler and with advanced compilations, efficient JavaScript code can be generated. Of course, getting advanced compilations to work with JavaScript libraries that were not written with Google Closure in mind (almost all of them) turned out to be a different story, but I kind of figured that one out. Kind of.

So I went ahead with ClojureScript.

On hindsight

On hindsight, I think was a very good choice to use Clojurescript. My experience with Scheme paid off; Clojure felt a lot more modern than Scheme and Common Lisp and I did not have to go through the Lisp fear/shock factor (of seeing parentheses on the different side of code than one is used to). After writing this bit of ClojureScript, I have to say that Clojure is a very well designed language. It’s quite safe to say that most of the pain points I’ve faced working on this project do not lie with Clojure as a programming language; this is actually a rare thing for me - I tend to see the flaws of programming languages quickly, and so far Clojure has been really pleasant. Of course I need to write more code to find out if that is really the case =P

At work, I have a colleague whom I talk to on technical topics, and in recent times he’s taken an interest in Clojure. In fact, I rewatched Rich Hickey’s Simple Made Easy talk after he showed it to me. To be honest, I didn’t really get the big deal about Rich Hickey’s points the first time I watched the talk (which was several years ago). When I watched the talk for a second time (after having more experience than the past me, and having some Clojure experience through this project), I felt like I had only barely begun to understand the talk. That made me feel that I’ve made the right choice in using ClojureScript. Anyways, do watch the talk; it’s awesome.


Currently, the source code for cljs-nusmods is rather ugly and nowhere near purely functional. That said, I’ve tried my best to stick to being functional. I’m also pretty new to Clojure and ClojureScript, so much of the code is probably non-idiomatic. There is a lot of refactoring to be done, and many features have not been implemented. I’ve put in a lot of console.log with some weird messages to aid debugging, and I’ve left a few Git commits labelled [TEMP COMMIT] and didn’t bother to rework them because they were too far back. However, there is something we can play around with, and that’s what’s important.

Once again, I’d like to thank Beng for making his NUSMods project open source. cljs-nusmods will have taken a very different path without it. Thank you Beng!

Disclaimer: Opinions expressed on this blog are solely my own and do not express the views or opinions of my employer(s), past or present.

comments powered by Disqus