I have a conceptual model for an object system which involves combining Go/Obj-C interfaces/protocols with being able to add virtual methods from any unit, not just the one which defines a class. The idea of this is to allow Ruby-ish open classes so you can take a minimalist approach to library development, and attach on small pieces of functionality as is actually needed by the whole program.Implementation of this involves a table of methods marked virtual in an RTTI table, which system functions are allowed to add to during module initialization. Upon typecasting an object to an interface, a Go-style lookup is done to create a vtable for that particular mapping and pass it off so you can have comparable performance to C/C++. In this case, methods may be added /afterwards/ which were not previously known and these new methods allow newer interfaces to be satisfied; while I like this idea because it seems like it would be very flexible (disregarding the potential for spaghetti code, which can happen with just about any model you use regardless).By wrapping the system calls for binding methods up in a set of clean C-compatible calls, one would also be able to integrate code with shared libraries and retain a decent amount of performance (Go does not do shared linking, and Objective-C does a dynamic lookup on each call.)Is there a valid use-case for this model that would make it worth the extra background plumbing? As much as this Dylan-style extensibility would be nice to have access to, I can't quite bring myself to a use case that would justify the overhead other than it could make some kinds of code more extensible in future scenarios.
Go/Obj-C style interfaces with ability to extend compiled objects after initial release
design;objective c;languages;go
The most important use case that I can think of is making two independent libraries/modules work together with minimal glue. This is quite common in the Haskell world (Haskell allows making a type (roughly equivalent to a class in traditional OOP) a member of a typeclass (roughly equivalent to an interface) independent from the definition of both the type and the typeclass: you can take a type T from module A, a typeclass C from module B, and declare T to be an instance of C in module X. For example, let's assume you have a library that implements a document model type DocumentNode, and another library that provides functions to traverse trees, and exposes a typeclass TreeTraversable to define what objects it can consume. Neither library knows about the other, but you can provide an instance declaration that maps methods from the typeclass (e.g. isLeaf, childNodes) to functions on the type. As a result, the libraries do not need to depend on each other: only the module that glues them together depends on both. This mechanism is very helpul in keeping dependencies between modules and libraries low, and it makes for great extensibility at the module level. The mechanism isn't even restricted to user types: you can make any built-in type (e.g. Int) a member of any typeclass you want, and you can make any type implement any built-in typeclass (such as Ord, which makes a type sortable).Another example would be mix-ins, which allow the programmer to dynamically inject methods into objects; this is pretty common in many dynamic languages, including Python and Javascript. Unlike the Haskell example, these languages don't provide any type safety though - a class is basically just a bag of properties, and a method is just a property that happens to be a function. The advantage is that this is relatively easy to implement, and gives the programmer full flexibility (any method can be glued onto any object), but obviously, you won't get the benefits of a static type system (but then, if you're using a dynamic language, you have already decided to let go of static type checking).