Sunday, November 28, 2010

Learning Clojure...a newbies thoughts

I spent a good deal of my vacation this week learning, or I should say re-studying Clojure.  I bought Stuart Halloway's "Programming Clojure" book earlier this year, and I read through almost all of it except the chapter on Macros.  However I found learning Clojure to be a fairly difficult process.  However with the help of two new MEAP books from Manning.com, I am on track to becoming Clojure fluent (I hope)


In college, I took an Artificial Intelligence class, and we did have to write a few of our programs in lisp (Common Lisp), but to be honest, I'm not sure how I was able to do it because at the time it made no sense to me.  Lisp has a horrible reputation among many software engineers, and yet ironically, it is also held up as something of a pinnacle.  For example, a coworker at my job showed me a list of the "hierarchy" of programmers.  At  the top, the spot was shared by lisp and assembly programmers (I guess the list was made before VHDL programming became more common?), and at the bottom were people who insisted that HTML was a language.


But despite some people who acknowledge the power of lisp, quite a few others either know little of lisp, or they relegate it to the land of so-called dead/dying languages like Cobol, Fortran and Ada.  And of course, many people who have ventured into lisp territory refuse to touch it again due to the Lots of Insipid and Superfluous Parentheses (LISP).


However, I think the syntax (or lack thereof) of a lisp dialect is simple bias.  I remember when I first started learning python, how stupid it was (I thought) to make white space matter.  I had that opinion for all of about 3 days, and then I just got used to it, and now I love it.  I'm now feeling the same way about Clojure and the "strange" syntax.  And Clojure is better than most lisps and schemes because they added some new data types which don't use parentheses (it uses [] to denote vectors, and {} to denote maps).  Moreover, after reading chapter 1 of "Clojure In Action" by Amit Rathore, I have a better appreciation for why the syntax is the way it is.


But I think another reason many people give up or don't even want to try learning a lisp dialect is because it is so different in its paradigm.  Clojure is a functional language for the most part, and getting used to immutable data, and not having first-class variables is a HUGE leap for most people including myself.  I'm sort of getting past the mutable data thing (just return a new data structure instead of mutating an existing data sturcture), the idea of not having what most programmers think of as variables is still something I'm grappling with.  


Yet another stumbling block for programmers used to mutable state and imperative programming is their bias against recursion.  "What do you mean there's no for loop?".  Well, actually, there is a for function in Clojure, but it's not a loop, it's a sequence comprehension
(sort of like a python list comprehension, but more abstract...for a loop, you'd probably want a doseq macro instead).  One of my coworkers is a recent CS grad, and he was told by his professor that recursion is generally frowned upon.



While many languages do not optimize recursion, and recursion can be dangerous due to its consuming of call/stack frames, that doesn't mean it's always bad.  Recursion can ALWAYS be used to implement a loop (if the iterations are small enough).  And better yet, depending on the language and how you implement the recursion, the code might wind up generating a for-loop for you anyway (such as with languages that can do tail call optimization).  For example, Clojure's loop/recur form will do this as opposed to direct self-recursion.  Until recently, I considered myself very bad with recursion, and I know that others also have some problems with understanding it.  But due to a lot of practice at my job with it including some mutual recursive functions, I have gotten a bit better at it.  There is a symmetrical elegance to recursion that is lacking in for loops and not to mention that for and while loops can be dangerous due to mutating the state of some iterator or sentinel variable.


So slowly and surely I am starting to "get" Clojure, and thus some of the legacy of lisp.  I even had a small and temporary epiphany when I understood what is meant by "code is data".  Lisp was designed to compute symbols, not numbers, and lisp code has the same form as data.  I briefly envisioned the clojure reader as consuming structures...not code.  But that in turn helped me understand Macros a little better, and indeed one of my next tasks is to write a small macro.


Most importantly though, I find programming in clojure fun.  I honestly haven't felt this way since I learned python.  I picked up a book on Scala, but for some reason, it didn't really catch my interest (maybe because they chose the perl philosophy of "there is more than one way to do it"....for example, you 'usually' don't have to put semi-colons at the end of a statement or expression...huh?).  That's not to say I might not pick it up again after I get good with Clojure, but it's on the backburner now.  And perl?  Let's just say that I hope I never have to program in perl again.  No introspection, no built-in shell, no real exception handling (eval'ing is not exception handling), bolted on joke of a OO system, TIMTOWTDI (ummm, why are there at least three different ways to pass arguments to a function?) are just things I don't want to have to deal with again (and if you love perl...great for you...but it was not great for my own work style)




So in my quest to get better at Clojure, I have decided to do three things:
1.  Create a "computer assisted" role playing game (of the pen and paper sort, not MMORPG)
2.  Create a blog detailing my experiences learning Clojure
3.  Go over some classic CS problems in Clojure


For the first goal, there's no better teacher than practice.  So why not do something fun while I am at it?  It will also help me relearn Swing which I haven't used in years.


The second goal is so that I can help others learn from my mistakes or to just get a perspective from a fellow n00b who might be just a little farther down the path.  My uncle, who was a Harvard law grad once told me that he learned more from his fellow students than he did his professors.  Sometimes when you already know something, it's hard to put yourself back in the shoes of someone just learning.  So hopefully having a blog detailing my experiences will be of help.


And finally, I do want to go back and start taking Master's degree classes maybe next Fall.  I realize how weak some of my basics have gotten (analysis of algorithms, automata theory, and especially my math).  So going back and reimplementing some classic algorithms in clojure might help jump-start my brain again.



Introduction

It's been quite awhile since I have done any blogging.  I used to do quite a bit while I was active on MySpace a few years ago, but I haven't posted a blog in probably a year, and maybe only half a dozen in two years.


The majority of my last few blogs had been about either politics or Buddhism, and predominately about Buddhism.  But one of the main reasons I stopped writing blogs is that I felt I couldn't say anything anymore.  I started feeling, quite honestly, like a fool.  Buddhism is something that must be experienced and practiced, not explained or studied.


But I have of late felt an itch to write again.  My real desire was to blog about programming topics, something that I very rarely did before, mainly because my audience (my friends) weren't programmers themselves.  I may even start writing some of my thoughts or experiences with Buddhism again, if only for myself (as evidenced by the title of my blog).   I have however learned an important lesson in my practice: do not try to be understood by others.


I may also talk about some other non-program related things, like getting back in shape, history, or a few other issues.  One topic I will try to avoid however is politics.  When I was younger, my grandfather once said "There are three things you don't talk about in polite company; politics, religion or women".  I don't mind talking about religion, and I may continue to do so, but politics is just too depressing to talk about.


But who knows...I can only say that I will write about what interests or concerns me, not just as a programmer, but more importantly, as a human being.