Wednesday, April 18, 2012

Philosophy and Tools

TL;DR

Its amazing how cool things just keep popping up all over teh interwebz. Rich Hickey (of Clojure fame) commented once in a Clojure-conj talk, that "Not everything is awesome!" We flock like lambs around this or that technology because it is 'awesome,' and less because it may solve this or that problem.

I've been playing with Node.js recently. It's Javascript, it's server-side, and it's pretty cool. One of the bright ideas it brings to the table is that for developers coding on node, the system by design uses almost exclusively non-blocking IO. Other platforms have asynchronous IO too; but Node could be the poster child.

The big win here is that for an IO op that may take some time, the developer simply provides a callback, and execution merrily proceeds through the code, top to bottom, until the event fires and the callback is invoked. The advantage is not programming with callbacks; the advantage is speed of execution.

One potential problem is keeping everything wired up neatly. Exceptions can get messy. They propagate...where, exactly? And the control flow of a non-trivial system evokes memories of the GOTO (or perhaps COMEFROM) days.

Node packs a punch, its async IO is fast, and it brings the best of the V8 Javascript engine from Google to server-side apps. It is new, and I think it deserves a chance to grow into something robust and mature. Who knows, maybe it will make it into my toolkit sometime soon.

In the meantime, there are alternate solutions. For Ruby, there is Eventmachine. Python has a number of solutions as well. Both Ruby and Python provide abstractions (E.g. Fibers, green threads, etc.) which tuck the details under the covers, allowing the programmer to bring the language closer to the problem domain.

Different domains lend themselves to different styles, and in this glorious day of hip dynamic languages let me say that even C++, as barnacle-encrusted as any ship sailing the seas of leadership by committee has ever been, has the flexibility to express many different styles appropriate to different domains. We have added dynamic languages to the toolbox to gain flexibility, not to forfeit it.

To return to the example, Node.js may be appropriate to solve a certain kind of problem. Like Patterns, languages and frameworks must be understood in terms of the problems they solve, the forces they resolve. Otherwise we run the risk of being the one-trick pony, who can only bleat "NoSQL!" and is forced to write every kind of middleware, client app, and numerical simulation in a hacky, "Ajax-ian" style.

Saturday, April 7, 2012

Ruby and Xcode 4.2

This weekend I didn't have anything better to do, so I decided to play with ruby-opengl.

My platform (for the machine in question) is OS X Lion, and my tool chain is from a full install of Xcode 4.2. Unfortunately "gem install ruby-opengl" resulted in a veritable cornucopia of error messages which flowed tauntingly over my screen. $#!$@#@!

It turns out this is for good reason. Here is what rvm has to say about my setup:

Xcode 4.2:
* is only supported by ruby 1.9.3+ using command line flag: --with-gcc=clang
* it breaks gems with native extensions, especially DB drivers.

Hmm, that doesn't sound good. Here I was thinking that rvm more or less kept things sane, but it looks like there is a little too much dark magic going on under the covers (something true a little bit too often when it comes to Ruby methinks). So I'm trying out an alternative, rbenv, which purports to abstract versions and such through directories and the path variable.

So after staring into the void for at least an hour too long, I managed to conjure up a MRI Ruby 1.8.7 release, like so (this is *after* uninstalling rvm):

Install (using home brew) apple-gcc42:
brew update
brew tap homebrew/homebrew-dupes
brew install apple-gcc42

Install rbenv:
brew install rbenv
brew install ruby-build

Install ruby-1.8.7-p352:
rbenv install 1.8.7-p352

Tell rbenv to make the installed Ruby interpreter the default, per user global:
rbenv global 1.8.7-p352

Install the ruby-opengl gem:
gem install ruby-opengl