Should method names be (module-) scoped?

This is a question that I encounter frequently when thinking about OOP and modules.

Say, I define a method m on some class inside a module M.

Should the method lookup table of the class contain an entry named "m" or "M::m"?

"M::m" seems cleaner, and more modular... whereas "m" seems more OO.

Comment viewing options

Select your preferred way to display the comments and click "Save settings" to activate your changes.

It depends

Usually, methods are not first class and can only be used in combination with an object reference, which then indirectly serves as a namespace.

If you want methods to be first class, where you want to refer to a method "m" without mentioning an object or class, then I would use "M::m".

I think it depends on how you interpret the question...

The best reference implementation for namespaces, IMHO, is .NET's MSIL (Microsoft Intermediate Language) for the CLR (Common Language Runtime). The ILAsm, when creating the PE (Portable Executable) file (aka *.exe or *.dll) does its best to make sure all "objects" in assembly language are fully resolved. Among other things, this simplifies the design of the loader and linker, and it also makes it easier to design byte-code engineering lbiraries (BCELs) because all references are fully resolved. Thus, the number of invariants your code injection facilities must keep track of in a von Neumann-style block-structured language is kept to a minimum: stuff like branching and constants are the two main gotchas, and .NET simplifies management of constants by making changing them breaking changes. Branching correctly is tricky, and in fact trips up even smart people at MS Research, like the PeX team and anyone designing testing facilities that insert invariant-checks into code (possibly causing a short-branch optimization made by the compiler to become a broken invariant).

MSIL also still provides things like using constructs to simplify human readibility and human typability but they matter not for static analysis. That's because, within a given module, all references are unambiguous. In fact, MSIL's ILAsm compiler will not compile ambiguous references.

Stable Interposition

I forgot to mention that there is a name in computer science/software engineering for the classical problem of preserving invariants of an environment while modifying it. This is known as the Interposition Problem (although not that well known).

This sounds like horizontal

This sounds like horizontal class modification, where you're adding new methods to existing class (call it A) as part of M, such that there is a new method. The question is how this new method is called:

A a = myAFactory.make("...")
a.m(parameter)
  ; or perhaps
a.M::m(parameter)

If my understanding of the question is correct, you'll be facing two cases:

  • A new subclass C extends A is visible to a client of M (which knows about method 'm') but is not known to module M. This subclass needs the new method m to be overridden. In this case, the client may need to explicitly override an implicit name 'M::m', which will be a problem if you ever wish to move the 'original' definition of 'm' into a super-module. You've nailed your module system to its past.
  • A client of module M is also a client of (independently developed) module N. Each M and N independently add method named 'm' to the class in question, but the two methods have different semantics. This is a problem because the client of both modules now sees a namespace conflict, and must be able to choose between 'm' used in N and 'm' used in M.

I think the best solution is to name the method with plain-old 'm', but to provide namespace conflict resolution facilities as another (wholly independent) language feature. That way, with namespace conflict (which will happen often for clients of independently developed modules), you just solve it as it appears - i.e. renaming N's m to 'm_from_n', and perhaps allowing order-of-import to determine default resolution.

IMHO, they should

Why should this be non-OO, isn't OO all about proper encapsulation? If you have extension methods, ie methods defined in different modules than their class (often called monkey patching), it seems insane to not prefix them the module. How else do you tell apart two method of the same name but different semantics? Still, this is what Ruby and (to my best knowledge) all Smalltalk dialects do. Alas, I dont know about the state of this affair in other languages (with monkeys all the way down :) beyond these...