views:

43

answers:

1

Is the concept of a strict modularity provided by OSGi frameworks in Java, available in any other programming language?

I felt the concept of friend classes in C++ is somewhat similar, but it seems to be a much more granular control. I'm not sure if the friend concept can be applied at a namespace level.

In other languages I have no idea, and would really appreciate if someone can provide some insight here.

+1  A: 

There are plenty of languages that have module systems. Three that spring to mind immediately are the module system of Standard ML, the unit system of Racket and the module system of Newspeak.

Those three are by some people regarded as either more powerful or better designed (or both) than OSGi or similar systems.

I specifically like the Newspeak module system, because of its incredible simplicity. In fact, Newspeak doesn't even really have a module system, it just turns out that if you take object-orientation seriously, classes automatically become module definitions, and objects automatically become modules.

This is a refreshing contrast to other module systems like Standard ML's, Racket's or OSGi's, which typically are insanely complex. Here is a nice and funny quote by Jonathan Shapiro, the designer of the BitC programming language about designing a module system:

The ML module system is fully understood only by David MacQueen, and only on alternating weeks. The Scheme module system required the combined brilliance of Matt Flatt and Matthias Felleisen (and six revisions of the language standard) to achieve.

And when Simon Peyton Jones, one of the designers of Haskell, was asked why Haskell has only such a basic module system, he said that they didn't feel they were smart enough to design a real one. Let that sink in ... The designers of Haskell. Not smart.

Newspeak's design is utterly brilliant: in object-orientation, everything is a message send (in Java-speak that's a (non-static) method call, in C++-speak that's a virtual function call). In most object-oriented languages that is unfortunately not true. You have variables, fields, constants, non-virtual functions, static methods, a class dictionary, a package dictionary, and so on. Accessing any of those is not done via a message send, but via some other means.

Not so on Newspeak: in Newspeak, everything is a message send. Even the superclass of a class is a message send. (I.e.: if I write class Foo extends Bar in Newspeak, then Bar is not a reference to the class itself, it is just calling a method named Bar, which will then return a class. Which BTW means that you can override superclasses in subclasses, which is pretty mindblowing.)

This means that top-level classes cannot have a superclass: since the superclass is message send, where would you send it to? In a top-level class, you can only call methods that are defined in the class itself: you cannot call methods from the enclosing scope, because in a top-level class, there is no enclosing scope. And you cannot call methods inherited from a superclass, because in order to declare a superclass, you would need to call a method, but you can only call methods defined inside the class.

Now, this is isn't very useful, so classes have class initializers, which allow you to inject objects (and classes are objects) into a class. And this is the only way to inject dependencies into the class, ergo the class initializer functions as a module dependency specification.

On the flip side, if the only way to do something is via message sending, then the internals of a class are automatically private, its functionality can only be achieved by calling public methods. Ergo, the public methods function as a module interface specification.

A couple of other cool features also fall out naturally from this. Features that many other module systems don't have: since a module is really just a class, you can have multiple instances of a module, just call the constructor multiple times like you would with any other class. In a lot of other module systems, modules are singletons.

And, you can pass in arguments to the constructor, thus providing you with parameterized modules, which is typically only supported by very advanced module systems, if at all.

Jörg W Mittag