guile-user
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: Delegation in goops?


From: Alan Grover
Subject: Re: Delegation in goops?
Date: Sun, 19 Feb 2006 10:24:48 -0500
User-agent: Mozilla Thunderbird 1.0.6 (X11/20050716)

Neil Jerram wrote:
> Alan Grover <address@hidden> writes:
> 
> 
>>Does anybody have a solution to implement delegation in goops?
>>
>>I have an object that implements the full behavior of interest. Say it's
>>an employee object.
>>
>>For whatever perverse reason, which I assure you is reasonable, I want
>>to wrap the employee in another object. And, for the most part, it will
>>act just like the employee, except in a few places. Let's say I want to
>>have the employee masquerade as the CEO. The wrapper would implement a
>>few methods like "title", "salary", etc. And, specifically, the wrapper
>>doesn't need to know what all the other methods are, or what might be
>>added later.
>>
>>Seems like a job for delegation.
> 
> Sounds like a job for inheritance to me.  But I'm sure you must have
> thought of that and rejected it already, so can you explain why?  That
> will probably throw some more light on your objective and thinking.

Assume that an instantiated "employee" already exists in the system
(maybe via a third-party interface), so I can't just sub-class it.
Assume that I want to delegate in two different ways.

>>So, I looked at the goops MOP.
>>
>> ...
>>
>>"no-applicable-method" assumes that you will throw an exception. It does
>>not let you substitute a method of your choosing. Specifically, it's
>>result is discarded, and it appears to be approximately in the same
>>place as "compute-applicable-methods" ....
> 
> 
> But if you could customize no-applicable-method to return a just in
> time method, you can equally well define your fallback method using
> define-method, can't you?  (Using <top> to ensure that it matches all
> possible arg types.)  

That is also one of my complaints. The only meaningful specialization on
no-applicable-method is the first argument: which is the
generic-function. So, you can't specialize on a specific generic
function, and you can't specialize on the arguments to a generic function.

If no-applicable-method was defined as:
        (define-method (no-applicable-method (gf <generic>) . args)
(note the "."), then I could specialize on the arguments.

Not that it would solve the problem of delegation.

> So I don't think this is a significant
> restriction.

Well, I actually replaced no-applicable-method, and wrote a cond
statement to "specialize" on the arguments.

I can't just write a single generic-function on <top>, because I want to
delegate on "all methods for class-x, except a few". So, I would have to
enumerate all of the generic functions on the delegate-class. Which I
could do at any one point in time, but somebody could add a
generic-function/method in the future.


I did come up with a limited solution. In goops, you can change the
class of an object. So, as long as you only have one place where you
want to delegate, you can construct a sub-class, and then force an
object to become the sub-class. The behavior then looks like delegation:
the new sub-class is my "wrapper" (the CEO impostor) which only need
implement a few methods, and the original class is the delagate. But, if
I "delegated" somewhere else, it would break the first delegation.

I think I could hack another solution via compute-applicable-methods (by
replacing it). When I detect that I need to delegate, I return a special
"delegate-this" method, which calls the generic-function with
appropriate arguments fixed-up. Something like:

        (define-method (compute-applicable-methods (gf <generic>) args)
                (if (need-to-delegate? gf args)
                        (make-delegate-this gf args)
                        (old-compute-applicable-methods gf args))
        
        (define (make-delegate-this gf args)
                (construct-correct-data-structure delegate-this))

        (define-method (delegate-this gf args)
                ; overly simplified:
                ; replace-wrapper-with-delegate needs to know
                ; what wrapper-class needs replacement (with what)
                (apply gf (map replace-wrapper-with-delegate args)))

But this all smells bad to me.





reply via email to

[Prev in Thread] Current Thread [Next in Thread]