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.
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?
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.
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.
So I went ahead with ClojureScript.
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.