preferences (was: generic functions)

Patrick Premont premont@IRO.UMontreal.CA
Fri, 28 Jul 1995 17:29:08 -0400 (EDT)


> 
> I agree with some of what Rene' and Patrick have said about generic
> functions, but must admit to being an object/message passing fan.
> 
> It is very true that objects alone are not sufficient for all "grains"
> of modularity that one might want in a system. Yes, you will have to
> patch some basic class ( in Smalltalk, for example ) to make your
> application work and that can be a mess in an "image" shared by many
> users on a network. Generic functions seem to be the answer - you
> "patch" the class hierarchy from the outside, without disturbing
> other users of the same classes.

In Dylan, adding methods to generic functions doesn't affect the class
hierarchy, it only introduces special cases in the functions. I guess
you mean that it affects something that would require patching the
class hierarchy in Smalltalk.

> But if we look at SmalltalkAgents for the Mac, however, we see that
> this problem *can* be addressed in the object/message passing framework.

I'm not sure I see what problem you are talking about. You mean changing
the class hierarchy without affecting other users ? As I see it, you
change an object only when you want all of it's users to see the change.
If you don't want them to see it, you'll have to define a new object
and use that one.

You may want to define a new context and make the change in only one
context but I don't understand how contexts really work. Fare, would
you like to explain the contexts you have in mind and how they could
be used to patch part of the system for a specific user ? The only
working contexts I understand now are complete copies of the system.
That seems to have the desired properties but it's not efficient at all!

> This language allows local "name scopes" when looking up messages, so
> you can patch the Number class without affecting other users or even
> other applications of your own.
> 
> I think that this is just the tip of the iceberg - the problem is more
> complex than it seems. I have placed this in the "preferences" subproject
> in Merlin. I have identified these preference levels ( at least ):
> 
>    - object: an object might decide what font to use or what color
>      it should be
> 
>    - application: all of the objects in an application might share
>      a sound volume or cursor shape
> 
>    - user: will the prompts be in English or French?
> 
...

I don't see the problem here. Have a font and color slot in each
object. Have a sound volume and cursor shape slot in each application
which all contain (and share) the same object. Have a language slot in
every object which represents a user. ...

> Don't let my examples fool you - any characteristic might be defined at
> any level.

If characteristic A is defined at level B, make sure you have an object
that represents level B and add a slot to hold the desired characterstic.

> I wasn't able to arrange these things in a strict order, but
> the one I listed them here is a reasonable one.
> 
> What does this have to do with generic functions? I am pointing out that
> they are simply not enough! Adding the argument types to the "lookup"
> of the code to be executed does make the system more flexible, but there
> is a *lot* more context that could be taken into account here than just
> that. I am looking for a solution to the whole problem, not a limited
> subset of it.

Once the complete type system is in place (arbitrary logic predicates
used as types), I expect the generic function's dispatch to be based on
logical implication instead of subclassing, which should provide all
the flexibility you need. But I don't think generic functions are the
right place to implement the preferences you are talking about.

> A single dispatching solution to a problem that is inherently
> multi-dispatching ( and my experience says that these are not that
> common )

My experience says they are quite common. Note that many are hidden
behind the fact that a few dispatches are done at compile time. (C++)
Drawing a primitive on a display, unifying two terms, even adding two
numbers (fixnum+fixnum, fixnum+bignum, bignum+bignum ...) ... Also, if
you know about singletons, you'll see that they can often be used to
introduce special cases, and that often introduces multi-dispatch.
Ex: patching the multiplication of a matrix by a constant so that
multiplication by zero and one are optimised requires dispatching
on the constant but you may already be dispatching on the matrix
to optimize the 1x1 case.

Patrick