Today I’m coming to you from about 38,000 feet. I’m headed out to visit my sister in Los Angeles, but nothing can stop the Month of New Technology. Nothing. But that’s why there aren’t any hyperlinks.
Before I left for the airport, I downloaded OCaml with Homebrew (my new BFF) and the “Introduction to Objective Caml” PDF. OCaml is
a popular, expressive, high-performance dialect of ML developed by a research team at INRIA in France.
I didn’t know much about the language going in, only that it’s a functional language, it’s used in the MediaWiki project, and it has a web framework called Ocsigen, which I’d link to if I had internet access. Nevertheless, something about the language has always fascinated me, and actually sitting down to learn it was one of the prime motivators of this month-long experiment.
OCaml installed flawlessly with Homebrew, and I fired up my laptop in the Nashville airport and opened the interactive shell, which the docs call a “toploop”. Oh the French. I started working through the examples, playing around with basic datatypes, functions, and pattern matching. I’ve spent a little bit of time with Haskell in the past, and parts of OCaml are very similar, especially the built-in currying. Check this out. When you define a function that takes two variables, you’re really defining a function which takes one variable and returns a function that takes the second variable. If you have a function ‘add’ that adds two variables, you can call it with just ‘2’ and get back a function that takes a single integer and adds two to it. Tell me that’s not the coolest. You can’t. Because it is.
The OCaml docs don’t dumb anything down — one of the first examples of using higher-order functions was method for computing first and second derivatives of mathematical functions. That said, it still feels like an approachable language in a way that some other functional languages do not. I definitely want to pull down Ocsigen and see what OCaml web programming looks like.
The ostensible subject of today’s experiment was the Io langauge — and what an un-Google-able name it is — but the title of today’s post might as well be, “Why I finally switched to Homebrew.” I’ve been a loyal MacPorts user ever since I switched to Mac about five years ago. I’ve had a decent experience, but never liked how long it takes to install some software. MacPorts maintains its own versions of all required dependencies; it doesn’t matter that OSX ships with its own version of Perl — MacPorts is installing its own. There’s good reason for doing it this way: how else can you be sure that the version of a library you’re depending on is actually the one you want? That said, it feels a lot like the TSA — penalizing everyone for the bad behavior of a very small few.
All that said, I sat down to install Io using MacPorts, but exited out after sitting at “Installing subversion” for five minutes. Then I opted to clone the GitHub repo and build from there. The download went fine, but when I ran “make”, it would get caught in an infinite loop and eventually error out. I’m pretty frustrated at this point. I’ve successfully installed Io in the past, on my Netbook, using Homebrew, an alternate package manager that uses the built-in libraries on OSX. I’ve been put off by the thought of having two package managers running side-by-side on my machine, but at this point, I can’t see any other option. I installed it and ran “brew install io”. My heart sank when I saw it executing the same “make vm” command I had entered when building by hand, but somehow, it worked. Thanks, internet.
CHAPTER THE SECOND. With about half an hour left, I sat down to actually use today’s technology. Io is a “Small, embeddable, object-oriented, prototype-based, garbage collected language” (from the Google search result page). And how about this, from programming guide:
Io’s guiding design principle is simplicity and power through conceptual unification.
Io definitely has my interest. The next step is to see how it’s actually being used for projects I’d enjoy coding — I know people are using it in embedded systems, but that’s not somthing I’m into. After that, actually sitting down with some good Io code and seeing how its done.
Tonight, Ren and I took a look at MacRuby, a version of Ruby that runs on top of Mac OS X core technologies, allowing developers to create Mac apps in Ruby. Version 0.6 was released just today, so it seemed like a good occasion to dive in. I wasn’t able to use the installer, as it requires Mac OS X 10.6 (Snow Leopard) while I’m still running Leopard. I downloaded the source and tried to build it, but it requires LLVM, the installation of which took the bulk of the hour. Once I had that installed, I tried to build again, but it gave no output and created no executables that I could see.
Ren, being on Snow Leopard, was able to use the installer, so we worked together on his computer. We were able to fire up an IRB session and play around with the built-in datatypes. It’s pretty much just the same as Ruby, until you start looking at an object’s heirarchy and see things like NSObject. We looked at the official tutorial and tried to create a sample application, but it seems like a lot has changed in MacRuby, OS X, and XCode since it was written, so we couldn’t get the basic app to work.
We then took a look at the MacRuby PeepCode screencast, which is well done, but again suffers from outdated information. One of the main contributors to MacRuby has a book coming out which I’m sure does a better job getting new developers up to speed. The problem is, after spending over an hour with it, I never had that “aha” moment, and I can’t tell if it’s any more enjoyable to code than normal Objective-C development.
Once I felt like I had a decent grasp on how to create extensions, I decided to create my own, one that would get the URL of the current tab, shorten it, and then open the Twitter homepage with the short URL in the status form. This is a fundamentally different extension that the tutorial example, as it doesn’t simply display an HTML page, but rather does work behind the scenes and then opens a new tab. I had to dig into the extension API a good bit, but it wasn’t difficult. I was happy to see that I could easily include jQuery in my extension, making handling Ajax a hell of a lot easier. Here’s my (working) extension.
Yesterday was spent traveling to Wintergreen ski resort for a company event, so the only free time to learn the chosen technology, Google’s Go language, was during the bus ride up. Clinton joined me for today’s experiment, and we worked through the official tutorial in about an hour and a half. Go is a systems programming language, somewhat similar to C, initially released late last year. It’s a cool language, for sure. Some of the standout features for me:
The type system: If you define a new interface, all data structures that contain the methods in the interface are considered to implement it, and can be passed to functions that expect it. Clinton referred to this as “static duck typing.”
Public/private methods: Though not a classicly object-oriented language, you can add methods to data structures. If a method begins with a capital letter, it is public, while if it begins with a lowercase letter, it’s private. Simple and consistent.
Go routines: Go is built for concurrent programming, and includes several built-in constructs for making it easy to do.
Functional programming: They don’t make a big deal about it, but Go has full support for anonymous functions
I really enjoyed spending time with Go. I don’t do much systems-level programming, but in the event I ever need to, this will be the first thing I try.
Last night, Ren and I checked out MongoDB, a document-oriented database that claims to bridge the gap between key-value stores and traditional RDBMSes. Mongo is one of the technologies at the forefront of the NoSQL movement — which, in a nod to political correctness, apparently now stands for “not only SQL” — and has been getting a lot of good press in the Ruby on Rails community. This post by John Nunemaker, for one, served as a call to action to many Ruby devs that it might be time to step away from the typical MySQL-backed app.
After working through the basic examples, I decided to investigate how to write complex queries against Mongo. The official docs were somewhat obtuse, but this post by Kyle Banker proved to be much more helpful. In fact, it’s the last of a series of three very well-written posts. All highly recommended. Ren took a look at GridFS, Mongo’s solution for storing large chunks of binary data. I’m still not sold on it as a solution for storing uploads; you’ve long been able to store binary data in an RDBMS, but it turns out that we already have a great system for storing files … the filesystem.
MongoDB is clearly awesome, and I’m glad to have a better sense of its internals. I’ll be on the lookout for a project where a document-oriented database seems appropriate. I wonder if the changes to ActiveRecord in Rails 3 will bring SQL back into vogue or if more and more devs will make the jump.
Tonight, I sat down with Scheme, “one of the two main dialects of the programming language Lisp.” Though MacPorts offered several versions of Scheme, I opted to download PLT Scheme from its website, as I’d heard it was among the best versions available. With that installed, I loaded the REPL and opened The Little Schemer, loaned to me by Scheme fan (and implementor) Clinton R. Nixon.
The book has conversational style, with questions on the left side and answers on the right. I’d opened the book once before, but was put off by the way the code in the questions wasn’t always valid Scheme. It took about ten seconds of struggling to realize that all the non-valid code had footnotes indicating the correct code, for both Scheme and Lisp. That’s the beauty of this month: every technology gets an hour — no giving up when frustrations arise.
I love the style of this book. In Test Driven Development, we have the notion of writing the simplest implementation to make the test pass. This book takes the same approach: “Is it true that this is an atom? atom — Yes, because atom is a string of characters beginning with the letter a.” That’s not even close to a comprehensive definition of an atom, and that it begins with the letter ‘a’ is neither here nor there. The full definition is fleshed out in the subsequent question-answer pairs.
After introducing you to basic list manipulation functions (
cons) in chapter one, The Little Schemer throws you right into creating recursive functions. This stuff is just fun as hell. The dialogue style works great, creating skeleton implementations, then incorrectly filling them in, then correcting them. It dragged a little bit at parts because it also serves as a basic introduction to recursion, a topic with which I’m comfortable. Here are my answers for the first three chapters, though if you decide to work through this book, I heartily recommend writing all the functions yourself.
This was some of the most fun I’ve had programming in a long time, and one of the biggest successes of this experiment so far. I’ll definitely work my way through the book, and then pick up the two sequels.
Today, Ren and I sat down to learn Mercurial, a version control system similar to Git. We downloaded Dan Benjamin’s Peepcode screencast and put it up on my television. The screencast is very well done, and Dan does a good job outlining Mercurial’s functionality. As a fan of Git, though, I have to ask: why do these two pieces of software exist? They’re exactly the same. Mercurial has numbered commits. Git has the staging area. A couple of the commands are slightly different (though most are exactly the same).
Git vs. Mercurial is one of those technological holy wars, like Ruby vs. Python or Safari vs. Firefox. The common criticism is that they’re both so much better than the dominant players in their fields (PHP and Internet Explorer, respectively) that their differences are insignificant. The comparison doesn’t hold, though. Ruby and Python are legitimately different pieces of software, as are Safari and Firefox. Mercurial and Git are the same piece of software, written twice. If you know one, you know the other.
If you’re still using Subversion or CVS, or if you don’t use any version control at all, by all means, pick either Git or Mercurial, it hardly matters. GitHub is incredible, but I’ve heard good things about Bitbucket, as well. If you’ve already learned one, I can see no good reason to switch.
As I’ve looked at these different technologies in the last two-and-a-half weeks, one difference I’ve become keenly aware of is how well they market themselves. Redis and Sinatra both do fantastic jobs welcoming new users. Today’s technology, Cassandra, does not. From the Getting Started page:
Cassandra is an advanced topic, and while work is always underway to make things easier, it can still be daunting to get up and running for the first time. This document aims to provide a few easy to follow steps to take the first-time user from installation, to an operational Cassandra cluster.
It’s really not that complicated, but they do such a crap job getting new users up and running that Ren and I were about to punt on this one and pick something else. Fortunately, we were able to find a tutorial by Evan Weaver which simplified things considerably. One note: if you’re following Evan’s tutorial, make sure to install the ‘simple_uuid’ gem and then run ‘include SimpleUUID’ in your IRB session.
Cassandra is a non-relational data store developed at Facebook. It’s refered to as a column-oriented database, which means it stores its content by column rather than by row. Think of it like a key-value store, except with somewhere between three and five levels of namespacing. At the top level, you have what’s called a “keyspace,” which, in relational database terms, you can think of as the database itself (though you could conceivably use multiple keyspaces in a single app). Next, you have a “column family,” which is akin to a table. After that, you have the “key,” which is pretty obvious — think of it like a primary key.
From here, two things can happen: “columns” or “super columns.” Columns are key-value pairs where both are strings. Super columns are also key-value pairs, except the values are maps of string key-value pairs. Arin Sarkissian has a good writeup of the Cassandra data model if that didn’t make things abundantly clear for you.
Cassandra is non-relational, which means you can’t do JOINs across multiple tables/column families, though you still have the notion of referring to rows in other column families by unique identifiers. The effect of this limitation, from what I’ve been able to gather, is that you wind up having to do a lot more queries into Cassandra than you would in a corresponding relational database. My understanding is that Cassandra scales up incredibly well, but it’s as yet unclear to me what its sweet spot is. It seems to fill a strange niche between key-value stores like Redis and Memcached and full-blown RDMSes.
To mark the halfway point of this month, I decided to tackle Scala tonight, one of the three most intimidating technologies on my list (the other two being Erlang and Haskell). One way to think about Scala is “Java done right” — it runs on the JVM, and works very similarly to Java, but with a lot of the cruft thrown out. It’s still statically typed, but the compiler will infer the type of an object if it’s at all discoverable.
On the surface, Scala has a lot in common with Ruby: everything is an object (including low-level datatypes like Int and String), it’s a hybrid of OO and functional programming, and it has interfaces with implementations (Scala calls these “traits”; Ruby calls them “modules”). I started off by installing Scala from the project homepage, and then downloading the Brief Scala Tutorial (PDF) from the Learning Scala page. The guide made it easy to get started, beginning with how to write and compile a simple “hello world” program and moving through objects, case classes, traits, and functions.
After working through the guide, I spent some time playing around with Scala’s functional aspects. I was able to come up with a basic fold function, but I spent a lot of time beating my head against the language syntax and argument types (here are my results). One question I wanted to answer was: how do you write functional code in a statically-typed language without having to redefine your functions for all possible type combinations? Well, I’m happy to say that I found the answer: Generics. Which is not at all to say that I understood them, but I read enough to feel like I could understand them given a few more hours.
An hour is not nearly enough time to explore all of Scala’s functionality. I regret that I didn’t take a look at actors, Scala’s model for concurrent programming. As a Ruby programmer, I’ve been taught to fear the day when single-threaded applications can’t keep up with modern multi-core processors, at which point I’ll have to find a new programming language or a new career. Functional programming has been touted as the solution to this problem, but Scala offers an interesting alternative: a lot of the features I love about Ruby combined with a novel approach to concurrency. That said, after living in the land of duck typing for the last few years, going back to static typing would be a bitter pill to swallow.