evan_tech

Previous Entry Share Next Entry
11:26 pm, 29 Oct 05

namespacing

One thing that OO languages do nicely is implicit namespacing of functions. That is, when I write button.setText() it's specified/implied which of many possible setText()s I'm referring to. In a lot of O'Caml/Haskell/C code there's a pattern where, for example, a function with a name like setText is too general, so instead of colliding with other potential setTexts they get names like buttonSetText.

In non-OO C++ you can do this this with overloaded functions: you can't confuse setText(Button*) with a setText that works with some other thing. But this only works because you have explicit types: at any call of setText the compiler knows the type of the argument and so can resolve which function to call. In a type-inferenced world, code like setText myobj is used by the compiler to figure out what type myobj has.

The irony of this is that Haskell does allow overloaded functions based on return types, which is one of many crazy aspects of the language but consistent with the way they think, which is this: overloading gives a single name for the same operation on multiple types, and is provided analogously to OO interfaces: your types all have to implement the same interface. And you could imagine the utility of a single ParseFromString which takes a string and returns one of many different types, calling different code underneath -- something impossible in C++ but used in Haskell.

But multiple unrelated setTexts can't share a name in Haskell -- they call it "ad hoc overloading" to distinguish from the more "principled" overloading described in the previous paragraph. And that's all well and good for principle but in practice it means that every time I look at Gtk2HS, the GTK bindings for Haskell, I get turned away by these long function names.

Now that I've typed this all out, though, I discover that the Haskell developers are aware of it and they have a paper describing the problem space much better than I could.