Keep Working, Worker Bee!

5.10.2006

Package interfaces

So we all know that you should program to an interface, not an implementation, if you're writing a program in the modular, component-oriented world. In Java or ML, at a basic level this is pretty much straightforward to do: you get some object with a known interface (or you import some structure with a known signature) and start referring to its fields/methods/values/types however you'd want, by saying some variant of "I want resource x from component C" every time you want something. Every time you want something from a component, you write down what you want, and from which component you want it. If you name something that you don't know to exist, the compiler yells at you and that's the end of the story. If the maintainer of the component you're using adds a new resource to the interface tomorrow, that doesn't affect your code at all.

In PLT Scheme the situation is a bit worse. When you import a module, you just name it and all its provided names get dumped into your namespace. If you import two modules, they must have completely distinct namespaces, or mzscheme doesn't know which one you wanted and signals an error. This has an insidious effect that becomes apparent as programs evolve: if you import a module, you're not only relying on it providing some names, but also on it not providing any other names. That means that if you start using somebody else's component and that person adds a new resource to its interface, your code might break.

This problem has always existed, but PLaneT turned it from a hypothetical problem to a real one. It has a tendency to do that ...