From: Vladimir Zolotykh
Subject: finding CLOS idiom
Date: 
Message-ID: <3C3EBE64.B0AEA06A@eurocom.od.ua>
Hi

Suppose I have two classes, say MASTER and SLAVE. Instances of both
can operate on its own, e.g. I can create instance of MASTER, call
defined methods on it etc, the same for SLAVE. Instance of SLAVE has
slot PARENT that can refers the instance of MASTER. In that case such
instance should behave slightly different than plain instance of SLAVE
(w/o value of that slot). For example, I might have method, say
CAN-ACCESS-PAGE (it doesn't matter what it actually do or what that
name stands for, I'm just going to illustrate the idea) that for plain
instance of SLAVE returns T if being called with A, B, C, D. For
instance of MASTER it returns T for A D. But I'm willing it returns T
for A, C, D for instance of SLAVE with non-null value of the slot PARENT.

Is appropriate idiom exits among various widely known CLOS solutions ?
Probably it does unless I explained badly or choosed completely wrong
model for such things.

Best regards

-- 
Vladimir Zolotykh                         ······@eurocom.od.ua

From: Kenny Tilton
Subject: Re: finding CLOS idiom
Date: 
Message-ID: <3C3ECE8D.AF18EB92@nyc.rr.com>
Vladimir Zolotykh wrote:
>  For example, I might have method, say
> CAN-ACCESS-PAGE (it doesn't matter what it actually do or what that
> name stands for, I'm just going to illustrate the idea) that for plain
> instance of SLAVE returns T if being called with A, B, C, D. For
> instance of MASTER it returns T for A D. But I'm willing it returns T
> for A, C, D for instance of SLAVE with non-null value of the slot PARENT.

Are A-D types or literals or something else? Did you mean those
input-putput combos literally, or were you just typing "A, C, D" at
random? I am hoping the latter, because otherwise there is no rhyme or
reason to this question: the slave loses access to B but not C because
the master does not have access to B or C...hunh?

If what you meant was that when a slave has a master the pages it can
access are mediated by its master and by its own access, otherwise only
by its own access, then you might have something like:

(defmethod can-access-page ((self Slave) (page A)) t) ;; etc for B, C, D

(defmethod can-access-page ((self master) (page A)) t) ;; same for D

(defmethod can-access-page :around ((self slave) page)
   (and (or (null (parent self))
            (can-access-page (parent self) page)))
        (call-next-method)))

But conceivably you did not mean A-D to be types or at least that
different instances of slave would have different answers for different
values of A-D. If so, keep the :around method and just code:

  (defmethod can-access-page (self page)
      (find (required-access-code page) (my-access-codes self)))) ;; or
whatever test you have in mind

kenny
clinisys
From: Vladimir Zolotykh
Subject: Re: finding CLOS idiom
Date: 
Message-ID: <3C3EEB19.8E842B77@eurocom.od.ua>
Kenny Tilton wrote:
> 
> (defmethod can-access-page ((self Slave) (page A)) t) ;; etc for B, C, D
> 
> (defmethod can-access-page ((self master) (page A)) t) ;; same for D
> 
> (defmethod can-access-page :around ((self slave) page)
>    (and (or (null (parent self))
>             (can-access-page (parent self) page)))
>         (call-next-method)))

This implies that we have completely independent logic for both primary methods on
CAN-ACCESS-PAGE but I'd like something mixture of both in a was I don't know yet. 
Of course it is possible do that such a way. Though my aim was to take benefits 
of CLOS and not overload things with more conditionals that it needed...

> 
> But conceivably you did not mean A-D to be types or at least that
> different instances of slave would have different answers for different
> values of A-D. If so, keep the :around method and just code:
> 
>   (defmethod can-access-page (self page)
>       (find (required-access-code page) (my-access-codes self)))) ;; or
> whatever test you have in mind

-- 
Vladimir Zolotykh                         ······@eurocom.od.ua
From: Kenny Tilton
Subject: Re: finding CLOS idiom
Date: 
Message-ID: <3C3F1719.33F2D602@nyc.rr.com>
Vladimir Zolotykh wrote:
> 
> Kenny Tilton wrote:
> >
> > (defmethod can-access-page ((self Slave) (page A)) t) ;; etc for B, C, D
> >
> > (defmethod can-access-page ((self master) (page A)) t) ;; same for D
> >
> > (defmethod can-access-page :around ((self slave) page)
> >    (and (or (null (parent self))
> >             (can-access-page (parent self) page)))
> >         (call-next-method)))
> 
> This implies that we have completely independent logic for both primary methods on
> CAN-ACCESS-PAGE but I'd like something mixture of both in a was I don't know yet.

OK, I better wait until the spec settles down before I do any more
coding.

:)

kenny
clinisys
From: Barry Margolin
Subject: Re: finding CLOS idiom
Date: 
Message-ID: <mtF%7.44$dE2.141540@burlma1-snr2>
In article <·················@eurocom.od.ua>,
Vladimir Zolotykh  <······@eurocom.od.ua> wrote:
>Kenny Tilton wrote:
>> 
>> (defmethod can-access-page ((self Slave) (page A)) t) ;; etc for B, C, D
>> 
>> (defmethod can-access-page ((self master) (page A)) t) ;; same for D
>> 
>> (defmethod can-access-page :around ((self slave) page)
>>    (and (or (null (parent self))
>>             (can-access-page (parent self) page)))
>>         (call-next-method)))
>
>This implies that we have completely independent logic for both primary
>methods on
>CAN-ACCESS-PAGE but I'd like something mixture of both in a was I don't
>know yet. 
>Of course it is possible do that such a way. Though my aim was to take benefits 
>of CLOS and not overload things with more conditionals that it needed...

Since CLOS method dispatch is based on classes, you would have to have more
distinct classes in order to do it that way.  Instead of just having a
class SLAVE, you could have:

(defgeneric can-access-page
  (:method-combination-type AND))

(defclass slave ...)

(defmethod can-acces-page ((self slave) (page A)) t)
...

(defclass slave-with-master (slave) ()
  master)

(defmethod can-access-page ((self slave-with-master) page)
  (can-access-page master page))

The AND method combination type will cause it to combine the result of the
SLAVE method and the SLAVE-WITH-MASTER method (which just queries the
master).

-- 
Barry Margolin, ······@genuity.net
Genuity, Woburn, MA
*** DON'T SEND TECHNICAL QUESTIONS DIRECTLY TO ME, post them to newsgroups.
Please DON'T copy followups to me -- I'll assume it wasn't posted to the group.
From: Vladimir Zolotykh
Subject: Re: finding CLOS idiom
Date: 
Message-ID: <3C443A14.70713562@eurocom.od.ua>
Just a short summary.

Introduced new mixin WITH-PARENT-MIXIN. Derived new classer from it
(and from 'plain' classes w/o parent e.g., MASTER, SLAVE).  Defined
CAN-ACCESS-PAGE-P with AND method-combination-type. And defined method
on this GF specialized on WITH-PARENT-MIXIN. Also this GF has methods
specialized on MASTER, SLAVE).

-- 
Vladimir Zolotykh                         ······@eurocom.od.ua
From: Pierre R. Mai
Subject: Re: finding CLOS idiom
Date: 
Message-ID: <878zb57ydp.fsf@orion.bln.pmsf.de>
Vladimir Zolotykh <······@eurocom.od.ua> writes:

> Suppose I have two classes, say MASTER and SLAVE. Instances of both
> can operate on its own, e.g. I can create instance of MASTER, call
> defined methods on it etc, the same for SLAVE. Instance of SLAVE has
> slot PARENT that can refers the instance of MASTER. In that case such
> instance should behave slightly different than plain instance of SLAVE
> (w/o value of that slot). For example, I might have method, say
> CAN-ACCESS-PAGE (it doesn't matter what it actually do or what that
> name stands for, I'm just going to illustrate the idea) that for plain
> instance of SLAVE returns T if being called with A, B, C, D. For
> instance of MASTER it returns T for A D. But I'm willing it returns T
> for A, C, D for instance of SLAVE with non-null value of the slot PARENT.

Like Kenny Tilton I'm a bit perplexed by the influence of the parent
on the returned list of values.

That said, if there are lots of methods on SLAVE that change
behaviour with a non-null PARENT, I'd probably use distinct classes to
model the behaviour, e.g.

;; The master
(defclass master () 
  (...))

;; The unparented "slave", probably want a better name for this
(defclass independent () 
  (...))

;; A real slave with a parent...
(defclass slave (independent)
  ((parent :initarg :parent :reader slave-parent) ...))

So in order to enslave an independent, you do

(defmethod enslave-independent ((independent independent) master)
  ;; CMU CL still doesn't support initargs in change-class
  #-CMU
  (change-class independent 'slave :parent master)
  #+CMU
  (reinitialize-instance (change-class independent 'slave) :parent master))

Similarly to free a slave:

(defmethod free-slave ((slave slave))
  (change-class slave 'independent))

Now you can override methods for independent, in the safe knowledge
that parent is bound:

(defmethod can-access-page ((node master) page)
  ...)

(defmethod can-access-page ((node independent) page)
  ...)

(defmethod can-access-page ((node slave) page)
  (and (call-next-method)
       (can-access-page (slave-parent node) page)))

Regs, Pierre.

-- 
Pierre R. Mai <····@acm.org>                    http://www.pmsf.de/pmai/
 The most likely way for the world to be destroyed, most experts agree,
 is by accident. That's where we come in; we're computer professionals.
 We cause accidents.                           -- Nathaniel Borenstein