Thin Air

Modules and Late Binding

Travis Griggs just posted some musings on namespaces and imports in VW. We do things a bit differently at Quallaby. We have very few namespaces - a "main" one for most of the code, one for test cases, and a couple of other special purpose namespaces that help enforce conceptual boundaries. This works pretty well for us; most of the time we only think about it when creating a new package, and even then the norm is to import just the main namespace. Still, it feels like this is a way to avoid the problem without really solving it.

This issue has come up several times on the squeak-dev list in recent months and has been debated pretty extensively. There hasn't been anything even approaching a consensus, but a couple interesting tidbits have come up.

Forth has been put forward as an example of how to do namespaces right. The idea, as I understand it, is to decide on how the names in a module should be resolved, not when a module is defined, but when it's loaded. When you load a module you give the compiler an (ordered) list of namespaces to look in to resolve names, and a "target" namespace, where the names defined in the module will be placed. (This seems pretty unusual to me - I don't know of any other language that allows a module to be compiled without reference to it's own contents!)

This is an attractive idea to me because it casts the issue of namespace and imports as a question of early- vs. late-binding. Do we decide on how variables will be resolved when the code is written, or when it's compiled?

Another option that takes that idea even further is Dan Ingalls' "Environments," which was used as part of the (now-defunct) modules system in Squeak 3.3. It pushed name-binding even later, from compile-time to execution-time, by making it a message send. Instead of writing dotted names (Module.Class new), you'd send messages: Module Class new.

It would be interesting to see how late-bound module dependencies work in practice.

Posted in design