From: Karol Skocik
Subject: CLOS question
Date: 
Message-ID: <1128480601.754340.240390@g49g2000cwa.googlegroups.com>
Hello,
  I would like to know how to dispatch in CLOS, not directly on the
type of argument,
but on attribute of the argument - if it is possible.

I have a struct like this :

(defstruct node
  attribute
  array-index
  out-edges
  in-edges)

and I have a hierarchy of attributes for nodes like this :

(defclass sc-element ()
  ((app-condition :initarg :app-condition :initform +neutral-ac+)))

(defclass sc-broker-object (sc-element) ())

(defclass sc-cost-object (sc-element) ())

(defclass sc-variable (sc-element)
  ((value :initarg :value)))

(defclass sc-constant (sc-element)
  ((value :initarg :value)))

(defclass sc-proxy (sc-element)
  ((original-array-index :initarg :original-array-index)))

Now, what I want to do, is to output string with some dot attributes
for graphviz according to a type of argument's attribute of instance.

I want to have a method, which will look roughly like this :

(defmethod node->dot ((??) ?)
  ...)

where the input to the method will be of type node, and not directly
the instance of subtype sc-broker-object for example.

So there must probably go some other arguments to the defmethod,
telling Lisp that the thing it should dispatch is (node-attribute
node).

Is this possible? If no, I will make a macro which dispatches it behind
the scene, but it would be nice to have such feature.

Thanks for any ideas,
  Karol

From: drewc
Subject: Re: CLOS question
Date: 
Message-ID: <COH0f.86292$oW2.35950@pd7tw1no>
Karol Skocik wrote:
> Hello,
>   I would like to know how to dispatch in CLOS, not directly on the
> type of argument,
> but on attribute of the argument - if it is possible.
> 
> I have a struct like this :
> 
> (defstruct node
>   attribute
>   array-index
>   out-edges
>   in-edges)
> 
> and I have a hierarchy of attributes for nodes like this :
> 
> (defclass sc-element ()
>   ((app-condition :initarg :app-condition :initform +neutral-ac+)))
> 
> (defclass sc-broker-object (sc-element) ())
> 
> (defclass sc-cost-object (sc-element) ())
> 
> (defclass sc-variable (sc-element)
>   ((value :initarg :value)))
> 
> (defclass sc-constant (sc-element)
>   ((value :initarg :value)))
> 
> (defclass sc-proxy (sc-element)
>   ((original-array-index :initarg :original-array-index)))
> 
> Now, what I want to do, is to output string with some dot attributes
> for graphviz according to a type of argument's attribute of instance.
> 
> I want to have a method, which will look roughly like this :
> 
> (defmethod node->dot ((??) ?)
>   ...)
> 
> where the input to the method will be of type node, and not directly
> the instance of subtype sc-broker-object for example.

(defmethod node-to-dot ((node node))
  (node->dot-using-attibute node (node-attribute node)))

(defmethod node-to-dot-using-attribute ((node node) (attribute sc-element))
  t)

In essense, creating a Meta Node Protocol.


> So there must probably go some other arguments to the defmethod,
> telling Lisp that the thing it should dispatch is (node-attribute
> node).

Nope. :)

> Is this possible? If no, I will make a macro which dispatches it behind
> the scene, but it would be nice to have such feature.

I think something like the above is more in the spirit of CLOS. However, 
i have been known to use something like the following :

(defmacro define-attribute-function (attributes &body function-form)
   `(progn
     ,@(loop for a in attributes
	    collect
	    `(defmethod node-to-dot-using-attribute
	      ((node node)(attribute ,a))
	      ,@function-form))))


(macroexpand-1 `(define-attribute-function (sc-contstant sc-variable)
			  (print attribute)))
=>(PROGN
     (DEFMETHOD NODE->DOT-USING-ATTRIBUTE
	((NODE NODE) (ATTRIBUTE SC-CONTSTANT))
       (PRINT ATTRIBUTE))
     (DEFMETHOD NODE->DOT-USING-ATTRIBUTE
	((NODE NODE) (ATTRIBUTE SC-VARIABLE))
       (PRINT ATTRIBUTE)))
T

In essence creating your own CLNS :)


-- 
Drew Crampsie
drewc at tech dot coop
"Never mind the bollocks -- here's the sexp's tools."
	-- Karl A. Krueger on comp.lang.lisp
From: Karol Skocik
Subject: Re: CLOS question
Date: 
Message-ID: <1128484457.632987.90500@z14g2000cwz.googlegroups.com>
this is nice :

> (defmethod node-to-dot ((node node))
>   (node->dot-using-attibute node (node-attribute node)))
>
> (defmethod node-to-dot-using-attribute ((node node) (attribute
> sc-element))
>   t)
> In essense, creating a Meta Node Protocol.

so I will go this way. But does it have something with MOP? I am a
little scared of MOP now, I want to avoid it until I will be a big boy
:)

anyway, if I will want to use your second idea - which expands into
this :

 =>(PROGN
     (DEFMETHOD NODE->DOT-USING-ATTRIBUTE
        ((NODE NODE) (ATTRIBUTE SC-CONTSTANT))
       (PRINT ATTRIBUTE))
     (DEFMETHOD NODE->DOT-USING-ATTRIBUTE
        ((NODE NODE) (ATTRIBUTE SC-VARIABLE))
       (PRINT ATTRIBUTE)))

I need to take care to happen this at which time? It looks to me, that
it has to be expanded at read-time, but I dont know, I am still newbie.

Thanks!
  Karol
From: Kenny Tilton
Subject: Re: CLOS question
Date: 
Message-ID: <joI0f.4841$Fc4.3597@twister.nyc.rr.com>
Karol Skocik wrote:

> this is nice :
> 
> 
>>(defmethod node-to-dot ((node node))
>>  (node->dot-using-attibute node (node-attribute node)))
>>
>>(defmethod node-to-dot-using-attribute ((node node) (attribute
>>sc-element))
>>  t)
>>In essense, creating a Meta Node Protocol.
> 
> 
> so I will go this way. But does it have something with MOP?

No, it has to do with you being confused.

You want a method specialized on something other than the arguments 
passed to the method. If that sounds bad, that is because it is.

You are not really trying to go from a node to a dot, you are trying to 
go from a dot-attribute to a dot, but you want to pass the node. What 
else will you do with the node in that function? Think about it. Two 
different types of node might have the same dot-attribute, or two nodes 
of the same type might have different dot-attributes.

So note-to-dot should be dot-attribute-to-dot, unless in some cases you 
need to see the node. then you need to refactor, with node-to-dot 
calling dot-attribute-to-dot, sometimes with a little extra processing 
based on node info.

-- 
Kenny

Why Lisp? http://wiki.alu.org/RtL_Highlight_Film

"I've wrestled with reality for 35 years, Doctor, and I'm happy to state 
I finally won out over it."
     Elwood P. Dowd, "Harvey", 1950
From: Karol Skocik
Subject: Re: CLOS question
Date: 
Message-ID: <1128486268.388568.291180@g44g2000cwa.googlegroups.com>
Yes, you are right about that, that it is not very nice. I need one
thing from node - value of array-index. So, I can either pass it as a
another argument, which is ok, but I wanted to hide it with passing the
whole node.
I don't want to refactorize, because this stuff what I am adding now is
just for my better understanding of the topology, but does not have any
impact on the core algorithms, and I don't want the core structures to
have another attributes which are used only very occasionally.

Cheers,
  Karol
From: Kenny Tilton
Subject: Re: CLOS question
Date: 
Message-ID: <ToJ0f.4845$Fc4.821@twister.nyc.rr.com>
Karol Skocik wrote:

> Yes, you are right about that, that it is not very nice. I need one
> thing from node - value of array-index. So, I can either pass it as a
> another argument, which is ok, but I wanted to hide it with passing the
> whole node.

Then you have to unpack the node inside a DEFUN and dispatch on the 
unpacked values. This is elementary stuff, not something that justifies 
bizarre MOPpery.

> I don't want to refactorize, because this stuff what I am adding now is
> just for my better understanding of the topology,...

So you are just looking for trouble? Oh, OK, knock yourself out.

> ... but does not have any
> impact on the core algorithms, and I don't want the core structures to
> have another attributes which are used only very occasionally.

It does not bleeping matter how often an attribute shapes the dispatch. 
If it ever shapes it, it is part of dispatch. This also is elementary.

You remind me of people who use phone number attributes to store post 
office box numbers because no one with a PO box ever has a phone number 
and there are not many cases where there is a PO Box so they do not want 
to add a PO Box field to their database. Afraid it will tip over, I presume.

Like I said, the problem is not with GF dispatch, it is with your 
classic "clever programmer" mentality. As we learned from Spinal Tap, it 
is a fine line between stupid and clever.

Me, I would unpack the node and be done with it in about ninety seconds. 
I foresee you up to your neck in AMOP for the next three weeks. Just to 
handle one tiny bit of programming.

And please drop this pose of wanting to improve your topology, whatever 
that is. You do not learn language constructs by using them wrong.

-- 
Kenny

Why Lisp? http://wiki.alu.org/RtL_Highlight_Film

"I've wrestled with reality for 35 years, Doctor, and I'm happy to state 
I finally won out over it."
     Elwood P. Dowd, "Harvey", 1950
From: John
Subject: Re: CLOS question
Date: 
Message-ID: <slrndkat1m.1ein.zuf8VvRd@mailinator.com>
On 2005-10-05, Kenny Tilton <·······@nyc.rr.com> wrote:
>  Then you have to unpack the node inside a DEFUN and dispatch on the 
>  unpacked values. This is elementary stuff, not something that justifies 
>  bizarre MOPpery.

Is there such a thing as non-bizarre MOPpery?

:)
From: drewc
Subject: Re: CLOS question
Date: 
Message-ID: <z2J0f.86647$oW2.83973@pd7tw1no>
Karol Skocik wrote:
> this is nice :
> 
> 
>>(defmethod node-to-dot ((node node))
>>  (node->dot-using-attibute node (node-attribute node)))
>>
>>(defmethod node-to-dot-using-attribute ((node node) (attribute
>>sc-element))
>>  t)
>>In essense, creating a Meta Node Protocol.
> 
> 
> so I will go this way. But does it have something with MOP? I am a
> little scared of MOP now, I want to avoid it until I will be a big boy
> :)

There is no MOP use involved, just CLOS, but it is similar in spirit to 
the MOP. CLOS itself is implemented like this, with SLOT-VALUE, for 
example, calling SLOT-VALUE-USING-CLASS. One of the coolest things about 
lisp is how easy it is to build your own abstractions like this :)

> anyway, if I will want to use your second idea - which expands into
> this :
> 
>  =>(PROGN
>      (DEFMETHOD NODE->DOT-USING-ATTRIBUTE
>         ((NODE NODE) (ATTRIBUTE SC-CONTSTANT))
>        (PRINT ATTRIBUTE))
>      (DEFMETHOD NODE->DOT-USING-ATTRIBUTE
>         ((NODE NODE) (ATTRIBUTE SC-VARIABLE))
>        (PRINT ATTRIBUTE)))
> 
> I need to take care to happen this at which time? It looks to me, that
> it has to be expanded at read-time, but I dont know, I am still newbie.

I'm guessing you're confused by my use of MACROEXPAND-1, which was 
simply to show you what the macro eventually expands into. In this case, 
there is no need to worry about it. DEFCLASS and DEFMETHOD are 
themselves macros which expand into forms which do the actual work 
(expand one to see what i mean). If CLOS did not exist in Common Lisp, 
it would be possible to build your own, by using techniques similar to 
what i have suggested here (and this was, in fact, how CLOS came to be). 
How cool is that!



-- 
Drew Crampsie
drewc at tech dot coop
  "... the most advanced use of lisp in the field of bass lure sales"
	-- Xach on #lisp
From: Kalle Olavi Niemitalo
Subject: Re: CLOS question
Date: 
Message-ID: <87y858a73l.fsf@Astalo.kon.iki.fi>
"Karol Skocik" <············@gmail.com> writes:

>> (defmethod node-to-dot-using-attribute ((node node)
>>                                         (attribute sc-element))
>>   t)
>> In essense, creating a Meta Node Protocol.
>
> so I will go this way. But does it have something with MOP? I am a
> little scared of MOP now, I want to avoid it until I will be a big boy
> :)

The slot-value-using-class function described in AMOP uses
a similar scheme, but the mechanism does not rely on a MOP.
The standard function cl:slot-unbound also does this.
From: Kenny Tilton
Subject: Re: CLOS question
Date: 
Message-ID: <69I0f.4840$Fc4.2438@twister.nyc.rr.com>
drewc wrote:
> Karol Skocik wrote:
> 
>> Hello,
>>   I would like to know how to dispatch in CLOS, not directly on the
>> type of argument,
>> but on attribute of the argument - if it is possible.
>>
>> I have a struct like this :
>>
>> (defstruct node
>>   attribute
>>   array-index
>>   out-edges
>>   in-edges)
>>
>> and I have a hierarchy of attributes for nodes like this :
>>
>> (defclass sc-element ()
>>   ((app-condition :initarg :app-condition :initform +neutral-ac+)))
>>
>> (defclass sc-broker-object (sc-element) ())
>>
>> (defclass sc-cost-object (sc-element) ())
>>
>> (defclass sc-variable (sc-element)
>>   ((value :initarg :value)))
>>
>> (defclass sc-constant (sc-element)
>>   ((value :initarg :value)))
>>
>> (defclass sc-proxy (sc-element)
>>   ((original-array-index :initarg :original-array-index)))
>>
>> Now, what I want to do, is to output string with some dot attributes
>> for graphviz according to a type of argument's attribute of instance.
>>
>> I want to have a method, which will look roughly like this :
>>
>> (defmethod node->dot ((??) ?)
>>   ...)
>>
>> where the input to the method will be of type node, and not directly
>> the instance of subtype sc-broker-object for example.
> 
> 
> (defmethod node-to-dot ((node node))
>  (node->dot-using-attibute node (node-attribute node)))


I am going to guess that node-to-dot can be a DEFUN.

> 
> (defmethod node-to-dot-using-attribute ((node node) (attribute sc-element))
>  t)
> 
> In essense, creating a Meta Node Protocol.
> 

-- 
Kenny

Why Lisp? http://wiki.alu.org/RtL_Highlight_Film

"I've wrestled with reality for 35 years, Doctor, and I'm happy to state 
I finally won out over it."
     Elwood P. Dowd, "Harvey", 1950
From: drewc
Subject: Re: CLOS question
Date: 
Message-ID: <gmJ0f.99324$tl2.42162@pd7tw3no>
Kenny Tilton wrote:
>> (defmethod node-to-dot ((node node))
>>  (node->dot-using-attibute node (node-attribute node)))
> 
> 
> 
> I am going to guess that node-to-dot can be a DEFUN.

And i left in node->dot-using-attribute, which i meant to rename 
node-to-dot-using-attribute, just to please the pedants! I'm just not 
very good at usenet. :)

-- 
Drew Crampsie
drewc at tech dot coop
  "... the most advanced use of lisp in the field of bass lure sales."
	-- Xach on #lisp