Thinking until the 2147483648'th second

About This

I think all of the files I linked to in some of my older posts are gone now. I am working on fixing them.

Thursday, August 23, 2007

Wrapping up code

Recently I've become obsessed with the idea of "modules". I don't mean any particular module or namespacing system, but just the idea that code should run isolated, in its own environment, and interact with an explicit interface (whether it be a whole set of function definitions or simply arguments to a function).

The idea is old, and has materialized in many forms. I think the idea of OOP is a variation on modules. Each 'object' has code which runs in its own object environment, and you present 'public' methods as an interface into the code. It even gets kinda fancy with polymorphism, where an interface can represent a dynamic codebase. The problem with traditional OOP is you get abstraction leaks everywhere and interfaces usually break (and you end up losing trust in the integrity of your interfaces, which is a very bad thing).

It's hard to develop a module system in the mainstream OOP languages (C++, Java, etc.). It's because scopes are screwed up in those languages. Java forces a certain namespace pattern on you, but at least everything is an object. C++ has two scopes, the global one where you can declare functions, and the local one where you cannot declare functions. Oh, but there's also the object scope mixed in there somewhere. (Interestingly enough, you can declare nested functions in GNU C).

The point is that if I am restricted as to where I can place my code (i.e. functions), I probably won't be able to isolate code as much as I want to.

Anyway, enough about OOP (I am a disgruntled developer who didn't discover functional programming until recently). This is the kind of module pattern I like, only available in functional languages (this is Javascript):

var f = (function() {
  var result = (function(o) {
    var i = 5;
    return o.val = 4*i;
  })(getobj());
  return result;
})();

This is similar to the 'let' form in Lisp. It's simply a block level expression that represents encapsulated code. It discourages mutation which is a very good thing, and everything is nicely placed into its own little environment.

So that's one form of modules, which could work on a large system as well because of how dynamic Javascript is (and you don't need to sort dependencies). jQuery wraps everything up into a (function() { ... })() expression, and scopes itself by attaching the jQuery object to the window object. neat, eh?

In languages like Scheme, especially ones which compile to C, you need a little bit more advanced module system on the global level because it needs to sort dependencies and do proper importing/exporting. I have recently been using Gambit Scheme and adopted Snow as my module system. I extended Snow to support better options for including and/or loading libraries, and ever since I started using it I've felt very liberated (I had just come from the C++ world). I love the fact that there is no difference between an statically linked library (such as a group of C .h/.c files) and a loadable library (a dll or shared library). In fact, I can control exactly which libraries should be linked/included and which should be built as loadable libraries in my Makefile.

So whether it's simply reorganizing Javascript to get a little more isolation, or building a large complicated system with dependencies in Scheme, the idea of 'modules' is just awesome.

2 comments:

Anonymous said...

Well written article.

Medical Blog said...

The global one where you can declare functions, and the local one where you cannot declare functions.

Random Notes

I work at Coptix

Ideas / To-do

  • Research .Mac style photo gallery for screenshots