taruss
4/1/2015 9:36:00 PM
On Wednesday, April 1, 2015 at 5:16:38 AM UTC-7, jara...@skynet.be wrote:
> (I think) I've understood the principles of CLOS and its generic functions instead of
> methods in C++, Python et al.
Well, not entirely...
> Still I'm missing one link:
> In C++, et al, a method belongs to the 'implicit namespace' (not a technical term)
> generated by the class, e.g. the method foo of class Class has the name
> Class::foo.
> On the other hand, a generic function / method in CLOS is not part of any class.
> Therefore it 'lives' in the package where it has been defined.
Mostly correct. The generic function could also be using a name defined in another package that is visible in the current package via using, imports, etc.
Common Lisp has only a single[*] namespace mechanism, namely packages. If you want to have distinct, accessible names, they will have to be in different packages. So you don't get separate names associated with them.
>
> So, how can I have a "local namespace" for each class except defining each class in a separate package.
You can't. If you want the names to be separate you need them in different packages. You would need that in order to distinguish between the different names, since the symbols are differentiated at the package level.
I suppose that you could always use your own convention for local namespaces by, for example, adopting "!" or "." as your own namespace delimiting character and then write your functions like
class1!method class2!method or class1.method class2.method
since "!" and "." are just ordinary name characters, so you can just use them.
But then you always have to qualify the names and there is no other real namespace support. This is done by convention, for example in elisp, because it doesn't have real namespaces.
> E.g., given several classes which (totally) different 'process' methods with incompatible parameter lists, these cannot be switched by one generic function
> unless I use lots of optional parameters - which is ugly in this case.
This is where I think you haven't fully adopted the design philosophy of generic functions. You should not have generic functions with the same name that do radically different things. In other words, if you have a graphics:draw and a card-game:draw and a weapon:draw method, you want those methods to be in different packages because they represent different sorts of actions. You could then, for example, in some game have a playing-card object that supports both graphics:draw and card-game:draw, each of which has a very different effect.
So you don't want to have a shared name for very different sorts of operations. And if you introduced a separate namespace for each class, you wouldn't get any real method dispatch at all, because all of the generic functions would be different.
So what you need to do is figure out for each operation what a good name is for it, and use that name only for that one operation. But then share that operation name among all the methods that implement the same method, using the argument types to do the method selection for you. If you have a different operation, then you need to choose a different name, either by giving it a different symbol name or by using the same symbol name but having the symbols be in different packages.
If you think about it, having a local namespace for a class wouldn't help with method dispatch at all, especially given the multiple-dispatch that lies at the core of the generic function paradigm. How would you even choose which "class namespace" a generic function belongs in if it takes arguments of two different classes?
So, in summary, Common Lisp has separate mechanisms for classes (which encapsulate data and form a hierarchy), generic functions (which encapsulate a particular sort of computation that is carried out in various ways by using specialized methods), and namespaces (which is handled by packages). These are all orthogonal to each other.
[*] OK, if one wants to get pendantic, there are separate namespaces for looking up different things associated with the same symbol, such as value, function definition, class, etc.