I notice my pace has yet again slowed between the last chapter of the book – Erlang – and this one. Another five months has passed since I finished the chapter on Erlang! In actual fact, I haven’t been slaving away on the next language that whole time – decompression of sorts has to follow each chapter, and dealing with a manic three-year-old, finding some time for a bit of exercise and trying to learn a spoken language (German) all take a decent amount away from my free time.
The sixth chapter of Seven Languages in Seven Weeks is Clojure – a challenging language, but after getting through the previous five chapters this one only took me about three weeks of real world time (spent on-and-off) to conquer the last exercise of the chapter.
Since I tend to ramble on about the experiences I had while learning the new language, I’m going to break it down into a series of (hopefully) short points – what I liked about it and what I disliked. Do bear in mind that I’m no expert in Clojure, with only a brief learning period dedicated to it.
What I liked:
- It seems to have everything. The transactional memory support, power/libraries/community of the JVM, and many programming paradigms baked into the one language. This felt a lot like my experience with Scala, and I’m not sure if it is due to the JVM powering the runtime or the intents of the creators of the language.
- What I learned previously about how to best utilise recursion from Prolog and Erlang was also quite applicable here (albeit in slightly different form using loop/recur).
- The Leiningen tool and its REPL make getting into Clojure relatively easy, without having to initially bother with much of the JVM-required compilation/classpathery stuff (which frankly, I still don’t understand).
- After just a small amount of time, the initial perception of it all being a mountain of parentheses dissipates reasonably quickly (but not entirely). Prefix notation is actually not that bad.
What I disliked:
- Despite my last point in the section above, parentheses and punctuation remain a big problem to newcomers to the language. If you are not used to Lisp-based languages, there is a big learning curve here. Similar to Scala, I found the large amount of other punctuation (which is used extensively in the language core as well) to be quite hard to understand. Some areas that provide interoperability with Java also have their own unique operators which makes it even harder to wrap your head around.
- There are often several ways to do things which are not obvious to a newcomer (e.g. creating classes with deftype vs defrecord vs a regular map, or when to use atoms vs refs vs other blocking data structures from the Java library). Some are still listed as experimental alpha features. Fortunately there are plenty of resources out either via Google or Stackoverflow.
- The language is powerful and sophistication, but I think this requires a corresponding amount of sophistication on the part of the programmer to use it without constructing a monstrosity. Macros take a while to wrap your head around (and I still couldn’t tell you with certainty exactly when things need to be quoted and when not).
- Without being very familiar with Java (and its libraries) or the JVM, I felt at a disadvantage. I think a lot of parts of Clojure and Scala are framed in terms of how they wrap around the JVM, or solve a Java problem in a better or more understandable way than simply standing on their own. If you want to use the extensive Java interoperability then you have no choice but to learn how that works and its requirements (and with such extensive facilities on the Java side, it frequently makes sense to use the Java interop).
- To me it just doesn’t feel like a great general-purpose language, but that is probably just because it seems quite academic. I can’t imagine doing very rapid iteration web-app development in it, for example (although I know some people at my work that are doing just that). I guess what it comes down to, is that you would need a lot more experience in this language than you would if you were to pick up Ruby and start developing with Rails for example.
If this all seems like I’m not in favour of the language, that’s not the case at all. Despite its challenges, I see Clojure as a very tempting and powerful language. If I were suddenly in a position where I had to do 100% of my coding in this language, I would see it as a good thing. For the moment though, there are simpler languages that accomplish everything that I need, and I don’t feel the desire to become an expert in every language I have managed to familiarise myself with.
Sidebar: Spoken vs Programming Languages
After doing this much study on a variety of programming languages I don’t use on a day-to-day basis, and having been learning German for a few years now (with varying levels of dedication) I’ve naturally been comparing how learning and knowledge of the two different types of language differs. I’ll preface everything I say below with the fact that I’m not a linguist and haven’t researched this topic academically whatsoever.
Firstly, there exists a certain type of programmer, computer nerd, systems engineer, etc. that will list (somewhat facetiously) their known languages (e.g. on Facebook, LinkedIn etc.) like this – English, German (or some other spoken language), Pig Latin, C, Python etc. etc. Maybe even Klingon. Their argument is that all languages are equivalent and that they know C just as well as they do English. The intent of listing languages in these data fields is usually just for natural spoken languages, but they have mixed the two “types” of language together.
To the majority of us, this argument is plainly false. I recall briefly reading some discussion on this from actual linguists, and at a purely biological level, using spoken languages and computer languages exercise completely different parts of the brain. There are different amounts of reasoning, analysis and plain communication going on depending on whether you are speaking to another human being or expressing an algorithm to a computer.
The grammar of spoken languages is complex, has many exceptions, idioms, and is constantly evolving, whereas in computer languages it is extremely well defined, seldom changes and must be understood by the computer and programmer in 100% of cases. Spoken languages have tens or hundreds of thousands of words, whereas computer languages often have just dozens or hundreds of identifiers at their core. Fluency is defined in a spoken language as basically needing no assistance to communicate with anyone in that language, whether it be spoken or written; even warping the language outside of its usual boundaries while remaining understood by other fluent speakers. Fluency in a computer language, it could be argued, might still permit a user of the language to consult references from time to time. Computer languages are also almost exclusively written, permitting more leisurely consideration of the correct grammar, syntax and vocabulary with which to express one’s self.
This seems like a fairly compelling argument for the two types of language to be vastly different, but recently I’ve been thinking more and more about another level of similarities beyond those points I’ve raised above. I would argue that true fluency in a computer language would in fact allow you to converse (perhaps not exclusively) with another fluent “speaker” of that language in actual spoken words, without aid of references. Anyone who has taken an interview at Google would know the requirement for whiteboarding a solution to a given problem in the language of your choice. You have no option but to be able to express yourself instantaneously, without references, and without making any mistakes – much like natural spoken languages.
Once you take into account all of the standard libraries, commonly used libraries outside of that, frameworks, extensions, plugins etc of a given computer language, the vocabulary is extended dramatically past the dozens or hundreds of words barrier. You can even draw a parallel between learning a given framework in a computer language, and becoming a specialist in a given occupational field – medicine for example introduces a new range of specialist language, just as the next new web-app framework might in your computer language of choice.
When speaking a computer language, the barrier for understandability is actually in some ways higher than than for natural spoken languages with a human partner. A human has the benefit of context, shared common knowledge and culture, observable body language, and can grant understandability concessions when the grammar, vocabulary or syntax is not entirely correct but can be inferred. A computer knows none of these and will not accept anything less than 100% accuracy.
Computers are hard, cold, reasoning machines and computer languages are expressly designed to convey meaning as efficiently as possible and with little room for interpretive error. Spoken languages are the result of centuries or millennia of evolution and culture, not to mention the development and psychology of the human brain itself. In some ways it is amazing that they are able to be compared at all, given their origins are so vastly different.
After dedicating my little free time over the last three weeks to Clojure it is now back to German until I have finished the current teaching book I’m working through. The unifying factor for me personally is that I find learning both spoken and computer languages challenging, mind-bending but exciting. I have no intention of becoming “fluent” in more than a very small amount of programming languages (a passing familiarity is probably sufficient) but I would be significantly upset if I never become fluent in German.
On a related note, if you haven’t yet checked out
Hello World Quiz, it is frustrating but simultaneously a lot of fun 🙂
Well, well, well. One virtual “week” later, but two real world months later, I have finished the chapter on Erlang from Seven Languages in Seven Weeks. Based on the Git repository where I am recording my coding efforts through the book, I’ve been working at it for almost 11 months, which is slightly disappointing, but I have noticed during the chapter on Erlang a subtle shift in how my brain is functioning. Perhaps it is Erlang, perhaps it is the book as a whole, but I do notice that I am considering programming languages in a more balanced, perhaps philosophical way.
After five chapters it is starting to become evident that the languages were presented in a very well-crafted order. Ruby is undeniably the easiest and most familiar to the hordes of programmers out there largely experienced in imperative or even vaguely C-like syntax languages. As a side-note, since we are hosting several RailsGirls teams in the building, we recently started a “book club” going through this book chapter by chapter with these new software developers and some of my coworkers. It is proving very stimulating discussing languages, especially when we have different opinions about them and different experiences. I’m looking forward to hearing others share their delight in features I’ve hated, and vice versa.
So far we have only just finished Ruby and started on Io (which I covered what feels like an age ago). From there it gets progressively more diverse, more challenging by the chapter but each time you reach a new language your thinking has been altered in such a way that the challenges are within reach. This is perhaps a bit abstract so I’ll get back to talking about Erlang, and perhaps my point will become clear.
I find it terribly ironic that I almost bitterly finished the chapter on Prolog, thankful I’d never see that syntax or computing model again, and found it staring my in the face with Erlang. Erlang originally grew out of Prolog so a lot of the syntax is very similar, but somehow after conquering the chapter on Prolog previously, the problems framed around learning Erlang didn’t seem as hard.
That being said, familiarity with the basic syntax only got me so far. The concurrency model, OTP services and supervisors/monitors are a lot to wrap your head around and I found this chapter utterly mind-bending, but in a good way. I gave myself plenty of time (about two months in total) but made sure I finished every exercise, and I believe it was well worth the effort, as I feel I have a much better understanding of how it all works now. It’s not a language I would reach for instinctively, but at least I feel I could navigate my way around it (and we do in fact have some services written in Erlang at SoundCloud). It does intrigue me to know that robust services such as CouchDB and the latest Chef Server have been written successfully in this language.
What specifically did I find interesting about the language?
- The use of Prolog-inspired pattern-matching, guard statements and the catch-all underscore all make for some very interesting ways of expressing data-driven decision-making or branching.
- Function overloading by using different pattern matchers in the input parameters.
- The actor- and message-based concurrency model.
- The various ways of linking and monitoring processes to ensure they robustly resist entire system failure.
- Atoms. I’m not sure what I make of them exactly – they feel a bit like symbols in Ruby, but evidently have a much wider namespace as you can register a process with an atom as its name, then refer to it in different places to where you registered it. But they are definitely convenient.
- The fact that you can send messages asynchronously or synchronously, either by expecting a response only as a return message to another process, or by waiting for return value.
- The slightly different syntax to io:format.
- How you have to do something that feels like force-quitting the Erlang VM to exit (Ctrl-C then q).
Of course these are all observations based on very beginner-usage of Erlang. It has its differences which I find both challenging and interesting, not necessarily flaws. If you’re playing along at home, feel free to check out the code I managed to create while working through this chapter, and of course I’m always interested to read your opinions on the subject so feel free to leave a comment. Onward and upward to Clojure!
Yet another instalment in my journey through Seven Languages in Seven Weeks – this time on Scala. The iteration period has gone down significantly to almost an actual week, so that’s some marked improvement on previous chapters!
I would say that I haven’t even really used Java seriously – what little I did in my university time I’ve forgotten, and I don’t believe I was ever competent in the language. So I’m approaching Scala from what I imagine is a fairly different vector to the typical Java “refugee” (yes, there are actually many blog posts using that exact term). That being said, I found Scala to have a somewhat similar syntax to Ruby and thus familiar in a sense. The strict typing is welcome after programming for quite a few months in Go and the language clearly has some power behind it.
Much like the sentiment in the book in the closing of the Scala chapter, I also found some of the more complicated syntax hard to wrap my head around. The idiomatic patterns seem to leave out parentheses, dots and introduce all manner of curly bracket blocks and closures which are a bit confusing for just a few days of Scala practice. I’m sure I have misunderstood aspects of the typing system, and I was quite confused by situations where Option or Any types were being returned. There seems to be a very powerful functional programming environment lurking under the covers but sadly the book and my practice barely touched on it.
Having grown to love Golang’s channels and goroutines, actors felt quite familiar but in practice behave quite differently. I do like the concept and think I could grow to love the actor model in Scala and many other aspects of the language, but that will heavily depend on what use I have for it. With Golang in my tool belt, it doesn’t seem I’ll need to reach for Scala much at all, sadly.
Yet another installment in my journey through Seven Languages in Seven Weeks. At this stage it is so far off seven weeks, it’s definitely going to be more than seven months, and I’m just hoping it won’t take seven years! But it is enjoyable nonetheless – if a little painful.
Prolog has a deeper hold on me than Io, though. I once took a second year university course on Logic Programming which had Prolog at the very core. The textbook and much of the workload for the course relied on using and understanding Prolog to learn the fundamentals of the course, and I did extremely poorly in it. In fact, I more or less gave up trying to understand and earned the worst grade out of my entire university career in that subject. So this time around I felt that I had something I needed to prove, at least to myself.
All of that said, it was still a big struggle. The paradigm is inherently unfamiliar to me, and it took a long time to understand even the basic exercises. The last couple of days I actually managed to implement something resembling a recursive insertion sort from scratch, which I was relatively pleased with, and the rest of the chapter was at least understandable. Take a look at my Github account if you feel like it – there are a lot of examples from the book and some of my own solutions to the exercises.
Would I use Prolog at my day job? Almost certainly not, but I feel like I’ve at least partially conquered the demons from university and I have definitely expanded my mind. Every time I learn a new language or new paradigm I feel the same exhilaration I did when moving permanently from shell script to Ruby. Now I couldn’t imagine even attempting any given problem in anything less than a complete programming language, and shudder at the memory of some of the horrors I used to write in Bash.
If you haven’t picked it up, I strongly recommend reading and working through this book, even if you don’t consider yourself a programmer (maybe you’ll find yourself one by the end of it).
I’ve mentioned a couple of times that I started reading through Seven Languages in Seven Weeks, and even though I’ve recently been heavily sidetracked by Learning Go I just finished chapter two which dealt with Io.
The book gushes over the language, and I’ve read a lot of other people’s blogs where they seem quite excited about it. In the end I couldn’t finish the last exercise, even having a working example to go off. It was just a bit too painful trying to find the right object context, navigate around the strange method syntax and other oddities in the language. Of course, it would be wrong to blame the language, so I’m just going to leave it saying that Io didn’t resonate with me.
For now, I’m conquered. Maybe I’ll come back to that exercise and solve it, but probably not. On to Prolog, which I did get into briefly around 2001 (with fairly awful results). Hopefully the experience will be better this time.
- February 2017
- January 2017
- December 2016
- October 2016
- August 2016
- June 2016
- May 2016
- August 2015
- June 2015
- April 2015
- March 2015
- January 2015
- December 2014
- November 2014
- August 2014
- May 2014
- April 2014
- March 2014
- February 2014
- January 2014
- December 2013
- November 2013
- October 2013
- September 2013
- July 2013
- June 2013
- March 2013
- February 2013
- January 2013
- December 2012
- November 2012
- October 2012
- September 2012
- August 2012
- July 2012
- June 2012
- May 2012
- April 2012
- March 2012
- February 2012
- December 2011
- November 2011
- October 2011
- September 2011
- August 2011
- July 2011
- June 2011
- May 2011
- April 2011
- March 2011
- February 2011
- January 2011
- November 2010
- October 2010
- September 2010