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


Friday, March 9, 2012

Getting my hands dirty with C++

Today I am working on a project in C++ for a computer graphics class.

C++ is interesting for a number of reasons; I generally appreciate it for the same reason the Newfie enjoyed banging his head on the wall...because it feels so good when I stop.

I jest. On a more serious note, I will take a moment to note a plus or two (pun++!) about C++. I find C++ interesting because of the expressive power it has compared to e.g. Java. One of the design decisions of OO in Java is that all object instances reside on the heap. That is because in Java, the garbage collector is responsible for freeing resources. That is cool when that is how you expect the System to operate, but there may be times when you want resources to be freed when their intended use has passed out of lexical scope; in other words, when some body of code has finished executing.

C++ of course allows the programmer to allocate object instances within stack frames. The answer is to declare them like any other variable, e.g.:

Foo aFoo(aParam);

This looks similar to "Foo aFoo = new aFoo(aParam)" in Java. However, because "new" isn't used, in C++ this is a stack variable allocation, and not a heap allocation. The "delete" keyword isn't required as the destructor will be called automatically when aFoo passes out of scope. Besides the fact that the deallocation of the object instance will possibly be deferred for a while in Java, the two stories look more or less the same.

However, when exceptions enter the picture, things are a little different. C++ is gracious enough to unwind the stack for you, and that means that for each block (a lexical scope) on the stack, object instances allocated within those blocks will be deallocated. In Java, this is not possible.

This leads to an important idiom in C++, invented by the venerable Bjarne Stroustrup himself, Resource Acquisition Is Instantiation. If resources must be freed, those resources may be acquired in the constructor of a class and freed in the destructor. Then an object of such a class can be instantiated inside a method or function body as a local variable. Whether an exception is thrown or not, because the destructor will be called, the resource will be freed.

There are ways to approximate this in Java and in other languages, e.g. a "with" block in Python will do more or less the same thing.

So where does that leave us? I'll try and close with an interesting thought. As a beginning programmer, I was intrigued by syntax. I think the most important parsers on the planet are human, so I still think syntax is important. But behind the syntax is meaning, is semantic. Javascript and Scheme have wildly differing syntaxes for meaning the same things. Here we saw an example of a humble line of Algol-derived syntax meaning completely different things in two closely-related languages.