From: Didier Verna
Subject: [CLOS] Ensuring a method exists
Date: 
Message-ID: <mux7izpdafx.fsf@uzeb.lrde.epita.fr>
        Hi !

Suppose I have:

(defgeneric foo (a b) ...)

(defclass base () ...)
(defmethod foo ((a base) (b base)) ...)



I'd like to ensure that if somebody writes a derived class:

(defclass derived (base) ...)

she also provides a method for this class:

(defmethod foo ((a derived) (b derived)) ...)



I'd be happy with a dynamic solution. Perhaps, the method combination would
check that the first applicable method matches exactly the class of the
arguments. But I know nothing about the MOP yet ...


Thanks !

-- 
Check out my new jazz CD on http://www.didierverna.com/ !

Didier Verna	EPITA / LRDE, 14-16 rue Voltaire   Tel.+33 (1) 44 08 01 85
             	94276 Le Kremlin-Bic�tre, France   Fax.+33 (1) 53 14 59 22

From: Christophe Rhodes
Subject: Re: [CLOS] Ensuring a method exists
Date: 
Message-ID: <sqodt1yaw0.fsf@cam.ac.uk>
Didier Verna <······@lrde.epita.fr> writes:

> I'd like to ensure that if somebody writes a derived class:
>
> (defclass derived (base) ...)
>
> she also provides a method for this class:
>
> (defmethod foo ((a derived) (b derived)) ...)
>
> I'd be happy with a dynamic solution. Perhaps, the method combination would
> check that the first applicable method matches exactly the class of the
> arguments. But I know nothing about the MOP yet ...

Interesting question.

Although it's not currently exposed to the DEFCLASS macro, SBCL's
version of CLOS (which is derived from the PCL from Xerox) has the
notion of CLASS-EQ specializers (as well as the MOP-standard CLASS and
EQL-SPECIALIZER specializers, implementing the class-based and
object-based dispatch that was standardized as part of ANSI CL).  It
sounds to me like a simple dynamic solution would be to define your
method FOO (BASE BASE) to use CLASS-EQ specializers rather than the
usual CLASS specializers; then this method will not be applicable to
objects of derived classes.  If you then want to automatically
generate a method if such arguments are passed, you can define a
method on no-applicable-method (or alternatively a method on FOO using
CLASS specializers) to perform the job of defining a method and
calling it.

(There are details lurking in there that are somewhat different
depending on what you want to happen with :after methods, :around
methods and so on; it should be possible to do without too much
difficulty.  If you don't want to rely on the PCL-internal
specializer, it probably isn't too hard to define for yourself, though
it means using a special generic function class and a specialized
method for compute-applicable-methods, I think.)

Christophe
From: Didier Verna
Subject: Re: [CLOS] Ensuring a method exists
Date: 
Message-ID: <muxlko5bj5d.fsf@uzeb.lrde.epita.fr>
Christophe Rhodes wrote:

> Interesting question.
>
> [...]

        Hi Christophe.

I have yet to decode your message, and I'll get back to you as soon as can :-)

Thanks.


-- 
Check out my new jazz CD on http://www.didierverna.com/ !

Didier Verna	EPITA / LRDE, 14-16 rue Voltaire   Tel.+33 (1) 44 08 01 85
             	94276 Le Kremlin-Bic�tre, France   Fax.+33 (1) 53 14 59 22
From: Pascal Costanza
Subject: Re: [CLOS] Ensuring a method exists
Date: 
Message-ID: <4nvug7Fc66srU2@individual.net>
Christophe Rhodes wrote:
> Didier Verna <······@lrde.epita.fr> writes:
> 
>> I'd like to ensure that if somebody writes a derived class:
>>
>> (defclass derived (base) ...)
>>
>> she also provides a method for this class:
>>
>> (defmethod foo ((a derived) (b derived)) ...)
>>
>> I'd be happy with a dynamic solution. Perhaps, the method combination would
>> check that the first applicable method matches exactly the class of the
>> arguments. But I know nothing about the MOP yet ...
> 
> Interesting question.
> 
> Although it's not currently exposed to the DEFCLASS macro, SBCL's
> version of CLOS (which is derived from the PCL from Xerox) has the
> notion of CLASS-EQ specializers (as well as the MOP-standard CLASS and
> EQL-SPECIALIZER specializers, implementing the class-based and
> object-based dispatch that was standardized as part of ANSI CL).  It
> sounds to me like a simple dynamic solution would be to define your
> method FOO (BASE BASE) to use CLASS-EQ specializers rather than the
> usual CLASS specializers; then this method will not be applicable to
> objects of derived classes.  If you then want to automatically
> generate a method if such arguments are passed, you can define a
> method on no-applicable-method (or alternatively a method on FOO using
> CLASS specializers) to perform the job of defining a method and
> calling it.

I see a problem when you want to do a call-next-method because the 
class-eq methods of less special classes are by definition not in the 
list of applicable methods.


Pascal

-- 
My website: http://p-cos.net
Common Lisp Document Repository: http://cdr.eurolisp.org
Closer to MOP & ContextL: http://common-lisp.net/project/closer/
From: Didier Verna
Subject: Re: [CLOS] Ensuring a method exists
Date: 
Message-ID: <mux64f15vrt.fsf@uzeb.lrde.epita.fr>
Christophe Rhodes wrote:

> Although it's not currently exposed to the DEFCLASS macro, SBCL's version of
> CLOS (which is derived from the PCL from Xerox) has the notion of CLASS-EQ
> specializers (as well as the MOP-standard CLASS and EQL-SPECIALIZER
> specializers, implementing the class-based and object-based dispatch that
> was standardized as part of ANSI CL). It sounds to me like a simple dynamic
> solution would be to define your method FOO (BASE BASE) to use CLASS-EQ
> specializers rather than the usual CLASS specializers;

        I get the idea, but I can't seem to make it work (I might be missing
something obvious). Trying something like this for instance:

(defmethod same ((a (sb-pcl::class-eq 'cls))
		 (b (sb-pcl::class-eq 'cls)))
  ...)

gives this error:


; caught ERROR:
;   (during macroexpansion of (DEFMETHOD SAME ...))
;   (SB-PCL::CLASS-EQ CLS) is not a legal class name.



Thanks.

-- 
Check out my new jazz CD on http://www.didierverna.com/ !

Didier Verna	EPITA / LRDE, 14-16 rue Voltaire   Tel.+33 (1) 44 08 01 85
             	94276 Le Kremlin-Bic�tre, France   Fax.+33 (1) 53 14 59 22
From: Christophe Rhodes
Subject: Re: [CLOS] Ensuring a method exists
Date: 
Message-ID: <sqd599sc3q.fsf@cam.ac.uk>
Didier Verna <······@lrde.epita.fr> writes:

> Christophe Rhodes wrote:
>
>> Although it's not currently exposed to the DEFCLASS macro, SBCL's version of
>> CLOS (which is derived from the PCL from Xerox) has the notion of CLASS-EQ
>> specializers (as well as the MOP-standard CLASS and EQL-SPECIALIZER
>> specializers, implementing the class-based and object-based dispatch that
>> was standardized as part of ANSI CL). It sounds to me like a simple dynamic
>> solution would be to define your method FOO (BASE BASE) to use CLASS-EQ
>> specializers rather than the usual CLASS specializers;
>
>         I get the idea, but I can't seem to make it work (I might be missing
> something obvious). Trying something like this for instance:
>
> (defmethod same ((a (sb-pcl::class-eq 'cls))
> 		 (b (sb-pcl::class-eq 'cls)))
>   ...)
>
> gives this error:

Yeah.  I said "it's not exposed to the DEFCLASS macro, while what I
meant was "it's not exposed to the DEFMETHOD macro.  You would have to
create the specializers yourself.

Additionally, an internal function,
SB-PCL::PARAMETER-SPECIALIZER-DECLARATION-IN-DEFMETHOD, was written
without anticipating that CLASS-EQ specializers might exist.  The body
of (FLET SPECIALIZER-CLASS) in that function needs to be changed to
                    (if (typep specializer 'class)
                        specializer
                        (if (typep specializer 'class-eq-specializer)
                            (specializer-object specializer)
                            (find-class specializer nil)))))
(I won't paste the whole function in, because it's absolutely huge).

Once that function is fixed, then
  (defclass super () ())
  (defclass sub (super) ())
  (defgeneric test (x))
  (let ((spec (sb-pcl::class-eq-specializer (find-class 'super))))
    (eval `(defmethod test ((x ,spec)) (format t "~%Hello, World!~%"))))
  (test (make-instance 'super)) ; prints "Hello, World!"
  (test (make-instance 'sub)) ; signals no-applicable-method.

To get around the need for (eval `(defmethod ...)), we either need to
invent some surface syntax for the defmethod macro, or else create the
method entirely using the MOP rather than the interface macro.

Christophe
From: Lars Rune Nøstdal
Subject: Re: [CLOS] Ensuring a method exists
Date: 
Message-ID: <pan.2006.09.27.08.18.32.822905@gmail.com>
On Wed, 27 Sep 2006 09:40:18 +0200, Didier Verna wrote:

> 
>         Hi !
> 
> Suppose I have:
> 
> (defgeneric foo (a b) ...)
> 
> (defclass base () ...)
> (defmethod foo ((a base) (b base)) ...)
> 
> 
> 
> I'd like to ensure that if somebody writes a derived class:
> 
> (defclass derived (base) ...)
> 
> she also provides a method for this class:
> 
> (defmethod foo ((a derived) (b derived)) ...)
> 
> 
> 
> I'd be happy with a dynamic solution. Perhaps, the method combination
> would check that the first applicable method matches exactly the class of
> the arguments. But I know nothing about the MOP yet ...

This seems to work:

(defclass SomeBase ()
  ())


(defmethod initialize-instance :before ((some-base SomeBase) &key)
  (format t "Checking for `foo': ~A~%"
          (find-method #'foo '() (mapcar #'find-class
                                         (list (type-of some-base)
                                               (type-of some-base))))))


(defmethod foo ((a SomeBase) (b SomeBase))
  (write-line "(foo SomeBase SomeBase)"))


(defclass SomeDerived (SomeBase)
  ())

cl-user> (make-instance 'SomeBase)
Checking for `foo': #<standard-method foo (SomeBase SomeBase) {AB54379}>
#<SomeBase {ACEAF41}>
cl-user> (make-instance 'SomeDerived) ;; *bang!*
cl-user> (defmethod foo ((a SomeDerived) (b SomeDerived))
           (write-line "(foo SomeDerived SomeDerived)"))
#<standard-method foo (SomeDerived SomeDerived) {AE59049}>
cl-user> (make-instance 'SomeDerived)
Checking for `foo': #<standard-method foo (SomeDerived
                                           SomeDerived) {AE59049}>
#<SomeDerived {AE68A91}>
cl-user> (fmakunbound 'foo)
foo
cl-user> (make-instance 'SomeBase) ;; *bang!*
; Evaluation aborted
cl-user> (make-instance 'SomeDerived) ;; *bang!*
; Evaluation aborted

(I feel like Steve Jobs and his booooms! :))

You could add a handler in `initialize-instance' that would show a more
helpful message or whatever.

-- 
Lars Rune Nøstdal
http://lars.nostdal.org/
From: Didier Verna
Subject: Re: [CLOS] Ensuring a method exists
Date: 
Message-ID: <mux1wpxd5x6.fsf@uzeb.lrde.epita.fr>
Lars Rune N�stdal <···········@gmail.com> wrote:

> This seems to work:
>
> (defclass SomeBase ()
>   ())
>
>
> (defmethod initialize-instance :before ((some-base SomeBase) &key)
>   (format t "Checking for `foo': ~A~%"
>           (find-method #'foo '() (mapcar #'find-class
>                                          (list (type-of some-base)
>                                                (type-of some-base))))))
>
>
> (defmethod foo ((a SomeBase) (b SomeBase))
>   (write-line "(foo SomeBase SomeBase)"))
>
>
> (defclass SomeDerived (SomeBase)
>   ())


        That's a nice solution but it has one caveat (my question was probably
not clear enough about this): your trick checks for the existence of a method
only for the class you instanciate, and not for the subclasses.

So imagine having A <- B and creating only instances of B. The lack of method
for class A would go unnoticed. But I want the check for the whole hierarchy
(consider for instance that I'm using the AND method combination type and I'm
expecting an implementation for all the classes).

-- 
Check out my new jazz CD on http://www.didierverna.com/ !

Didier Verna	EPITA / LRDE, 14-16 rue Voltaire   Tel.+33 (1) 44 08 01 85
             	94276 Le Kremlin-Bic�tre, France   Fax.+33 (1) 53 14 59 22
From: Ken Tilton
Subject: Re: [CLOS] Ensuring a method exists
Date: 
Message-ID: <%_rSg.312$7O6.105@newsfe11.lga>
Didier Verna wrote:
> Lars Rune N�stdal <···········@gmail.com> wrote:
> 
> 
>>This seems to work:
>>
>>(defclass SomeBase ()
>>  ())
>>
>>
>>(defmethod initialize-instance :before ((some-base SomeBase) &key)
>>  (format t "Checking for `foo': ~A~%"
>>          (find-method #'foo '() (mapcar #'find-class
>>                                         (list (type-of some-base)
>>                                               (type-of some-base))))))
>>
>>
>>(defmethod foo ((a SomeBase) (b SomeBase))
>>  (write-line "(foo SomeBase SomeBase)"))
>>
>>
>>(defclass SomeDerived (SomeBase)
>>  ())
> 
> 
> 
>         That's a nice solution but it has one caveat (my question was probably
> not clear enough about this): your trick checks for the existence of a method
> only for the class you instanciate, and not for the subclasses.
> 
> So imagine having A <- B and creating only instances of B. The lack of method
> for class A would go unnoticed. But I want the check for the whole hierarchy
> (consider for instance that I'm using the AND method combination type and I'm
> expecting an implementation for all the classes).
> 

How portable does it have to be? If not, maybe your Lisp has something 
like ACL's:

(method-specializers
    (find-method #'make-style-font nil
        (list (find-class 'gui-style-ftgl))))

-> (#<STANDARD-CLASS GUI-STYLE-FTGL>)

So you could check that you did not get something specialized on a 
superclass.

Another trick, as long as you are inventing requirements that fly in the 
face of CLOS (if there is a method for superX, than one /has/ been 
provided for subX!), is to simplify things for users by providing 
macrology that (a) defines a method X and (b) records the meta-fact as a 
symbol property or something.

Of course the big question no one will ask is why you want to do this. 
Sounds like bad design. But you are not alone, we get people wanting to 
do this almost as often as we get people trying to fix the parens.

:)

kt


-- 
Cells: http://common-lisp.net/project/cells/

"I'll say I'm losing my grip, and it feels terrific."
    -- Smiling husband to scowling wife, New Yorker cartoon
From: Christophe Rhodes
Subject: Re: [CLOS] Ensuring a method exists
Date: 
Message-ID: <sqbqp1y3ny.fsf@cam.ac.uk>
Ken Tilton <·········@gmail.com> writes:

> Of course the big question no one will ask is why you want to do
> this. Sounds like bad design. But you are not alone, we get people
> wanting to do this almost as often as we get people trying to fix the
> parens.

I'm not so certain that this kind of thing is necessarily bad design.
I think that CLOS's generic functions and class inheritance provide
good ways of adding functionality ("extending", if you will) by
subclassing; what I think is harder to express in vanilla CLOS is
removal of invariants, or generalization of functionality.

To take a concrete example, consider implementing a data structure
such as an R-tree, which has a relatively complex set of invariants
that you might want to assert are true at various points in the
protocol.  Then you implement a variant, such as the R*-tree, which
obeys the same protocol, and indeed shares much of the implementation,
but has slightly different (but overlapping) invariants.  How do you
model that, with just CLOS?  Probably what you do is define some kind
of abstract base class and make R-trees and R*-trees inherit from that
base class, but now you can't share the methods that actually should
be shared: instead you have to implement the methods separately,
admittedly maybe with a call to the same function.  So sometimes I
think it makes sense to want to treat direct instances and general
instances of a class differently: it allows you to express things in a
way that is closer to the application space (which is what we're
aiming for, right?)

I believe this is the kind of thing that beta's inner() was invented
to help in modelling; there are various claims around that it helps
with extensible GUI hierarchies (see e.g. Goldberg, Findler and Flatt,
"Super and Inner -- Together at Last!").  

Christophe
From: Ken Tilton
Subject: Re: [CLOS] Ensuring a method exists
Date: 
Message-ID: <3UtSg.5$9q2.0@newsfe12.lga>
Christophe Rhodes wrote:
> Ken Tilton <·········@gmail.com> writes:
> 
> 
>>Of course the big question no one will ask is why you want to do
>>this. Sounds like bad design. But you are not alone, we get people
>>wanting to do this almost as often as we get people trying to fix the
>>parens.
> 
> 
> I'm not so certain that this kind of thing is necessarily bad design.
> I think that CLOS's generic functions and class inheritance provide
> good ways of adding functionality ("extending", if you will) by
> subclassing; what I think is harder to express in vanilla CLOS is
> removal of invariants, or generalization of functionality.
> 
> To take a concrete example, consider implementing a data structure
> such as an R-tree, which has a relatively complex set of invariants
> that you might want to assert are true at various points in the
> protocol.  Then you implement a variant, such as the R*-tree, which
> obeys the same protocol, and indeed shares much of the implementation,
> but has slightly different (but overlapping) invariants.  How do you
> model that, with just CLOS?  Probably what you do is define some kind
> of abstract base class and make R-trees and R*-trees inherit from that
> base class, but now you can't share the methods that actually should
> be shared:

Oh. Why not? Don't see that from the set-up above. And, whatever it is, 
multiple-inheritance won't help? If not, sounds like classes and the 
very idea of OO are simply the wrong hammer for this problem, and it 
might be wiser to byte the bullet and use macrology and the DSL thing to 
Just Say What We Mean.

Now maybe that is what is going on and the OP is  just leveraging CLOS 
as a convenient internal tool to the larger API, but then that is why I 
suggest going /further/ and hide the CLOS behind some macrology, at 
which point the OP can enforce anything they want really really easily 
(instead of staring at AMOP looking for support for something not really 
OO-able).

> instead you have to implement the methods separately,
> admittedly maybe with a call to the same function.  So sometimes I
> think it makes sense to want to treat direct instances and general
> instances of a class differently: it allows you to express things in a
> way that is closer to the application space (which is what we're
> aiming for, right?)

Well, I'm not smart like you guys, I can only think in concrete, so I 
kinda would have to see the actual use case.*

kt

*  I get a kick out of it when people respond "oh, sure. here ya go. 
there's this class foo, see, and this other class bar, and...". :) k

-- 
Cells: http://common-lisp.net/project/cells/

"I'll say I'm losing my grip, and it feels terrific."
    -- Smiling husband to scowling wife, New Yorker cartoon
From: Christophe Rhodes
Subject: Re: [CLOS] Ensuring a method exists
Date: 
Message-ID: <sqbqp1jv10.fsf@cam.ac.uk>
Ken Tilton <·········@gmail.com> writes:

> Christophe Rhodes wrote:
>> To take a concrete example, consider implementing a data structure
>> such as an R-tree, which has a relatively complex set of invariants
>> that you might want to assert are true at various points in the
>> protocol.  Then you implement a variant, such as the R*-tree, which
>> obeys the same protocol, and indeed shares much of the implementation,
>> but has slightly different (but overlapping) invariants.  How do you
>> model that, with just CLOS?  Probably what you do is define some kind
>> of abstract base class and make R-trees and R*-trees inherit from that
>> base class, but now you can't share the methods that actually should
>> be shared:
>
> Oh. Why not? Don't see that from the set-up above. And, whatever it
> is, multiple-inheritance won't help? 

Sure, it will (or it can be made to), but part of the constraints that
I am assuming is that you want your class hierarchy to correspond to
your conception of the problem, rather than having to change how you
think about the problem to fit into one particular version of an
object system.  If you're not interested in talking about that, then
that's fine.

The reason I say you "can't" share the methods (which is too strong in
the general case, but is what I meant given the constraints of wanting
to use CLOS to express my problem rather than adapt my problem to
CLOS) is that neither
  (defmethod foo ((tree spatial-tree)) ...)
nor
  (defmethod foo ((tree r-tree)) ...)
  (defmethod foo ((tree r*-tree)) ...)
is appropriate.  The first case is too general: I would need to
document the inner workings so that other derived classes of spatial
tree can know how to be compatible with FOO.  The second case is too
specific: there is no way of saying that these should in fact be the
same method.  (Neither case is necessarily a problem in practice when
expressed at this simplified scale.)

Multiple inheritance might help to solve this problem if you developed
foo's protocol a bit more: say
  (defmethod foo ((tree spatial-tree)) 
    (assert-foo-invariants tree)
    ...)
and then the invariants issue could be dealt with by doing something
like
  (defclass r-tree-invariants-mixin () ())
  (defclass r-tree (r-tree-invariants-mixin spatial-tree) ())
  (defmethod assert-foo-invariants ((i r-tree-invariants-mixin)) ...)
but what is the mixin / multiple-inheritance buying us?  Only the
ability to express what we want by complicating the inheritance of our
classes, where what I am aiming towards is saying that there should
ideally be a way of expressing what we want without having to generate
implementation-only classes.

> If not, sounds like classes and the very idea of OO are simply the
> wrong hammer for this problem

Whose very idea of OO?  Just as Java's or C++'s model of objects is
not the be-all and end-all, which we as CLOS programmers can see from
our vantage point, it is also the case that CLOS's in-built models are
not the be-all and end-all of "OO", and indeed the designers of CLOS
recognized this themselves, allowing for small movements in the design
space of object-oriented programming.

> and it might be wiser to byte the bullet and use macrology and the
> DSL thing to Just Say What We Mean.

Why is this better than slightly adapting some of the existing
object-oriented system to express the object-oriented concept?  I
agree with you in that ...

> [...] maybe that is what is going on and the OP is  just leveraging CLOS
> as a convenient internal tool to the larger API 

... and it may be that your suggestion of ...

> [...] going /further/ and hide the CLOS behind some macrology, at
> which point the OP can enforce anything they want really really easily

... is sensible in any case, but ...

> (instead of staring at AMOP looking for support for something not
> really OO-able).

... you claim is that it's not really OO-able, but I don't think that
is true, and specifically I don't think it's necessarily bad design to
want to do things that help express how you think about a problem,
even if you have to tweak the language (using established protocols)
to help you achieve that.

> *  I get a kick out of it when people respond "oh, sure. here ya
> go. there's this class foo, see, and this other class bar, and...". :)

You can see a concrete but unpolished version of exactly my problem
case in the spatial-trees system; the paper I referenced gives an
example of extensible GUI widgets, as I said.

Christophe
From: Ken Tilton
Subject: Re: [CLOS] Ensuring a method exists
Date: 
Message-ID: <0yySg.3$B67.0@newsfe09.lga>
Christophe Rhodes wrote:
> Ken Tilton <·········@gmail.com> writes:
> 
> 
>>Christophe Rhodes wrote:
>>
>>>To take a concrete example, consider implementing a data structure
>>>such as an R-tree, which has a relatively complex set of invariants
>>>that you might want to assert are true at various points in the
>>>protocol.  Then you implement a variant, such as the R*-tree, which
>>>obeys the same protocol, and indeed shares much of the implementation,
>>>but has slightly different (but overlapping) invariants.  How do you
>>>model that, with just CLOS?  Probably what you do is define some kind
>>>of abstract base class and make R-trees and R*-trees inherit from that
>>>base class, but now you can't share the methods that actually should
>>>be shared:
>>
>>Oh. Why not? Don't see that from the set-up above. And, whatever it
>>is, multiple-inheritance won't help? 
> 

(It turns out multi-methods, not MI, were the solution in one paper on 
binary methods.)

> 
> Sure, it will (or it can be made to), but part of the constraints that
> I am assuming is that you want your class hierarchy to correspond to
> your conception of the problem, rather than having to change how you
> think about the problem to fit into one particular version of an
> object system.

That's a rather contentious way of viewing design; even Mohammed went to 
the mountain. Maybe I did /start out/ thinking single inheritance, but 
if I find myself writing type-sensitive code (methods) that cannot be 
aligned with an SI taxonomy (because the new code addresses concerns 
orthogonal to the original taxonomy, then MI is not forcing itself on 
me, I am simply discovering the correct taxonomy over the keyboard.

Programmers who lock onto a design decision and cling to it in the face 
of contradictory new information -- well, that's almost everyone in my 
experience, so I better not say what I think of them or people will 
start saying bad things about me on c.l.l.

Anyway, it turns out I was spending valuable time trying to help Didier 
with what he failed to disclose was worse than homework, a mere stupid 
pet trick*, so I think...

>  If you're not interested in talking about that, then
> that's fine.

Whew!

:)

kenny

* reminds me of part of a route description to a rock climb called 
Death's Door: "Don't use the jug handle just to the right of the finger 
jam, that hold is part of Cakewalk." k

-- 
Cells: http://common-lisp.net/project/cells/

"I'll say I'm losing my grip, and it feels terrific."
    -- Smiling husband to scowling wife, New Yorker cartoon
From: Rahul Jain
Subject: Re: [CLOS] Ensuring a method exists
Date: 
Message-ID: <87fye545gv.fsf@nyct.net>
Ken Tilton <·········@gmail.com> writes:

> Programmers who lock onto a design decision and cling to it in the face
> of contradictory new information -- well, that's almost everyone in my
> experience, so I better not say what I think of them or people will
> start saying bad things about me on c.l.l.

That would be a first.

-- 
Rahul Jain
·····@nyct.net
Professional Software Developer, Amateur Quantum Mechanicist
From: Rahul Jain
Subject: Re: [CLOS] Ensuring a method exists
Date: 
Message-ID: <87k63h45ia.fsf@nyct.net>
Christophe Rhodes <·····@cam.ac.uk> writes:

> Multiple inheritance might help to solve this problem if you developed
> foo's protocol a bit more: say
>   (defmethod foo ((tree spatial-tree)) 
>     (assert-foo-invariants tree)
>     ...)
> and then the invariants issue could be dealt with by doing something
> like
>   (defclass r-tree-invariants-mixin () ())
>   (defclass r-tree (r-tree-invariants-mixin spatial-tree) ())
>   (defmethod assert-foo-invariants ((i r-tree-invariants-mixin)) ...)
> but what is the mixin / multiple-inheritance buying us?  Only the
> ability to express what we want by complicating the inheritance of our
> classes, where what I am aiming towards is saying that there should
> ideally be a way of expressing what we want without having to generate
> implementation-only classes.

But wouldn't that be a good functional decomposition of the algorithm
anyway?

It's funny that funcitonal decomposition is considered a very procedural
programming type of exercise when it only benefits the readability and
maintainability of procedural programs. In OO, funcitional decomposition
allows for the whole point of OO (extensibility) to be realized.

-- 
Rahul Jain
·····@nyct.net
Professional Software Developer, Amateur Quantum Mechanicist
From: Pascal Costanza
Subject: Re: [CLOS] Ensuring a method exists
Date: 
Message-ID: <4o002mFc09i8U1@individual.net>
Ken Tilton wrote:

> Now maybe that is what is going on and the OP is  just leveraging CLOS 
> as a convenient internal tool to the larger API, but then that is why I 
> suggest going /further/ and hide the CLOS behind some macrology, at 
> which point the OP can enforce anything they want really really easily 
> (instead of staring at AMOP looking for support for something not really 
> OO-able).

Both macros and the CLOS MOP are means to do metaprogramming. The 
distinction is that macros can be used for compile-time processing of 
code [1], while the CLOS MOP is useful  for meta-programs that require 
special actions at runtime. Of course, it is always possible to make 
macros generate the code that takes care of the runtime issues, but it 
can be more convenient to rely on the MOP protocols, especially if you 
want to reuse major parts of the already existing functionality in CLOS.

Didier's example is actually a good one for the latter because you can 
delay the check whether methods are "properly" specialized until the 
latest possible stage, something that is not very easy to achieve with 
macros. That's similar to deferring class precedence lists, or the 
update protocols for changed or redefined classes, etc.


Pascal

[1] More correctly, "processing of code at macroexpansion time", but for 
most practical purposes, that's the same as compile time.

-- 
My website: http://p-cos.net
Common Lisp Document Repository: http://cdr.eurolisp.org
Closer to MOP & ContextL: http://common-lisp.net/project/closer/
From: Ken Tilton
Subject: Re: [CLOS] Ensuring a method exists
Date: 
Message-ID: <znBSg.57$gG3.22@newsfe11.lga>
Pascal Costanza wrote:
> Ken Tilton wrote:
> 
>> Now maybe that is what is going on and the OP is  just leveraging CLOS 
>> as a convenient internal tool to the larger API, but then that is why 
>> I suggest going /further/ and hide the CLOS behind some macrology, at 
>> which point the OP can enforce anything they want really really easily 
>> (instead of staring at AMOP looking for support for something not 
>> really OO-able).
> 
> 
> Both macros and the CLOS MOP are means to do metaprogramming. The 
> distinction is that macros can be used for compile-time processing of 
> code [1]

??? Hunh? I never use macros for compile-time pro... OK, once.

> ..., while the CLOS MOP is useful  for meta-programs that require 
> special actions at runtime. Of course, it is always possible to make 
> macros generate the code that takes care of the runtime issues, but it 
> can be more convenient to rely on the MOP protocols, especially if you 
> want to reuse major parts of the already existing functionality in CLOS.
> 
> Didier's example...

He did not have an example. he was literally trying to match the 
behavior of the C+= compiler in enforcing binary methods. Anyway...

>... is actually a good one for the latter because you can 
> delay the check whether methods are "properly" specialized until the 
> latest possible stage, something that is not very easy to achieve with 
> macros.

Nonsense. Macros can expand to code that gets run at load time, which 
code records (say, in, symbol properties) information to be used by 
runtime code, such as an around method to check that a method has been 
defined for the specific types of the arguments.

Or is that not "very easy"? This SuperKenny thing is getting old.

:)

kt

-- 
Cells: http://common-lisp.net/project/cells/

"I'll say I'm losing my grip, and it feels terrific."
    -- Smiling husband to scowling wife, New Yorker cartoon
From: Pascal Costanza
Subject: Re: [CLOS] Ensuring a method exists
Date: 
Message-ID: <4o0917Fcc8pcU1@individual.net>
Ken Tilton wrote:

> Pascal Costanza wrote:
>> Ken Tilton wrote:
>>
>>> Now maybe that is what is going on and the OP is  just leveraging 
>>> CLOS as a convenient internal tool to the larger API, but then that 
>>> is why I suggest going /further/ and hide the CLOS behind some 
>>> macrology, at which point the OP can enforce anything they want 
>>> really really easily (instead of staring at AMOP looking for support 
>>> for something not really OO-able).
>>
>>
>> Both macros and the CLOS MOP are means to do metaprogramming. The 
>> distinction is that macros can be used for compile-time processing of 
>> code [1]
> 
> ??? Hunh? I never use macros for compile-time pro... OK, once.

You _always_ use macros for compile-time processing of code.

Quiz question: What parameters does a macro function take, and what does 
it eventually return? Joker question: What does the return value of a 
macro function depend on?

>> ..., while the CLOS MOP is useful  for meta-programs that require 
>> special actions at runtime. Of course, it is always possible to make 
>> macros generate the code that takes care of the runtime issues, but it 
>> can be more convenient to rely on the MOP protocols, especially if you 
>> want to reuse major parts of the already existing functionality in CLOS.
>>
>> Didier's example...
> 
> He did not have an example. he was literally trying to match the 
> behavior of the C+= compiler in enforcing binary methods. Anyway...

That _is_ an example.

>> ... is actually a good one for the latter because you can delay the 
>> check whether methods are "properly" specialized until the latest 
>> possible stage, something that is not very easy to achieve with macros.
> 
> Nonsense. Macros can expand to code that gets run at load time, which 
> code records (say, in, symbol properties) information to be used by 
> runtime code, such as an around method to check that a method has been 
> defined for the specific types of the arguments.
> 
> Or is that not "very easy"? This SuperKenny thing is getting old.

"Easy" is always relative. Defining methods for 
compute-applicable-methods and compute-applicable-methods-using-classes 
is easier than what you propose. And your sketch of a solution doesn't 
yet deal with doing the check only once for each list of specializers.



Pascal

-- 
My website: http://p-cos.net
Common Lisp Document Repository: http://cdr.eurolisp.org
Closer to MOP & ContextL: http://common-lisp.net/project/closer/
From: Javier
Subject: Re: Ensuring a method exists
Date: 
Message-ID: <1159394568.567822.323080@m73g2000cwd.googlegroups.com>
Going on with this matter, and because I don't fully understand all the
answers you have done:

How would you implement an interface using CLOS with lots of different
methods? For example:

interface Collection {
  void add (Object o);
  void remove (Object o);
  ...
}
Tipically, your are going to implement lot of methods, say for example
10 or more.

The main reason for having an interface is that you are going to
provide classes based on it, and let the door open for the user to
implement new ones. So, if it doesn't make sense to implement them on
CLOS because Lisp resolves this problem in a different way, how is that
way? I mean, how is resolving Lisp this problem? Or, if CLOS doesn't
have this problem, why it doesn't?

(Note: I'm not interested in discussing but learning, so Ken please
avoid insulting again.)
From: Jack Unrue
Subject: Re: Ensuring a method exists
Date: 
Message-ID: <14imh2t6kp9b6thb8o71e3mlokpuuqskq0@4ax.com>
On 27 Sep 2006 15:02:48 -0700, "Javier" <·······@gmail.com> wrote:
>
> Going on with this matter, and because I don't fully understand all the
> answers you have done:
> 
> How would you implement an interface using CLOS with lots of different
> methods? For example:
> 
> interface Collection {
>   void add (Object o);
>   void remove (Object o);
>   ...
> }

In CLOS terms, you think of the add, remove, etc operations comprising
a protocol. You use DEFGENERIC to define a generic function for each
operation; the resulting set of generic functions embodies the logical
protocol. Then given classes for which those operations apply,
you use DEFMETHOD to provide implementations. Note that CLOS methods
belong to generic functions, not to classes.

There is no construct in CLOS that corresponds to the Java interface
syntax. The concept of a protocol is something you would describe in
documentation, but it is not manifested as any Lisp object that you
can manipulate.

-- 
Jack Unrue
From: Rahul Jain
Subject: Re: Ensuring a method exists
Date: 
Message-ID: <878xjx44yv.fsf@nyct.net>
Jack Unrue <·······@example.tld> writes:

> There is no construct in CLOS that corresponds to the Java interface
> syntax. The concept of a protocol is something you would describe in
> documentation, but it is not manifested as any Lisp object that you
> can manipulate.

As of 2.5 years ago, you can create objects of class
RJAIN.PROTOCOLS:PROTOCOL that represent this concept. :)

-- 
Rahul Jain
·····@nyct.net
Professional Software Developer, Amateur Quantum Mechanicist
From: Pascal Costanza
Subject: Re: Ensuring a method exists
Date: 
Message-ID: <4o19ahFcbl10U1@individual.net>
Javier wrote:
> Going on with this matter, and because I don't fully understand all the
> answers you have done:
> 
> How would you implement an interface using CLOS with lots of different
> methods? For example:
> 
> interface Collection {
>   void add (Object o);
>   void remove (Object o);
>   ...
> }
> Tipically, your are going to implement lot of methods, say for example
> 10 or more.
> 
> The main reason for having an interface is that you are going to
> provide classes based on it, and let the door open for the user to
> implement new ones. So, if it doesn't make sense to implement them on
> CLOS because Lisp resolves this problem in a different way, how is that
> way? I mean, how is resolving Lisp this problem? Or, if CLOS doesn't
> have this problem, why it doesn't?

In Java, interfaces are only necessary to make the static type system 
happy. When different classes offer similar functionality and you want 
to use their instances in the same place, they have to have the same 
type. So either, they are derived from the same common superclass, one 
is derived from the other, or they implement the same interface. 
Interface types are more flexible than class types because the former 
are not restricted to single inheritance. If Java classes would support 
multiple inheritance, interfaces would not be necessary, but abstract 
classes would be sufficient (like in C++).

Since Common Lisp is dynamically typed, you don't have to worry about 
all these things. When different classes offer functionality and you 
want to use their instances in the same place, you ... just use them.


Pascal

-- 
My website: http://p-cos.net
Common Lisp Document Repository: http://cdr.eurolisp.org
Closer to MOP & ContextL: http://common-lisp.net/project/closer/
From: Javier
Subject: Re: Ensuring a method exists
Date: 
Message-ID: <1159446254.268705.10670@k70g2000cwa.googlegroups.com>
Pascal Costanza ha escrito:

> In Java, interfaces are only necessary to make the static type system
> happy. When different classes offer similar functionality and you want
> to use their instances in the same place, they have to have the same
> type. So either, they are derived from the same common superclass, one
> is derived from the other, or they implement the same interface.
> Interface types are more flexible than class types because the former
> are not restricted to single inheritance. If Java classes would support
> multiple inheritance, interfaces would not be necessary, but abstract
> classes would be sufficient (like in C++).
>
> Since Common Lisp is dynamically typed, you don't have to worry about
> all these things. When different classes offer functionality and you
> want to use their instances in the same place, you ... just use them.

Thanks Pascal. Let see if I understand it, I'll give up you an example:

For example you develop a sound application, like Cubase. Cubase uses
VST, which is an especification of abstract classes in C++. Basically,
the devolper enforces you to write a series of methods to ensure that
your plugin will work correctly in the entire system. A similar issue
happens with Java Sound.
What I don't understand from your answer is that interfaces (and
abstract classes) are something that only strongly typed languages
need. I understand that an interface is a void framework of methods
primaly, independetly of the data type of their methods or fields. How
would a CLOS programmer would enforce other users to develop plugins
for their application without an abstract class or interface? (just
asking).
From: Javier
Subject: Re: Ensuring a method exists
Date: 
Message-ID: <1159446533.273786.279490@d34g2000cwd.googlegroups.com>
Pascal Costanza ha escrito:

> In Java, interfaces are only necessary to make the static type system
> happy. When different classes offer similar functionality and you want
> to use their instances in the same place, they have to have the same
> type. So either, they are derived from the same common superclass, one
> is derived from the other, or they implement the same interface.
> Interface types are more flexible than class types because the former
> are not restricted to single inheritance. If Java classes would support
> multiple inheritance, interfaces would not be necessary, but abstract
> classes would be sufficient (like in C++).
>
> Since Common Lisp is dynamically typed, you don't have to worry about
> all these things. When different classes offer functionality and you
> want to use their instances in the same place, you ... just use them.

Thanks Pascal. Let see if I understand it, I'll give up you an example:

For example you develop a sound application, like Cubase. Cubase uses
VST, which is an especification of abstract classes in C++. Basically,
the devolper enforces you to write a series of methods to ensure that
your plugin will work correctly in the entire system. A similar issue
happens with Java Sound.
What I don't understand from your answer is that interfaces (and
abstract classes) are something that only strongly typed languages
need. I understand that an interface is a void framework of methods
primaly, independetly of the data type of their methods or fields. How
would a CLOS programmer would enforce other users to develop plugins
for their application without an abstract class or interface? (just
asking).
From: Pascal Costanza
Subject: Re: Ensuring a method exists
Date: 
Message-ID: <4o1uu5Fcjv7vU1@individual.net>
Javier wrote:
> Pascal Costanza ha escrito:
> 
>> In Java, interfaces are only necessary to make the static type system
>> happy. When different classes offer similar functionality and you want
>> to use their instances in the same place, they have to have the same
>> type. So either, they are derived from the same common superclass, one
>> is derived from the other, or they implement the same interface.
>> Interface types are more flexible than class types because the former
>> are not restricted to single inheritance. If Java classes would support
>> multiple inheritance, interfaces would not be necessary, but abstract
>> classes would be sufficient (like in C++).
>>
>> Since Common Lisp is dynamically typed, you don't have to worry about
>> all these things. When different classes offer functionality and you
>> want to use their instances in the same place, you ... just use them.
> 
> Thanks Pascal. Let see if I understand it, I'll give up you an example:
> 
> For example you develop a sound application, like Cubase. Cubase uses
> VST, which is an especification of abstract classes in C++. Basically,
> the devolper enforces you to write a series of methods to ensure that
> your plugin will work correctly in the entire system. A similar issue
> happens with Java Sound.
> What I don't understand from your answer is that interfaces (and
> abstract classes) are something that only strongly typed languages
> need. I understand that an interface is a void framework of methods
> primaly, independetly of the data type of their methods or fields. How
> would a CLOS programmer would enforce other users to develop plugins
> for their application without an abstract class or interface? (just
> asking).

The equivalent of defining interfaces, making them public and asking 
client software to implement them is to define generic functions, making 
them public and asking client software to implement them. So, for 
example, you can define a generic function like this:

(defgeneric add (collection object))
(defgeneric rem (collection object))

You can even define default behavior alongside:

(defgeneric add (collection object)
   (:method ((collection list) object)
    (cons object collection)))

(defgeneric rem (collection object)
   (:method ((collection list) object)
    (remove object collection)))

There are some examples in the HyperSpec and in the CLOS MOP 
specification. For example, print-object, initialize-instance, 
slot-unbound, slot-missing, and so on, are generic functions that are 
primarily there for users to define methods on, not for calling them.

What you don't have in CLOS is that you can force client software to 
explicitly implement methods. It's left up to the responsibility of the 
programmer to define the right methods, or to leave them out when they 
are actually not necessary.

It's important to note that static typing doesn't really help you a lot, 
either. One of the pro-static-typing arguments is that it require 
programmers to at least think about their design and provide empty 
methods in case they are not really needed, making that design decision 
an explicit one. But for example in Java, such a method can still throw 
an OperationNotSupportedException, divide by zero, or do other silly 
things. "Modern" development environments like Eclipse even fill in such 
methods automatically for you - go figure.

So to summarize, a CLOS programmer mainly uses documentation to 
advertise what a client program has to do to fulfill the needs of a 
framework.


Pascal

-- 
My website: http://p-cos.net
Common Lisp Document Repository: http://cdr.eurolisp.org
Closer to MOP & ContextL: http://common-lisp.net/project/closer/
From: Javier
Subject: Re: Ensuring a method exists
Date: 
Message-ID: <1159467004.884693.47890@m73g2000cwd.googlegroups.com>
Pascal Costanza ha escrito:

> [...]
> What you don't have in CLOS is that you can force client software to
> explicitly implement methods. It's left up to the responsibility of the
> programmer to define the right methods, or to leave them out when they
> are actually not necessary.

I understand. Thanks.

> It's important to note that static typing doesn't really help you a lot,
> either. One of the pro-static-typing arguments is that it require
> programmers to at least think about their design and provide empty
> methods in case they are not really needed, making that design decision
> an explicit one. But for example in Java, such a method can still throw
> an OperationNotSupportedException, divide by zero, or do other silly
> things. "Modern" development environments like Eclipse even fill in such
> methods automatically for you - go figure.

Yes, I'm used to.

> So to summarize, a CLOS programmer mainly uses documentation to
> advertise what a client program has to do to fulfill the needs of a
> framework.

Or you can use more sophisticated MOP algorithms.

I understand that this is in this way because generic functions do not
belong to classes. That's why they invented :after and :before, it is
the only way to simulate virtual functions in some way.
From: Pascal Costanza
Subject: Re: Ensuring a method exists
Date: 
Message-ID: <4o33p7Fcr3e6U2@individual.net>
Javier wrote:

>> So to summarize, a CLOS programmer mainly uses documentation to
>> advertise what a client program has to do to fulfill the needs of a
>> framework.
> 
> Or you can use more sophisticated MOP algorithms.

Hm, maybe. But that shouldn't be necessary in the general case.

> I understand that this is in this way because generic functions do not
> belong to classes. That's why they invented :after and :before, it is
> the only way to simulate virtual functions in some way.

No, that's incorrect. Even without :before, :after, :around, etc., you 
would have 'virtual' functions. The essence of generic functions is that 
they can do dynamic / virtual dispatch on its arguments (not just one 
implicit one like in most other object-oriented languages). For example, 
Dylan doesn't have :before, :after, :around and is still an 
object-oriented language in the CLOS sense.


Pascal

-- 
My website: http://p-cos.net
Common Lisp Document Repository: http://cdr.eurolisp.org
Closer to MOP & ContextL: http://common-lisp.net/project/closer/
From: Ken Tilton
Subject: Re: [CLOS] Ensuring a method exists
Date: 
Message-ID: <auCSg.7$Z63.3@newsfe12.lga>
Pascal Costanza wrote:
> Ken Tilton wrote:
> 
>> Pascal Costanza wrote:
>>
>>> Ken Tilton wrote:
>>>
>>>> Now maybe that is what is going on and the OP is  just leveraging 
>>>> CLOS as a convenient internal tool to the larger API, but then that 
>>>> is why I suggest going /further/ and hide the CLOS behind some 
>>>> macrology, at which point the OP can enforce anything they want 
>>>> really really easily (instead of staring at AMOP looking for support 
>>>> for something not really OO-able).
>>>
>>>
>>>
>>> Both macros and the CLOS MOP are means to do metaprogramming. The 
>>> distinction is that macros can be used for compile-time processing of 
>>> code [1]
>>
>>
>> ??? Hunh? I never use macros for compile-time pro... OK, once.
> 
> 
> You _always_ use macros for compile-time processing of code.

Gee, that explains the runtime errors I get when I try to call macros 
then. <sigh>

I think this may be a non-native speaker thing. "use-for" does not mean 
what you think it means ("use-at"). I use macros for (to achieve) new 
syntax and to hide implementation.

kt

-- 
Cells: http://common-lisp.net/project/cells/

"I'll say I'm losing my grip, and it feels terrific."
    -- Smiling husband to scowling wife, New Yorker cartoon
From: Pascal Costanza
Subject: Re: [CLOS] Ensuring a method exists
Date: 
Message-ID: <4o18m9Fcj02bU1@individual.net>
Ken Tilton wrote:
> 
> 
> Pascal Costanza wrote:
>> Ken Tilton wrote:
>>
>>> Pascal Costanza wrote:
>>>
>>>> Ken Tilton wrote:
>>>>
>>>>> Now maybe that is what is going on and the OP is  just leveraging 
>>>>> CLOS as a convenient internal tool to the larger API, but then that 
>>>>> is why I suggest going /further/ and hide the CLOS behind some 
>>>>> macrology, at which point the OP can enforce anything they want 
>>>>> really really easily (instead of staring at AMOP looking for 
>>>>> support for something not really OO-able).
>>>>
>>>>
>>>>
>>>> Both macros and the CLOS MOP are means to do metaprogramming. The 
>>>> distinction is that macros can be used for compile-time processing 
>>>> of code [1]
>>>
>>>
>>> ??? Hunh? I never use macros for compile-time pro... OK, once.
>>
>>
>> You _always_ use macros for compile-time processing of code.
> 
> Gee, that explains the runtime errors I get when I try to call macros 
> then. <sigh>
> 
> I think this may be a non-native speaker thing. "use-for" does not mean 
> what you think it means ("use-at"). I use macros for (to achieve) new 
> syntax and to hide implementation.

Maybe. What I was trying to get at was that macros work at compile time 
and the CLOS MOP can be more convenient when meta-level stuff is 
required at run time.


Pascal

-- 
My website: http://p-cos.net
Common Lisp Document Repository: http://cdr.eurolisp.org
Closer to MOP & ContextL: http://common-lisp.net/project/closer/
From: Simon Katz
Subject: Re: [CLOS] Ensuring a method exists
Date: 
Message-ID: <blbnh25v3knue58ikinnpbnieiam5q3n35@4ax.com>
On Thu, 28 Sep 2006 08:34:01 +0200, Pascal Costanza <··@p-cos.net>
wrote:

>Ken Tilton wrote:
>> 
>> 
>> Pascal Costanza wrote:
>>> Ken Tilton wrote:
>>>
>>>> Pascal Costanza wrote:

>>>>> Both macros and the CLOS MOP are means to do metaprogramming. The 
>>>>> distinction is that macros can be used for compile-time processing 
>>>>> of code [1]
>>>>
>>>>
>>>> ??? Hunh? I never use macros for compile-time pro... OK, once.
>>>
>>>
>>> You _always_ use macros for compile-time processing of code.
>> 
>> Gee, that explains the runtime errors I get when I try to call macros 
>> then. <sigh>
>> 
>> I think this may be a non-native speaker thing. "use-for" does not mean 
>> what you think it means ("use-at"). I use macros for (to achieve) new 
>> syntax and to hide implementation.
>
>Maybe. What I was trying to get at was that macros work at compile time 
>and the CLOS MOP can be more convenient when meta-level stuff is 
>required at run time.
>
>
>Pascal

FWIW, that was clear to this particular native speaker of English.
I think it would be clear to most.

Simon

___________________
Real email address:
(substitute ··@ #\+ (substitute #\s #\! "u!enet001+nomi!tech.com"))
From: Ken Tilton
Subject: Re: [CLOS] Ensuring a method exists
Date: 
Message-ID: <EXPSg.8$I45.4@newsfe10.lga>
Simon Katz wrote:
> On Thu, 28 Sep 2006 08:34:01 +0200, Pascal Costanza <··@p-cos.net>
> wrote:
> 
> 
>>Ken Tilton wrote:
>>
>>>
>>>Pascal Costanza wrote:
>>>
>>>>Ken Tilton wrote:
>>>>
>>>>
>>>>>Pascal Costanza wrote:
> 
> 
>>>>>>Both macros and the CLOS MOP are means to do metaprogramming. The 
>>>>>>distinction is that macros can be used for compile-time processing 
>>>>>>of code [1]
>>>>>
>>>>>
>>>>>??? Hunh? I never use macros for compile-time pro... OK, once.
>>>>
>>>>
>>>>You _always_ use macros for compile-time processing of code.
>>>
>>>Gee, that explains the runtime errors I get when I try to call macros 
>>>then. <sigh>
>>>
>>>I think this may be a non-native speaker thing. "use-for" does not mean 
>>>what you think it means ("use-at"). I use macros for (to achieve) new 
>>>syntax and to hide implementation.
>>
>>Maybe. What I was trying to get at was that macros work at compile time 

No sh*t, Einstein. Too bad that is not what you said (nice try, tho):

     >>>>You _always_ use macros for compile-time processing of code.

Offered in contradiction to my:

    >>>>>??? Hunh? I never use macros for compile-time pro... OK, once.

The once is ix-layer-expand, which takes keywords from a shorthand DSL 
for building up Cello panes from so many "layers" and generates code to 
be eval'ed at runtime and expands them into a lambda form. I guess like 
cl-who, tho my data arguments in the DSL evaluate at runtime.

This is OpenGL code which wants to be fast for (in order to get!) decent 
frame rates. The expansion of my mini-layering DSL into OpenGL calls can 
be done at compile time, so (read my lips, will ya?) /in this one case/ 
I use macros /for/ compile-time processing (interpretation of the DSL) 
instead of the usual purposes of  syntax transformation and/or 
implementation-hiding.

>>and the CLOS MOP can be more convenient when meta-level stuff is 
>>required at run time.

<thump> <thump> Is this thing on?

> FWIW, that was clear to this particular native speaker of English.

I wouldn't go around bragging about that.

Ken: "Cute puppy. Did you get it for companionship or to pick up chicks?"
Simon: "Hunh? My puppy /always/ gives me companionship."

hth, ken

-- 
Cells: http://common-lisp.net/project/cells/

"I'll say I'm losing my grip, and it feels terrific."
    -- Smiling husband to scowling wife, New Yorker cartoon
From: Pascal Costanza
Subject: Re: [CLOS] Ensuring a method exists
Date: 
Message-ID: <4o33jeFcr3e6U1@individual.net>
Ken Tilton wrote:
> 
> 
> Simon Katz wrote:
>> On Thu, 28 Sep 2006 08:34:01 +0200, Pascal Costanza <··@p-cos.net>
>> wrote:
>>
>>
>>> Ken Tilton wrote:
>>>
>>>>
>>>> Pascal Costanza wrote:
>>>>
>>>>> Ken Tilton wrote:
>>>>>
>>>>>
>>>>>> Pascal Costanza wrote:
>>
>>
>>>>>>> Both macros and the CLOS MOP are means to do metaprogramming. The 
>>>>>>> distinction is that macros can be used for compile-time 
>>>>>>> processing of code [1]
>>>>>>
>>>>>>
>>>>>> ??? Hunh? I never use macros for compile-time pro... OK, once.
>>>>>
>>>>>
>>>>> You _always_ use macros for compile-time processing of code.
>>>>
>>>> Gee, that explains the runtime errors I get when I try to call 
>>>> macros then. <sigh>
>>>>
>>>> I think this may be a non-native speaker thing. "use-for" does not 
>>>> mean what you think it means ("use-at"). I use macros for (to 
>>>> achieve) new syntax and to hide implementation.
>>>
>>> Maybe. What I was trying to get at was that macros work at compile time 
> 
> No sh*t, Einstein. Too bad that is not what you said (nice try, tho):
> 
>     >>>>You _always_ use macros for compile-time processing of code.
> 
> Offered in contradiction to my:
> 
>    >>>>>??? Hunh? I never use macros for compile-time pro... OK, once.

...which was a response to my:

 >>>>>>
Both macros and the CLOS MOP are means to do metaprogramming. The 
distinction is that macros can be used for compile-time processing of 
code [1], while the CLOS MOP is useful for meta-programs that require 
special actions at runtime.
<<<<<<

Seems to me that you changed the topic, not me. Now what?

> The once is ix-layer-expand, which takes keywords from a shorthand DSL 
> for building up Cello panes from so many "layers" and generates code to 
> be eval'ed at runtime and expands them into a lambda form. I guess like 
> cl-who, tho my data arguments in the DSL evaluate at runtime.
> 
> This is OpenGL code which wants to be fast for (in order to get!) decent 
> frame rates. The expansion of my mini-layering DSL into OpenGL calls can 
> be done at compile time, so (read my lips, will ya?) /in this one case/ 
> I use macros /for/ compile-time processing (interpretation of the DSL) 
> instead of the usual purposes of  syntax transformation and/or 
> implementation-hiding.

You seem to have a limited notion of what "compile-time processing of 
code" can mean. Syntax transformation _is_ compile-time processing of code.


Pascal

-- 
My website: http://p-cos.net
Common Lisp Document Repository: http://cdr.eurolisp.org
Closer to MOP & ContextL: http://common-lisp.net/project/closer/
From: Didier Verna
Subject: Re: [CLOS] Ensuring a method exists
Date: 
Message-ID: <mux1wpxbhnj.fsf@uzeb.lrde.epita.fr>
Ken Tilton <·········@gmail.com> wrote:

> How portable does it have to be ?

        Don't care right now.

> If not, maybe your Lisp has something like ACL's:
>
> (method-specializers
>    (find-method #'make-style-font nil
>        (list (find-class 'gui-style-ftgl))))
>
> -> (#<STANDARD-CLASS GUI-STYLE-FTGL>)

        Sounds like this is along the lines of Christophe's message. I'll look
into it. thanks.


> Of course the big question no one will ask is why you want to do this. 

        It was after a discussion with a friend about the problems of binary
methods in traditional objects systems. I was playing with the idea and trying
to see how those problems could be solved with CLOS.


> Sounds like bad design.

        Why ? If you're implicitely referring to your "macrology" stuff (or
Lars'suggestion which sounds identical AFAIUI), I'm not sure this is a better
idea. Yes, you can provide a macro that would define the class AND the
required method and ask people to use it. But this may render the code less
readable, and users are not forced to use your macro.

Please note that I don't have a strong opinion on this, actually. What
motivated my question was originally to compare support for binary methods in
Lisp and C++ (my friend is a C++ user). In this aim, it *is* interesting to
see what the language itself can do for you (here: checking that all required
methods are defined, rather than only documenting this and hoping that the
programmer won't forget to write one of them).


> But you are not alone, we get people wanting to do this almost as often as
> we get people trying to fix the parens.

        I have no problem with parens :-)

-- 
Check out my new jazz CD on http://www.didierverna.com/ !

Didier Verna	EPITA / LRDE, 14-16 rue Voltaire   Tel.+33 (1) 44 08 01 85
             	94276 Le Kremlin-Bic�tre, France   Fax.+33 (1) 53 14 59 22
From: Ken Tilton
Subject: Re: [CLOS] Ensuring a method exists
Date: 
Message-ID: <IRxSg.14$bJ7.0@newsfe08.lga>
Didier Verna wrote:
> Ken Tilton <·········@gmail.com> wrote:
> 
> 
>>How portable does it have to be ?
> 
> 
>         Don't care right now.
> 
> 
>>If not, maybe your Lisp has something like ACL's:
>>
>>(method-specializers
>>   (find-method #'make-style-font nil
>>       (list (find-class 'gui-style-ftgl))))
>>
>>-> (#<STANDARD-CLASS GUI-STYLE-FTGL>)
> 
> 
>         Sounds like this is along the lines of Christophe's message. I'll look
> into it. thanks.
> 
> 
> 
>>Of course the big question no one will ask is why you want to do this. 
> 
> 
>         It was after a discussion with a friend about the problems of binary
> methods in traditional objects systems. I was playing with the idea and trying
> to see how those problems could be solved with CLOS.

http://lucacardelli.name/Papers/Binary.A4.ps

I see. They discuss CLOS at length and concede it eliminates the 
problem, then whine about encapsulation and runtime efficiency. :) Then 
(in the next section which I did not read) they come up with a solution 
they advertise as the best of C++ and multi-methods. anyway...

> 
> 
> 
>>Sounds like bad design.
> 
> 
>         Why ?

First Principles. As I said, if a method is provided for superX, then 
one has been provided for X. A premise of your question is that that is 
not the case. Of course then I did not know you did not even have a use 
case and were just having fun seeing if CL could do stupid C++ tricks.

> If you're implicitely referring to your "macrology" stuff (or
> Lars'suggestion which sounds identical AFAIUI), I'm not sure this is a better
> idea.

If you had had a use case in which some problem could have been solved 
by pretending a method for superX did not apply to X, then I think the 
best thing to do is go the whole nine yards and /really/ establish a 
distinct layer (DSL some like to say), cuz then you can (as I said) do 
what you want any way you want, CLOS specifics be damned.

> Yes, you can provide a macro that would define the class AND the
> required method and ask people to use it. But this may render the code less
> readable, ...

No, on the contrary. Suppose you come with a new required...

(defmacro DEFCOMPARATOR(<class> (&rest args...) &body body)...

...thingy. It automatically supplies the binary method, helping your 
user out and really taking them to a higher level of abstraction. 
Happens also to hide implementation details in case that changes.

>>...and users are not forced to use your macro.

Oh, we have our ways. :) (Yes, we can enforce it. Once we bite the 
bullet and take an emerging DSL seriously, we can do anything we want.)


> 
> Please note that I don't have a strong opinion on this, actually. What
> motivated my question was originally to compare support for binary methods in
> Lisp and C++ (my friend is a C++ user). In this aim, it *is* interesting to
> see what the language itself can do for you (here: checking that all required
> methods are defined, rather than only documenting this and hoping that the
> programmer won't forget to write one of them).

Oh, then you can just murder the ball* with MOP.

kt

* hit a baseball really hard. Maybe other balls, too. Tennis, golf...not 
a basketball, I should think. k

-- 
Cells: http://common-lisp.net/project/cells/

"I'll say I'm losing my grip, and it feels terrific."
    -- Smiling husband to scowling wife, New Yorker cartoon
From: jayessay
Subject: Re: [CLOS] Ensuring a method exists
Date: 
Message-ID: <m3psdhxkff.fsf@rigel.goldenthreadtech.com>
Didier Verna <······@lrde.epita.fr> writes:

> Ken Tilton <·········@gmail.com> wrote:
> > Sounds like bad design.
> 
>         Why ? If you're implicitely referring to your "macrology"
> stuff (or Lars'suggestion which sounds identical AFAIUI), I'm not
> sure this is a better idea. Yes, you can provide a macro that would
> define the class AND the required method and ask people to use
> it. But this may render the code less readable, and users are not
> forced to use your macro.

I think you need to reassess your views here.  The "macrology" stuff
can make your intentions exactly clear in that the construct the user
is expected to utilize does exactly what you want it to.  So, it
actually makes the code _more_ readable because you don't have to
decipher an _idiom_ (aka pattern).  And, further, if you are concerned
that users won't use it (why??), you can "force" them to by simply
shadowing defclass.  Then they would have to actively work to
circumvent your desires: 1. use cl:defclass, 2. Write their own
"defclass" or some such.


> Please note that I don't have a strong opinion on this,
> actually. What motivated my question was originally to compare
> support for binary methods in Lisp and C++ (my friend is a C++
> user). In this aim, it *is* interesting to see what the language
> itself can do for you (here: checking that all required methods are
> defined, rather than only documenting this and hoping that the
> programmer won't forget to write one of them).

By "the language itself", you must include the potential of macros
here to achieve the goal.  You shouldn't get misled into thinking that
since this appears to be "oo focused" that only the object
system/model of the language should be brought to bear to achieve your
goal.  As is often pointed out, CLOS itself is mostly "just macrology"
over a base protocol.


/Jon

-- 
'j' - a n t h o n y at romeo/charley/november com
From: Pascal Costanza
Subject: Re: [CLOS] Ensuring a method exists
Date: 
Message-ID: <4o1899Fc26utU1@individual.net>
Didier Verna wrote:

>         It was after a discussion with a friend about the problems of binary
> methods in traditional objects systems. I was playing with the idea and trying
> to see how those problems could be solved with CLOS.

Taking Wade's recent comment into account, that it is questionable why 
methods for all classes must exist, here is another rule that could be 
more useful: In a binary function, it could be useful to check that 
methods are always specialized on both arguments and always for the same 
classes. This could easily be checked in a method on add-method. Roughly 
like this:

(defclass binary-function (standard-generic-function)
   ()
   (:metaclass funcallable-standard-class))

(defmethod add-method :before
   ((gf binary-function) method)
   (assert (apply #'equal (method-specializers method))))

Any objections why one could want to break this requirement?


Pascal

-- 
My website: http://p-cos.net
Common Lisp Document Repository: http://cdr.eurolisp.org
Closer to MOP & ContextL: http://common-lisp.net/project/closer/
From: Rahul Jain
Subject: Re: [CLOS] Ensuring a method exists
Date: 
Message-ID: <874pul44n7.fsf@nyct.net>
Didier Verna <······@lrde.epita.fr> writes:

>         Why ? If you're implicitely referring to your "macrology" stuff (or
> Lars'suggestion which sounds identical AFAIUI), I'm not sure this is a better
> idea. Yes, you can provide a macro that would define the class AND the
> required method and ask people to use it. But this may render the code less
> readable, and users are not forced to use your macro.

Users are not forced to use the C++ compiler. They can write assembly
directly and link it into their binaries.

> Please note that I don't have a strong opinion on this, actually. What
> motivated my question was originally to compare support for binary methods in
> Lisp and C++ (my friend is a C++ user). In this aim, it *is* interesting to
> see what the language itself can do for you (here: checking that all required
> methods are defined, rather than only documenting this and hoping that the
> programmer won't forget to write one of them).

Don't people write unit tests? Wouldn't you realize when writing the
unit test that it's missing obviously required functionality? "OK, the
next thing I need to write a test for is the insert operation. Um, I
didn't write one. D'oh." Or you realize that the operator is really not
useful in your context... in which case why is it in the interface in
the first place?

-- 
Rahul Jain
·····@nyct.net
Professional Software Developer, Amateur Quantum Mechanicist
From: Didier Verna
Subject: Re: [CLOS] Ensuring a method exists
Date: 
Message-ID: <muxr6xo4kit.fsf@uzeb.lrde.epita.fr>
Rahul Jain <·····@nyct.net> wrote:

>> it *is* interesting to see what the language itself can do for you (here:
>> checking that all required methods are defined, rather than only
>> documenting this and hoping that the programmer won't forget to write one
>> of them).
>
> Don't people write unit tests? 

"It may not work: I have only proven it correct; I have not tested it"
-- Donald Knuth


What makes you think unit tests would suffice ? Consider writing morphological
operators in an image processing library. The results of a bogus
implementation might not even be visible to the human eye. So I'd rather have
the program abort because I forgot one method, rather than having to figure
out that the resulting image "don't look right".


-- 
Check out my new jazz CD on http://www.didierverna.com/ !

Didier Verna	EPITA / LRDE, 14-16 rue Voltaire   Tel.+33 (1) 44 08 01 85
             	94276 Le Kremlin-Bic�tre, France   Fax.+33 (1) 53 14 59 22
From: Rahul Jain
Subject: Re: [CLOS] Ensuring a method exists
Date: 
Message-ID: <87wt7fn9er.fsf@nyct.net>
Didier Verna <······@lrde.epita.fr> writes:

> What makes you think unit tests would suffice ? Consider writing morphological
> operators in an image processing library. The results of a bogus
> implementation might not even be visible to the human eye. So I'd rather have
> the program abort because I forgot one method, rather than having to figure
> out that the resulting image "don't look right".

Thanks for answering my question. It seems that you don't even know what
a unit test is.

A unit test would find that problem.

-- 
Rahul Jain
·····@nyct.net
Professional Software Developer, Amateur Quantum Mechanicist
From: Alan Crowe
Subject: Re: [CLOS] Ensuring a method exists
Date: 
Message-ID: <861wpo5a9x.fsf@cawtech.freeserve.co.uk>
Didier Verna <······@lrde.epita.fr> writes:
>
> "It may not work: I have only proven it correct; I have not tested it"
> -- Donald Knuth
> 
To understand Knuth's point you must first understand the
idea of separation of concerns.

Algorithms may contain subtle logical errors in weird corner
cases. There is little chance of smoking these out with
testing, you need to sit down with paper and pencil and try
proving your algorithm. You need to be strict with yourself
if you want to spot that a case split is not actually
exhaustive, but you often have a better chance of detecting
it by focussed thinking than by testing.

Algorithms may contain typos and bloopers. These are
usually pretty destructive of the functionality and easily
caught by testing. Proof is relatively powerless here, your
proof only applies to what you see, but as any proof reader
knows, you see what is supposed to be there, not what is
actually there. 

Code may contain both subtle logical errors and typos. You
want to catch both. So you have two separate concerns.
Knuth's position is that you need to tackle the two concerns
seperately, using proof against subtle logical errors and
testing against typos.

When he writes "It may not work: I have only proven it
correct; I have not tested it" he is merely warning that he
has left the job half done, breaking off after finishing the
half in which he specialises.

> What makes you think unit tests would suffice ? Consider
> writing morphological operators in an image processing
> library. The results of a bogus implementation might not
> even be visible to the human eye. So I'd rather have the
> program abort because I forgot one method, rather than
> having to figure out that the resulting image "don't look
> right".

You've written your method, but it contains a bug. However
it is not visible on your test patterns, so you don't
notice. That is a hopeless way to write software. If you
didn't test it, it doesn't work.

This is one of the reasons why you are recommended to write
you test cases first, so that you can run them before you
write the code that handles them and check that they
actually fail. For example you have to come up with a test
pattern which shows that the morphological operator hasn't
been run. Then you write the morphological operator. Now if
there is a bug you have a chance of catching it.

I remember writing some numerical code a special way to
avoid cancelation error. I was rather proud of it, because
it passed my tests. Later I grew suspicious and tried out
the naive way of writing the code. It passed too! My test
cases were wrong. I should have validated the test cases by
making sure that they failed on the naive code, ie, that
they actually showed up the cancellation errors that can
take place with naive code.

That strikes me as a fairly general point - your test case
had better be run and be seen to fail before you write the
code it is testing, otherwise you might type in a buggy
version that does nothing and not know until the customer
asks sarcastically "Don't people write unit tests?"

In "Need to pivot"
http://www.hulver.com/scoop/story/2005/3/1/3534/17555 I
recount a tail in which I struggled to come of with test
cases. There is real work needed in constructing test cases
and if you don't do it the quality of your software will be
poor.

Alan Crowe
Edinburgh
Scotland
From: Rahul Jain
Subject: Re: [CLOS] Ensuring a method exists
Date: 
Message-ID: <87sli3n992.fsf@nyct.net>
Alan Crowe <····@cawtech.freeserve.co.uk> writes:

> I remember writing some numerical code a special way to
> avoid cancelation error. I was rather proud of it, because
> it passed my tests. Later I grew suspicious and tried out
> the naive way of writing the code. It passed too! My test
> cases were wrong. I should have validated the test cases by
> making sure that they failed on the naive code, ie, that
> they actually showed up the cancellation errors that can
> take place with naive code.
>
> That strikes me as a fairly general point - your test case
> had better be run and be seen to fail before you write the
> code it is testing, otherwise you might type in a buggy
> version that does nothing and not know until the customer
> asks sarcastically "Don't people write unit tests?"

Very good point.

But that means we need test cases for our test cases. Hmm... ;)

-- 
Rahul Jain
·····@nyct.net
Professional Software Developer, Amateur Quantum Mechanicist
From: Didier Verna
Subject: Re: [CLOS] Ensuring a method exists
Date: 
Message-ID: <muxejtn3eyw.fsf@uzeb.lrde.epita.fr>
Alan Crowe <····@cawtech.freeserve.co.uk> wrote:

>> What makes you think unit tests would suffice ? 

        BTW, Rahul, I know what a unit test is, but indeed, I was just
thinking "test" when I wrote this.

>> Consider writing morphological operators in an image processing library. 
>> The results of a bogus implementation might not even be visible to the
>> human eye. So I'd rather have the program abort because I forgot one
>> method, rather than having to figure out that the resulting image "don't
>> look right".
>
> You've written your method, but it contains a bug. However
> it is not visible on your test patterns, so you don't
> notice. That is a hopeless way to write software. If you
> didn't test it, it doesn't work.

        I agree completely.

But continuing with the image processing example (a real world one in my lab),
I am the developer of it, but I also have users for it. Those users might not
only use the library directly, but also write their own extensions to it by
subclassing. I can't force them to write proper tests, even if they should. So
for instance, if they forget one method, I can tell them that they just get
what they deserve, or I can provide a machinery to ensure the method exists
and thow the information to their face otherwise. I prefer the second option. 
What's wrong with that ?

-- 
Check out my new jazz CD on http://www.didierverna.com/ !

Didier Verna	EPITA / LRDE, 14-16 rue Voltaire   Tel.+33 (1) 44 08 01 85
             	94276 Le Kremlin-Bic�tre, France   Fax.+33 (1) 53 14 59 22
From: Rahul Jain
Subject: Re: [CLOS] Ensuring a method exists
Date: 
Message-ID: <87fye2msy0.fsf@nyct.net>
Didier Verna <······@lrde.epita.fr> writes:

> Alan Crowe <····@cawtech.freeserve.co.uk> wrote:
>
>>> What makes you think unit tests would suffice ? 
>
>         BTW, Rahul, I know what a unit test is, but indeed, I was just
> thinking "test" when I wrote this.

I specifically talked about unit tests for a reason.

> But continuing with the image processing example (a real world one in my lab),
> I am the developer of it, but I also have users for it. Those users might not
> only use the library directly, but also write their own extensions to it by
> subclassing. I can't force them to write proper tests, even if they should.

If they don't test their code, why should they expect it to work at all? 
So what if you've made sure that they write some random code for each
required method in the protocol? That doesn't mean that the methods
actually do what the author intended them to do.

-- 
Rahul Jain
·····@nyct.net
Professional Software Developer, Amateur Quantum Mechanicist
From: Thomas A. Russ
Subject: Re: [CLOS] Ensuring a method exists
Date: 
Message-ID: <ymiirit1kz5.fsf@sevak.isi.edu>
Didier Verna <······@lrde.epita.fr> writes:

> I am the developer of it, but I also have users for it. Those users might not
> only use the library directly, but also write their own extensions to it by
> subclassing. I can't force them to write proper tests, even if they should. So
> for instance, if they forget one method, I can tell them that they just get
> what they deserve, or I can provide a machinery to ensure the method exists
> and thow the information to their face otherwise. I prefer the second option. 
> What's wrong with that ?

Well, this does get to the crux of the philosophical difference between
the C++/Java view of programming style and the (Common) Lisp way.  In
your case, you make the assumption that if the person subclassing your
objects doesn't write a particular specialized method, then they have
"forgotten" it.  The Common Lisp designer assumes that they have weighed
the choices and decided that there was no need for such a specialized
method.

What is somewhat abhorent to the CL mindset is to force programmers to
write methods like

  (defmethod point= ((x mynewpoint) (y mynewpoint))
    (call-next-method))

just to satisfy some mandatory method constraint that really doesn't
apply to the particular case.  I prefer to not have to write such
vacuous methods, and don't like being forced to do it.  What's wrong
with that?

If you want to provide some validation machinery, then the nice CL way
to do it would be to provide some code that will do the analysis of the
classes and methods that exist.  It would be easy to write some such
code, without even needed to resort to the MOP.  It could then be
invoked by the programmer at the appropriate part of the development
cycle and produce a report about what is thought to be "missing".

In any case, such a missing method should be at most a warning, and not
a hard error.  That gives notice while not forcing behavior that annoys
the users of the library.

-- 
Thomas A. Russ,  USC/Information Sciences Institute
From: Pascal Costanza
Subject: Re: [CLOS] Ensuring a method exists
Date: 
Message-ID: <4ovo9lFgm4iaU1@individual.net>
Thomas A. Russ wrote:
> Didier Verna <······@lrde.epita.fr> writes:
> 
>> I am the developer of it, but I also have users for it. Those users might not
>> only use the library directly, but also write their own extensions to it by
>> subclassing. I can't force them to write proper tests, even if they should. So
>> for instance, if they forget one method, I can tell them that they just get
>> what they deserve, or I can provide a machinery to ensure the method exists
>> and thow the information to their face otherwise. I prefer the second option. 
>> What's wrong with that ?
> 
> Well, this does get to the crux of the philosophical difference between
> the C++/Java view of programming style and the (Common) Lisp way.  In
> your case, you make the assumption that if the person subclassing your
> objects doesn't write a particular specialized method, then they have
> "forgotten" it.  The Common Lisp designer assumes that they have weighed
> the choices and decided that there was no need for such a specialized
> method.

There is no distinguished CL way, at least IMHO. The nice thing about CL 
is that you can have things any way you like, including the "fascist" way.

> What is somewhat abhorent to the CL mindset is to force programmers to
> write methods like
> 
>   (defmethod point= ((x mynewpoint) (y mynewpoint))
>     (call-next-method))
> 
> just to satisfy some mandatory method constraint that really doesn't
> apply to the particular case.  I prefer to not have to write such
> vacuous methods, and don't like being forced to do it.  What's wrong
> with that?

I guess Didier assumes that such forwarding methods are the exception 
for the cases he has in mind.

> If you want to provide some validation machinery, then the nice CL way
> to do it would be to provide some code that will do the analysis of the
> classes and methods that exist.  It would be easy to write some such
> code, without even needed to resort to the MOP.  It could then be
> invoked by the programmer at the appropriate part of the development
> cycle and produce a report about what is thought to be "missing".
> 
> In any case, such a missing method should be at most a warning, and not
> a hard error.  That gives notice while not forcing behavior that annoys
> the users of the library.

You can have all these things implemented using the MOP, and I would 
claim that it's better to use the MOP here. According to some settings, 
a MOP solution can decide to skip the test, so that you can have your 
cake at development time and be sure it's eaten when the code is 
deployed. (Actually, it shouldn't be harder than changing the class of 
the respective functions.) Of course, the error raised can be a 
continuable error.


Pascal

-- 
My website: http://p-cos.net
Common Lisp Document Repository: http://cdr.eurolisp.org
Closer to MOP & ContextL: http://common-lisp.net/project/closer/
From: Pascal Bourguignon
Subject: Re: [CLOS] Ensuring a method exists
Date: 
Message-ID: <8764ezskq0.fsf@thalassa.informatimago.com>
Alan Crowe <····@cawtech.freeserve.co.uk> writes:

> I remember writing some numerical code a special way to
> avoid cancelation error. I was rather proud of it, because
> it passed my tests. Later I grew suspicious and tried out
> the naive way of writing the code. It passed too! My test
> cases were wrong. I should have validated the test cases by
> making sure that they failed on the naive code, ie, that
> they actually showed up the cancellation errors that can
> take place with naive code.
>
> That strikes me as a fairly general point - your test case
> had better be run and be seen to fail before you write the
> code it is testing, otherwise you might type in a buggy
> version that does nothing and not know until the customer
> asks sarcastically "Don't people write unit tests?"

Yes, that's what's bothering be with test cases.  You have to first
debug them.  And for this, you need to write buggy code before
writting the code you have to write.  

I prefer to concentrate on generating correct code.

-- 
__Pascal Bourguignon__                     http://www.informatimago.com/

PLEASE NOTE: Some quantum physics theories suggest that when the
consumer is not directly observing this product, it may cease to
exist or will exist only in a vague and undetermined state.
From: Rahul Jain
Subject: Re: [CLOS] Ensuring a method exists
Date: 
Message-ID: <87zmcd2plx.fsf@nyct.net>
Didier Verna <······@lrde.epita.fr> writes:

> Please note that I don't have a strong opinion on this, actually. What
> motivated my question was originally to compare support for binary methods in
> Lisp and C++ (my friend is a C++ user). In this aim, it *is* interesting to
> see what the language itself can do for you (here: checking that all required
> methods are defined, rather than only documenting this and hoping that the
> programmer won't forget to write one of them).

Thinking about this further, where have you ever come up with a case
where you have a function that is REALLY binary? All of the overloadable
operators in C++ are not binary operators, they're simply associative. 
Although there's a defined association order for them, which is bogus. 
Hmm, I guess except for the shifiting operators, but those are only used
for visual gimmicks that need to be compensated for later with a bunch
of wrapper functions that allow you to actually specify the format of
the output, destroying the initial advantage of succintness and clear
structure.

If you want a math library for ring theory, use Weyl (part of the Simlab
application). This allows you to deal with stuff like commutativity and
associativity properly.

-- 
Rahul Jain
·····@nyct.net
Professional Software Developer, Amateur Quantum Mechanicist
From: Barry Fishman
Subject: Re: [CLOS] Ensuring a method exists
Date: 
Message-ID: <m3bqoqbzli.fsf@bfishman.alum.rpi.edu>
Didier Verna <······@lrde.epita.fr> writes:

> Ken Tilton <·········@gmail.com> wrote:
>> Sounds like bad design.
>
> ...
>
> Please note that I don't have a strong opinion on this, actually. What
> motivated my question was originally to compare support for binary methods in
> Lisp and C++ (my friend is a C++ user). In this aim, it *is* interesting to
> see what the language itself can do for you (here: checking that all required
> methods are defined, rather than only documenting this and hoping that the
> programmer won't forget to write one of them).

It would be nice to see an example of where you think this really is
needed as part of a real design rather that just a language feature.
The point color-point example does not seem to me to be such a case.

First deriving color-point from point seems to be wrong if color-point
isn't a type of (geometric?) point.  I would think you would be better
off using a (virtual) point base class which contains any common
structure, and can be used for shared (sub-type independent) methods.
That way, when you define geometric point methods, you don't need to
worry about their relevance to other types of points.

(defclass point ()
  ((x :initarg :x :accessor point-x)
   (y :initarg :y :accessor point-y)
   (z :initarg :z :accessor point-z)))

(defclass geo-point (point) ())
(defclass color-point (point) ())

Now if geo-point and color-point equality are separate, one should
define them separately.  In common lisp, they can share method names
without having them be defined on the point class.  If the code is the
same you could use a (possible inline) function that operates on
points.

However, if you think something like point-equal is a common concept
with the additional constraint that equal points must be of the same
type, then do just that:

(defmethod point-equal ((a point) (b point))
  (and (eql (class-of a) (class-of b))
       (= (point-x a) (point-x b))
       (= (point-y a) (point-y b))
       (= (point-z a) (point-z b))))

-- 
Barry Fishman
From: Lars Rune Nøstdal
Subject: Re: [CLOS] Ensuring a method exists
Date: 
Message-ID: <pan.2006.09.27.09.40.19.18043@gmail.com>
On Wed, 27 Sep 2006 11:17:57 +0200, Didier Verna wrote:

> Lars Rune Nøstdal <···········@gmail.com> wrote:
> 
>> This seems to work:
>>
>> (defclass SomeBase ()
>>   ())
>>
>>
>> (defmethod initialize-instance :before ((some-base SomeBase) &key)
>>   (format t "Checking for `foo': ~A~%"
>>           (find-method #'foo '() (mapcar #'find-class
>>                                          (list (type-of some-base)
>>                                                (type-of some-base))))))
>>
>>
>> (defmethod foo ((a SomeBase) (b SomeBase))
>>   (write-line "(foo SomeBase SomeBase)"))
>>
>>
>> (defclass SomeDerived (SomeBase)
>>   ())
> 
> 
>         That's a nice solution but it has one caveat (my question was probably
> not clear enough about this): your trick checks for the existence of a method
> only for the class you instantiate, and not for the subclasses.

Hm, ok - maybe something like this:

(defmethod initialize-instance :before ((some-base SomeBase) &key)
  (labels ((checkHierarchy (class)
             (format t "About to check `~A' for method #'foo~%" class)
             (find-method #'foo '()
                          (mapcar #'find-class
                                  (list class class)))
             (dolist (class (sb-mop:class-direct-subclasses (find-class class)))
               (checkHierarchy (class-name class)))))
    (checkHierarchy (type-of some-base))))

Note that `sb-mop' isn't portable .. just figure out in which package
`class-direct-subclasses' is in your implementation and change
accordingly, or use a compatibility-layer like
http://common-lisp.net/project/closer/closer-mop.html

-- 
Lars Rune Nøstdal
http://lars.nostdal.org/
From: Didier Verna
Subject: Re: [CLOS] Ensuring a method exists
Date: 
Message-ID: <muxu02tbjat.fsf@uzeb.lrde.epita.fr>
Lars Rune N�stdal <···········@gmail.com> wrote:

> Hm, ok - maybe something like this:
>
>   (dolist (class (sb-mop:class-direct-subclasses (find-class class)))

        Yup, that's the kind of thing I was looking for, thanks. Actually,
I'll use class-direct-SUPERclasses to go up the hierarchy, and also filter out
(find-class 'standard-object) from the check list. But that's the idea.


-- 
Check out my new jazz CD on http://www.didierverna.com/ !

Didier Verna	EPITA / LRDE, 14-16 rue Voltaire   Tel.+33 (1) 44 08 01 85
             	94276 Le Kremlin-Bic�tre, France   Fax.+33 (1) 53 14 59 22
From: Lars Rune Nøstdal
Subject: Re: [CLOS] Ensuring a method exists
Date: 
Message-ID: <pan.2006.09.27.13.04.59.541710@gmail.com>
On Wed, 27 Sep 2006 14:11:54 +0200, Didier Verna wrote:

> Lars Rune Nøstdal <···········@gmail.com> wrote:
> 
>> Hm, ok - maybe something like this:
>>
>>   (dolist (class (sb-mop:class-direct-subclasses (find-class class)))
> 
>         Yup, that's the kind of thing I was looking for, thanks. Actually,
> I'll use class-direct-SUPERclasses to go up the hierarchy, and also filter out
> (find-class 'standard-object) from the check list. But that's the idea.

When moving upwards while only looking upwards you'll miss the branches
passing along "beside" you as you head for the top .. I think you'll
figure this stuff out however .. :)

-- 
Lars Rune Nøstdal
http://lars.nostdal.org/
From: Didier Verna
Subject: Re: [CLOS] Ensuring a method exists
Date: 
Message-ID: <mux7izpa1dx.fsf@uzeb.lrde.epita.fr>
Lars Rune N�stdal <···········@gmail.com> wrote:

> When moving upwards while only looking upwards you'll miss the branches
> passing along "beside" you as you head for the top .. I think you'll figure
> this stuff out however .. :)

        :-) I was just simplifying for my own testcase ...

-- 
Check out my new jazz CD on http://www.didierverna.com/ !

Didier Verna	EPITA / LRDE, 14-16 rue Voltaire   Tel.+33 (1) 44 08 01 85
             	94276 Le Kremlin-Bic�tre, France   Fax.+33 (1) 53 14 59 22
From: Pascal Costanza
Subject: Re: [CLOS] Ensuring a method exists
Date: 
Message-ID: <4nvuk9Fc66srU3@individual.net>
Didier Verna wrote:
> Lars Rune N�stdal <···········@gmail.com> wrote:
> 
>> Hm, ok - maybe something like this:
>>
>>   (dolist (class (sb-mop:class-direct-subclasses (find-class class)))
> 
>         Yup, that's the kind of thing I was looking for, thanks. Actually,
> I'll use class-direct-SUPERclasses to go up the hierarchy, and also filter out
> (find-class 'standard-object) from the check list. But that's the idea.

If you really need the list of all direct and indirect superclasses, you 
can simply call class-precedence-list. (This may only work when the 
class is already finalized, that is, roughly when an instance of that 
class already exists.)


Pascal

-- 
My website: http://p-cos.net
Common Lisp Document Repository: http://cdr.eurolisp.org
Closer to MOP & ContextL: http://common-lisp.net/project/closer/
From: Didier Verna
Subject: Re: [CLOS] Ensuring a method exists
Date: 
Message-ID: <mux64f980x8.fsf@uzeb.lrde.epita.fr>
Pascal Costanza wrote:

> If you really need the list of all direct and indirect superclasses, you can
> simply call class-precedence-list. (This may only work when the class is
> already finalized, that is, roughly when an instance of that class already
> exists.)

        Thanks.

-- 
Check out my new jazz CD on http://www.didierverna.com/ !

Didier Verna	EPITA / LRDE, 14-16 rue Voltaire   Tel.+33 (1) 44 08 01 85
             	94276 Le Kremlin-Bic�tre, France   Fax.+33 (1) 53 14 59 22
From: Lars Rune Nøstdal
Subject: Re: [CLOS] Ensuring a method exists
Date: 
Message-ID: <pan.2006.09.27.09.49.49.385185@gmail.com>
On Wed, 27 Sep 2006 11:17:57 +0200, Didier Verna wrote:
>
> So imagine having A <- B and creating only instances of B. The lack of method
> for class A would go unnoticed. But I want the check for the whole hierarchy
> (consider for instance that I'm using the AND method combination type and I'm
> expecting an implementation for all the classes).

Oh, the one I just posted only checks downwards from the instantiated - I
guess you could walk from the base at the very top each time.

Just change the last line in `initialize-instance', like this I think:

    (checkHierarchy 'SomeBase)))

-- 
Lars Rune Nøstdal
http://lars.nostdal.org/
From: Lars Rune Nøstdal
Subject: Re: [CLOS] Ensuring a method exists
Date: 
Message-ID: <pan.2006.09.27.11.56.36.165503@gmail.com>
On Wed, 27 Sep 2006 11:49:49 +0200, Lars Rune Nøstdal wrote:

> On Wed, 27 Sep 2006 11:17:57 +0200, Didier Verna wrote:
>>
>> So imagine having A <- B and creating only instances of B. The lack of method
>> for class A would go unnoticed. But I want the check for the whole hierarchy
>> (consider for instance that I'm using the AND method combination type and I'm
>> expecting an implementation for all the classes).
> 
> Oh, the one I just posted only checks downwards from the instantiated - I
> guess you could walk from the base at the very top each time.
> 
> Just change the last line in `initialize-instance', like this I think:
> 
>     (checkHierarchy 'SomeBase)))

..or you could "force" #'foo to be defined earlier:


(defmacro defclassAndFoo ((name superclasses &body class-body)
                          &body method-body)
  `(progn
     (setf (find-class ',name) nil)

     (defclass ,name ,superclasses
       ,@class-body)
     
     (values (find-class ',name)
             (defmethod foo ((a ,name) (b ,name))
               ,@method-body))))


(defclassAndFoo
    (SomeBase ()
      ())
  (write-line "(foo SomeBase SomeBase"))


(defclassAndFoo
    (SomeDerived (SomeBase)
      ())
  (write-line "(foo SomeDerived SomeDerived)"))


..I have no idea if this stuff will work for you or if it's suitable for
what you are doing - or whatever..

-- 
Lars Rune Nøstdal
http://lars.nostdal.org/
From: Rahul Jain
Subject: Re: [CLOS] Ensuring a method exists
Date: 
Message-ID: <87odst45t6.fsf@nyct.net>
Didier Verna <······@lrde.epita.fr> writes:

>         That's a nice solution but it has one caveat (my question was probably
> not clear enough about this): your trick checks for the existence of a method
> only for the class you instanciate, and not for the subclasses.
>
> So imagine having A <- B and creating only instances of B. The lack of method
> for class A would go unnoticed. But I want the check for the whole hierarchy
> (consider for instance that I'm using the AND method combination type and I'm
> expecting an implementation for all the classes).

RED FLAG!

You shouldn't be subclassing something if you don't want to get its
functionality as default. You shouldn't be using subclassing at all
here. I suspect that if you use my library do define a protocol like
VALIDATABLE and have method on the VALIDATE g-f as part of the protocol,
you'll get what you want. Then VALIDATABLE wouldn't be a class, so you
wouldn't get any functionality from it, just the requirement of that
method being implemented for VALIDATABLE classes.

So maybe you're just using the wrong terminology, as you haven't been
exposed to the Lisp concept of "protocols" which are analgous to the
Java concept of "interfaces" except that protocols aren't part of the
language officially (as it's rather tricky to force anything to be
around before anything else in a multiple-dispatch, dynamic OO
language). My library just allows a declaration of what a class
conforming to a protocol should support and a function to test whether
it has gotten to that point after you've loaded all appropriate code. 
Note that in CL, you can add functionality to a class in a different
library. Think about dispatching on INTEGER; effectively, you've now
given the INTEGER class more functionality than it may have before. This
is why my library allows you to declare protocols both inside the
defclass form as well as outside (to parallel the method definitions
that can occur in both places, as well).

-- 
Rahul Jain
·····@nyct.net
Professional Software Developer, Amateur Quantum Mechanicist
From: Didier Verna
Subject: Re: [CLOS] Ensuring a method exists
Date: 
Message-ID: <muxwt7g4l96.fsf@uzeb.lrde.epita.fr>
Rahul Jain <·····@nyct.net> wrote:

>> So imagine having A <- B and creating only instances of B. The lack of
>> method for class A would go unnoticed. But I want the check for the whole
>> hierarchy (consider for instance that I'm using the AND method combination
>> type and I'm expecting an implementation for all the classes).

> RED FLAG!
>
> You shouldn't be subclassing something if you don't want to get its
> functionality as default.

Sorry ? Consider the classic binary method example Point <- ColorPoint with
the point= function. ColorPoint *is* a subclass of Point, and *no*, I don't
want the implementation of point= for Point as the default functionality in
ColorPoint. I want to be sure that there is an implementation of point= for
both classes.


> You shouldn't be using subclassing at all here. I suspect that if you use my
> library do define a protocol [...]

        I'll throw an eye to it; thanks for the pointer.


> My library just allows a declaration of what a class conforming to a
> protocol should support and a function to test whether it has gotten to that
> point after you've loaded all appropriate code.

        How much control do you have on the time at which the check is
performed ?

-- 
Check out my new jazz CD on http://www.didierverna.com/ !

Didier Verna	EPITA / LRDE, 14-16 rue Voltaire   Tel.+33 (1) 44 08 01 85
             	94276 Le Kremlin-Bic�tre, France   Fax.+33 (1) 53 14 59 22
From: Ken Tilton
Subject: Re: [CLOS] Ensuring a method exists
Date: 
Message-ID: <FKKUg.641$Og4.354@newsfe12.lga>
Didier Verna wrote:
> Rahul Jain <·····@nyct.net> wrote:
> 
> 
>>>So imagine having A <- B and creating only instances of B. The lack of
>>>method for class A would go unnoticed. But I want the check for the whole
>>>hierarchy (consider for instance that I'm using the AND method combination
>>>type and I'm expecting an implementation for all the classes).
> 
> 
>>RED FLAG!
>>
>>You shouldn't be subclassing something if you don't want to get its
>>functionality as default.
> 
> 
> Sorry ? Consider the classic binary method example Point <- ColorPoint with
> the point= function. ColorPoint *is* a subclass of Point, and *no*, I don't
> want the implementation of point= for Point as the default functionality in
> ColorPoint. I want to be sure that there is an implementation of point= for
> both classes.

So a Point can be compared with a ColorPoint but a ColorPoint cannot be 
compared with a Point. Classic indeed: a design flaw misconstrued as a 
use case.

hth, k

-- 
Cells: http://common-lisp.net/project/cells/

"I'll say I'm losing my grip, and it feels terrific."
    -- Smiling husband to scowling wife, New Yorker cartoon
From: Didier Verna
Subject: Re: [CLOS] Ensuring a method exists
Date: 
Message-ID: <muxd5984eys.fsf@uzeb.lrde.epita.fr>
Ken Tilton <·········@gmail.com> wrote:

> So a Point can be compared with a ColorPoint

        No. A Point can be compared only with a Point. Just as a ColorPoint
can be compared with a ColorPoint only. However, to compare the Point part of
two ColorPoints, you want to reuse the Point-specific method and not duplicate
code.

> but a ColorPoint cannot be compared with a Point. Classic indeed: a design
> flaw misconstrued as a use case.

        Whatever.

-- 
Check out my new jazz CD on http://www.didierverna.com/ !

Didier Verna	EPITA / LRDE, 14-16 rue Voltaire   Tel.+33 (1) 44 08 01 85
             	94276 Le Kremlin-Bic�tre, France   Fax.+33 (1) 53 14 59 22
From: Ken Tilton
Subject: Re: [CLOS] Ensuring a method exists
Date: 
Message-ID: <D8LUg.860$Yn2.637@newsfe10.lga>
Didier Verna wrote:
> Ken Tilton <·········@gmail.com> wrote:
> 
> 
>>So a Point can be compared with a ColorPoint
> 
> 
>         No. A Point can be compared only with a Point.

I ain't no C++ whiz, but if the Point class has a member function 
(terminology?) that takes a Point argument and ColorPoint is a subclass 
of Point, then this code works:

    Point pt;
    ColorPoint colorpt;
    ...whatever...
    if (pt->point=(colorpt))....etc

No?


> Just as a ColorPoint
> can be compared with a ColorPoint only. However, to compare the Point part of
> two ColorPoints, you want to reuse the Point-specific method and not duplicate
> code.
> 
> 
>>but a ColorPoint cannot be compared with a Point. Classic indeed: a design
>>flaw misconstrued as a use case.
> 
> 
>         Whatever.
> 

-- 
Cells: http://common-lisp.net/project/cells/

"I'll say I'm losing my grip, and it feels terrific."
    -- Smiling husband to scowling wife, New Yorker cartoon
From: Didier Verna
Subject: Re: [CLOS] Ensuring a method exists
Date: 
Message-ID: <mux8xjw4db8.fsf@uzeb.lrde.epita.fr>
Ken Tilton <·········@gmail.com> wrote:

> I ain't no C++ whiz, but if the Point class has a member function
> (terminology ?) that takes a Point argument and ColorPoint is a subclass of
> Point, then this code works:
>
>    Point pt;
>    ColorPoint colorpt;
>    ...whatever...
>    if (pt->point=(colorpt))....etc
>
> No ?

        Yes, and that precise example, that can be a problem (fixed more
easily in CLOS than in C++).

-- 
Check out my new jazz CD on http://www.didierverna.com/ !

Didier Verna	EPITA / LRDE, 14-16 rue Voltaire   Tel.+33 (1) 44 08 01 85
             	94276 Le Kremlin-Bic�tre, France   Fax.+33 (1) 53 14 59 22
From: Ken Tilton
Subject: Re: [CLOS] Ensuring a method exists
Date: 
Message-ID: <l_LUg.643$Og4.413@newsfe12.lga>
Didier Verna wrote:
> Ken Tilton <·········@gmail.com> wrote:
> 
> 
>>I ain't no C++ whiz, but if the Point class has a member function
>>(terminology ?) that takes a Point argument and ColorPoint is a subclass of
>>Point, then this code works:
>>
>>   Point pt;
>>   ColorPoint colorpt;
>>   ...whatever...
>>   if (pt->point=(colorpt))....etc
>>
>>No ?
> 
> 
>         Yes, ...

What happened to "No"?:

Didier Verna wrote:
 > Ken Tilton <·········@gmail.com> wrote:
 >> So a Point can be compared with a ColorPoint
 >
 >         No.

I am starting to think those girls in the pub moved away from you and 
your buddy because they /like/ programming.

> ...and that precise example, that can be a problem (fixed more
> easily in CLOS than in C++).
> 

the problem is (a) worrying about language mechanics when you 
(collectively with the paper authors) simply have no clue what you mean 
by point=, and (b) thinking more/different language mechanics will bail 
you out when you end up with silly results such as a non-commutative 
operation with "equals" in its name.

Once embarked on this road to nowhere, everything looks like a syntax 
issue, which is how you end up maintaining that a method specialized on 
a superclass does not apply to a subclass, which is blatant OO pap.

Apologies in advance if I am being too easy on you.

:)

kenny

-- 
Cells: http://common-lisp.net/project/cells/

"I'll say I'm losing my grip, and it feels terrific."
    -- Smiling husband to scowling wife, New Yorker cartoon
From: Didier Verna
Subject: Re: [CLOS] Ensuring a method exists
Date: 
Message-ID: <muxr6xo2rkw.fsf@uzeb.lrde.epita.fr>
Ken Tilton <·········@gmail.com> wrote:

>>>I ain't no C++ whiz, but if the Point class has a member function
>>>(terminology ?) that takes a Point argument and ColorPoint is a subclass of
>>>Point, then this code works:
>>>
>>>   Point pt;
>>>   ColorPoint colorpt;
>>>   ...whatever...
>>>   if (pt->point=(colorpt))....etc
>>>
>>>No ?
>>
>>
>>         Yes, ...
>
> What happened to "No"?:
>
> Didier Verna wrote:
>> Ken Tilton <·········@gmail.com> wrote:
>>> So a Point can be compared with a ColorPoint
>>
>>         No.

        So you really need a picture, don't you ? Actually, there are people
here that think you're reasonably smart, so I'm assuming you play the dummy
just for the fun of it. But here it is, just to be sure: a Point can be
compared with a ColorPoint /technically/ because of method inheritance (hence
the "yes"). But a Point can't be compared with a ColorPoint /conceptually/
because it makes no sense (hence the "no").



> when you (collectively with the paper authors) simply have no clue what you
> mean by point=

        On the contrary, I know precisely what I mean by point= and *you* have
no clue whatsoever about what you're talking about. If you're happy with
point= applying to a Point /and/ a ColorPoint at the same time, this means
that you're rather talking about position=.

But anyway, whatever the name you give to a method, the need for expressing
different forms of (concepts related to) equality is unarguable.



> Once embarked on this road to nowhere, everything looks like a syntax issue,
> which is how you end up maintaining that a method specialized on a superclass
> does not apply to a subclass, which is blatant OO pap.

        Utter nonsense. I never said such a method would not apply to a
subclass. Only, there are cases where it cannot apply alone; you need
additional processing, specific to the subclass. So you rilly, rilly need a
picture after all ...


;; Skipping the details of ensuring the methods exist, that calling point= on
;; objects of different types should barf etc.

(defgeneric point= (a b)
  ...
  (:method-combination and))

(defclass Point ()
  ;; define x,y,z coordinates
  )

(defmethod point= and ((a Point) (b Point))
  ;; check equality of coordinates
  )

(defclass ColorPoint (Point)
  ;; define a color
  )

(defmethod point= and ((a ColorPoint) (b ColorPoint))
  ;; check equality of colors
  )


Do you get it now ? Do you see why sometimes a method can technically apply by
to a subclass but shouldn't ? Do you realize that if you're missing the last
specialization, you won't get an error, but still your program is bogus ? Do
you finally acknowledge that such an equality concept is perfectly valid and
legitimate ?



> I am starting to think those girls in the pub moved away from you and your
> buddy because they /like/ programming.

        I'm a happy husband and father of two adorable children, thanks ;-)



> Apologies in advance if I am being too easy on you.

        Actually, I think I'm simply gonna stop reading you[1] as of now. My
original question was "ensuring a method exists". A voluntarily fuzzy one, in
order to see what poped up form people's minds. And I got very different,
interesting and constructive answers or remarks from Christophe, Pascal and
the others. However, this benign thing went all the way out of control when
you asked:

> And of course, the question nobody is going to ask is why do you want [...]

This is funny because recently, you wrote 

> The reason is that we cannot have a DWIM language. By which I mean "a
> language that guesses at what I am doing", however good its intentions. I do
> enough damage with languages that do exactly what I tell them, ya really
> wanna see how much damage I can do with a language that tries to read my
> mind ?

        Well, you know what ? We don't need a DWIM super-kenny. You wanna help
people ? Then answer their fraking questions instead of thinking you're so
smart that you can figure out what they have in mind. You're obviously not
good at that . Maybe if you stop being a DWIM human, you'll sound less
arrogant and people will stop "saying bad things about you on cll" ;-)

Apologies accepted :-)




Footnotes: 
[1]  I'm not putting you in my kill file, though, since I sometimes smile at
your "fortune" paragraphs that make you the official cll clown.

-- 
Check out my new jazz CD on http://www.didierverna.com/ !

Didier Verna	EPITA / LRDE, 14-16 rue Voltaire   Tel.+33 (1) 44 08 01 85
             	94276 Le Kremlin-Bic�tre, France   Fax.+33 (1) 53 14 59 22
From: Ken Tilton
Subject: Re: [CLOS] Ensuring a method exists
Date: 
Message-ID: <86QUg.717$Og4.650@newsfe12.lga>
Didier Verna wrote:

>         Well, you know what ? We don't need a DWIM super-kenny. You wanna help
> people ? Then answer their fraking questions...

We have Pascal for that. But did you mean...

Didier Verna wrote:
 > Ken Tilton <·········@gmail.com> wrote:
 >
 >>If not, maybe your Lisp has something like ACL's:
 >>
 >>(method-specializers
 >>   (find-method #'make-style-font nil
 >>       (list (find-class 'gui-style-ftgl))))
 >>
 >>-> (#<STANDARD-CLASS GUI-STYLE-FTGL>)
 >
 >
 >         Sounds like this is along the lines of Christophe's message. 
I'll look
 > into it. thanks.

Yer frickin' welcome. But it is more educational for Lisp newbies if 
experienced programmers do not slavishly buy into the misconceptions of 
those (such as you) seeking help here on c.l.l.

It is not a coincidence, when I or others raise an eyebrow at a 
question, that the questioner turns out invariably to need something 
other than for what they asked.

Your case is unusual because it turns out you did not need anything; you 
were not actually trying to write any code. You just wanted to waste 
c.l.l's time seeing if CLOS could do something contrived. You wrote: "It 
was after a discussion with a friend about the problems of binary 
methods in traditional objects systems. I was playing with the idea and 
trying to see how those problems could be solved with CLOS"

Funny, the paper I cited (http://lucacardelli.name/Papers/Binary.A4.ps) 
acknowledges that the binary method problem cannot even arise in CLOS. 
Perhaps this is why you are having so much trouble solving it with CLOS.

> instead of thinking you're so
> smart that you can figure out what they have in mind.

Nonsense. I /asked/: "Of course the big question no one will ask is why 
you want to do this." Maybe there is a language barrier. The French for 
question is "question". Does that help?

> You're obviously not
> good at that .

You are right, it never occurred to me that anyone would waste experts' 
time by asking a question they did not need for actual work without 
disclosing they were just pissing around so those of us who enjoy 
helping those seriously needing help could ignore you.

> Maybe if you stop being a DWIM human, you'll sound less
> arrogant and people will stop "saying bad things about you on cll" ;-)
> 
> Apologies accepted :-)

So in summary, I first answered your question, then offered to help you 
fix your design, and then, upon discovering you had no design and 
instead were just playing games, directed you to a solid paper 
concluding your question was itself a mistake (CLOS has no problem with 
the functionality in question)... and for all that I get called 
"arrogant" and apologies are demanded?

You French really are pissed off about Lance Armstrong, aren't you?

kenny

-- 
Cells: http://common-lisp.net/project/cells/

"I'll say I'm losing my grip, and it feels terrific."
    -- Smiling husband to scowling wife, New Yorker cartoon
From: Rahul Jain
Subject: Re: [CLOS] Ensuring a method exists
Date: 
Message-ID: <871wpnoo5r.fsf@nyct.net>
Didier Verna <······@lrde.epita.fr> writes:

> [1]  I'm not putting you in my kill file, though, since I sometimes smile at
> your "fortune" paragraphs that make you the official cll clown.

He's the official c.l.l. clown, guard dog, and evangelist, actually.

-- 
Rahul Jain
·····@nyct.net
Professional Software Developer, Amateur Quantum Mechanicist
From: Thomas A. Russ
Subject: Re: [CLOS] Ensuring a method exists
Date: 
Message-ID: <ymivemy1gu0.fsf@sevak.isi.edu>
Didier Verna <······@lrde.epita.fr> writes:

> Ken Tilton <·········@gmail.com> wrote:
> 
>         Utter nonsense. I never said such a method would not apply to a
> subclass. Only, there are cases where it cannot apply alone; you need
> additional processing, specific to the subclass. So you rilly, rilly need a
> picture after all ...
> 
> 
> ;; Skipping the details of ensuring the methods exist, that calling point= on
> ;; objects of different types should barf etc.
>
> (defgeneric point= (a b)
>   ...
>   (:method-combination and))
> 
> (defclass Point ()
>   ;; define x,y,z coordinates
>   )
> 
> (defmethod point= and ((a Point) (b Point))
>   ;; check equality of coordinates
>   )

Well, if using AND combination, why not also have a point=(T,T) that
checks that (eq (type-of a) (type-of b)) ??

> 
> (defclass ColorPoint (Point)
>   ;; define a color
>   )
> 
> (defmethod point= and ((a ColorPoint) (b ColorPoint))
>   ;; check equality of colors
>   )

OK.  But what if the programmer doesn't do the right thing here?
What if they forget the "and" combination tag?

> 
> Do you get it now ? Do you see why sometimes a method can technically apply by
> to a subclass but shouldn't ? Do you realize that if you're missing the last
> specialization, you won't get an error, but still your program is bogus ? Do
> you finally acknowledge that such an equality concept is perfectly valid and
> legitimate ?

Well, there are lots of other bugs that can make your program bogus.  At
some level you have to rely on the competence of the programmer.  So why
not rely on the programmer's competence to make sure the necessary
methods are implemented?

You could probably write some sort of around or before method that
checks to make sure the appropriate methods exist, but this would be a
runtime check.  I doubt it would be worth the trouble.  The fundamental
issue is also that methods belong to functions and not classes, so you
can't really force a check that methods exist at the class level.  It
has to be at the generic function level, but then how do you know that
you aren't supposed to have point= defined on INTEGER, FLOAT, STRING,
etc.?  

-- 
Thomas A. Russ,  USC/Information Sciences Institute
From: Didier Verna
Subject: Re: [CLOS] Ensuring a method exists
Date: 
Message-ID: <mux8xjt1usd.fsf@uzeb.lrde.epita.fr>
···@sevak.isi.edu (Thomas A. Russ) wrote:

>> ;; Skipping the details of ensuring the methods exist, that calling point=
>> on ;; objects of different types should barf etc.
>>
>> (defgeneric point= (a b)
>>   ...
>>   (:method-combination and))
>> 
>> (defclass Point ()
>>   ;; define x,y,z coordinates
>>   )
>> 
>> (defmethod point= and ((a Point) (b Point))
>>   ;; check equality of coordinates
>>   )
>
> Well, if using AND combination, why not also have a point=(T,T) that
> checks that (eq (type-of a) (type-of b)) ??

        Read again the comment above.



>> (defclass ColorPoint (Point)
>>   ;; define a color
>>   )
>> 
>> (defmethod point= and ((a ColorPoint) (b ColorPoint))
>>   ;; check equality of colors
>>   )
>
> OK.  But what if the programmer doesn't do the right thing here?
> What if they forget the "and" combination tag?

        Is that one or two questions ? CLOS will signal an error.



> Well, there are lots of other bugs that can make your program bogus.

        Sure, and I've never pretented I wanted to check'em all (of course).


> At some level you have to rely on the competence of the programmer. So why
> not rely on the programmer's competence to make sure the necessary methods
> are implemented ?

        So, the question really is where do I set this "level" of reliance on
the programmer. I have two answers:

1/ first, although I use Lisp and I enjoy its freedom, that's no reason to let
the programmer (say the library user) on its own completely, maybe contrary to
what most people here would do. In the case of a library user, I still think
it's better to abort with an informative message, than to let the application
crash obscurely, or worse, to continue running in a shaky state. People are
free to put their level of "willingness to help" where they want though (is
that english ?).

2/ but much more importantly, there is a *major* difference between what you
call the "other bugs" and, in my example, the fact of forgetting to write a
method. The difference is that the fact that the method must exist is *part of
the concept I want to express*. If that concept were directly available in the
language, I wouldn't have to worry about errors. But precisely because this
concept does not really exist in CLOS, I *have* to perform the check if I am
to pretend that the concept _is_ supported. Like I said in another post, I
really am defining a specific object system to support the concept here.


-- 
Check out my new jazz CD on http://www.didierverna.com/ !

Didier Verna	EPITA / LRDE, 14-16 rue Voltaire   Tel.+33 (1) 44 08 01 85
             	94276 Le Kremlin-Bic�tre, France   Fax.+33 (1) 53 14 59 22
From: jayessay
Subject: Re: [CLOS] Ensuring a method exists
Date: 
Message-ID: <m3fye1z8zj.fsf@rigel.goldenthreadtech.com>
Didier Verna <······@lrde.epita.fr> writes:

> method. The difference is that the fact that the method must exist
> is *part of the concept I want to express*. If that concept were
> directly available in the language, I wouldn't have to worry about
> errors. But precisely because this concept does not really exist in
> CLOS, I *have* to perform the check if I am to pretend that the
> concept _is_ supported. Like I said in another post, I really am
> defining a specific object system to support the concept here.

So, is there a reason why you don't want a separate syntax to support
this other "object system" which would provide construct(s) which
enforce this requirement?  Trying to do this with CLOS using only its
own surface syntax seems to be a big part of your "problem" here.


/Jon

-- 
'j' - a n t h o n y at romeo/charley/november com
From: Didier Verna
Subject: Re: [CLOS] Ensuring a method exists
Date: 
Message-ID: <muxzmc9z3rd.fsf@uzeb.lrde.epita.fr>
jayessay <······@foo.com> wrote:

> So, is there a reason why you don't want a separate syntax to support
> this other "object system" which would provide construct(s) which
> enforce this requirement?  Trying to do this with CLOS using only its
> own surface syntax seems to be a big part of your "problem" here.

        No it's not. Indeed, CLOS'surface (that is, the default object system
it implements) does not suffice. However, I can program my own object system
with the MOP, and the surface remains unchanged, precisely.

-- 
Check out my new jazz CD on http://www.didierverna.com/ !

Didier Verna	EPITA / LRDE, 14-16 rue Voltaire   Tel.+33 (1) 44 08 01 85
             	94276 Le Kremlin-Bic�tre, France   Fax.+33 (1) 53 14 59 22
From: jayessay
Subject: Re: [CLOS] Ensuring a method exists
Date: 
Message-ID: <m3bqomzs40.fsf@rigel.goldenthreadtech.com>
Didier Verna <······@lrde.epita.fr> writes:

> jayessay <······@foo.com> wrote:
> 
> > So, is there a reason why you don't want a separate syntax to support
> > this other "object system" which would provide construct(s) which
> > enforce this requirement?  Trying to do this with CLOS using only its
> > own surface syntax seems to be a big part of your "problem" here.
> 

>         No it's not. Indeed, CLOS'surface (that is, the default object system
> it implements) does not suffice.

This


> However, I can program my own object system with the MOP, and the
> surface remains unchanged, precisely.

contradicts this.  You need to understand this point in order to
understand some of the critiques here.  You are fixated on how to
_implement_ a semantic and have bypassed the (actually more important)
step of how to _express_ it.


/Jon

-- 
'j' - a n t h o n y at romeo/charley/november com
From: Rahul Jain
Subject: Re: [CLOS] Ensuring a method exists
Date: 
Message-ID: <8764ezooaf.fsf@nyct.net>
Ken Tilton <·········@gmail.com> writes:

> I am starting to think those girls in the pub moved away from you and
> your buddy because they /like/ programming.

[snip]

> the problem is (a) worrying about language mechanics when you
> (collectively with the paper authors) simply have no clue what you mean
> by point=, and (b) thinking more/different language mechanics will bail
> you out when you end up with silly results such as a non-commutative
> operation with "equals" in its name.

Ouch. Well done. You got this one covered, I guess. :)

-- 
Rahul Jain
·····@nyct.net
Professional Software Developer, Amateur Quantum Mechanicist
From: Thomas A. Russ
Subject: Re: [CLOS] Ensuring a method exists
Date: 
Message-ID: <ymi64ey2vrm.fsf@sevak.isi.edu>
Didier Verna <······@lrde.epita.fr> writes:

> Ken Tilton <·········@gmail.com> wrote:
> 
> > So a Point can be compared with a ColorPoint
> 
>         No. A Point can be compared only with a Point. Just as a ColorPoint
> can be compared with a ColorPoint only. However, to compare the Point part of
> two ColorPoints, you want to reuse the Point-specific method and not duplicate
> code.

But you don't get this behavior from your example.  If you have

(defmethod point= ((x Point) (y Point)) ...)
(defmethod point= ((x ColorPoint) (y ColorPoint)) ...)

and then you call 

(point= somePoint someColorPoint)

you would get the comparison for Point, since that is the most specific
method that applies to both items.

The fundamental thing that you are fighting against here is one of the
basic philosophic differences between say Java and Lisp.  Lisp doesn't
try to force the programmer to do things.  It assumes that the
programmer knows what he's doing and will do the right thing.

To some extent you can put in tests that will (at runtime) check for
various conditions.  You could, for example, put in some check that the
types being compared be the same.  But that can always be overridden by
someone else's method.

In fact, anyone who wants to can redefine your methods anyway, so what
is the point of trying to force a particular implementation?  Even if
you supply compiled code, they can redefine stuff, so you will need to
adjust to the different programming mindset.  Let the flexibility set
you free!


> > but a ColorPoint cannot be compared with a Point. Classic indeed: a design
> > flaw misconstrued as a use case.
> 
>         Whatever.
> 
> -- 
> Check out my new jazz CD on http://www.didierverna.com/ !
> 
> Didier Verna	EPITA / LRDE, 14-16 rue Voltaire   Tel.+33 (1) 44 08 01 85
>              	94276 Le Kremlin-Bic�tre, France   Fax.+33 (1) 53 14 59 22

-- 
Thomas A. Russ,  USC/Information Sciences Institute
From: Didier Verna
Subject: Re: [CLOS] Ensuring a method exists
Date: 
Message-ID: <muxd5951wkt.fsf@uzeb.lrde.epita.fr>
···@sevak.isi.edu (Thomas A. Russ) wrote:

>>         No. A Point can be compared only with a Point. Just as a ColorPoint
>> can be compared with a ColorPoint only. However, to compare the Point part
>> of two ColorPoints, you want to reuse the Point-specific method and not
>> duplicate code.
>
> But you don't get this behavior from your example.  If you have
>
> (defmethod point= ((x Point) (y Point)) ...)
> (defmethod point= ((x ColorPoint) (y ColorPoint)) ...)
>
> and then you call 
>
> (point= somePoint someColorPoint)
>
> you would get the comparison for Point, since that is the most specific
> method that applies to both items.

        You skipped the comment I Put on top of the code. Or maybe you're not
referring to that message ?


> The fundamental thing that you are fighting against here is one of the basic
> philosophic differences between say Java and Lisp. Lisp doesn't try to force
> the programmer to do things.

        Indeed, but it gives you plenty of ways to do so if you wish.


> In fact, anyone who wants to can redefine your methods anyway, so what is
> the point of trying to force a particular implementation? Even if you supply
> compiled code, they can redefine stuff, so you will need to adjust to the
> different programming mindset.

        The difference is that somebody might be shooting himself in the foot
by mistake (for instance, again, by forgetting to write a method), in which
case I'd like to help prevent this as much as I can. On the other hand, if
that guy is actually voluntarily doing things not the intended way (which is
the case you seem to underline), then yes, he's on his own.

-- 
Check out my new jazz CD on http://www.didierverna.com/ !

Didier Verna	EPITA / LRDE, 14-16 rue Voltaire   Tel.+33 (1) 44 08 01 85
             	94276 Le Kremlin-Bic�tre, France   Fax.+33 (1) 53 14 59 22
From: Stefan Nobis
Subject: Re: [CLOS] Ensuring a method exists
Date: 
Message-ID: <87ejtlk09y.fsf@snobis.de>
Didier Verna <······@lrde.epita.fr> writes:

>> The fundamental thing that you are fighting against here is one of
>> the basic philosophic differences between say Java and Lisp. Lisp
>> doesn't try to force the programmer to do things.

>         Indeed, but it gives you plenty of ways to do so if you wish.

But you shouldn't use them. Don't try to solve social problems with
technical means.

> The difference is that somebody might be shooting himself in the
> foot by mistake (for instance, again, by forgetting to write a
> method), in which case I'd like to help prevent this as much as I
> can.

But how can you be sure? What if that user on purpose didn't want to
implement a new point= method? Why do you think you classes are only
allowed to be used in the way(s) you thought of? Why not give others
all the freedom and acompany that with really good documentation?

Please don't force a user of your library to do only those things you
thought of. I had to use some libraries written in this style and that
really really sucks! There are much better tools (documentation not
the worst) to show other what you think should be the default way to
use your code.

-- 
Stefan.
From: Ken Tilton
Subject: Re: [CLOS] Ensuring a method exists
Date: 
Message-ID: <%5vVg.18$Zg1.7@newsfe10.lga>
Stefan Nobis wrote:
> Didier Verna <······@lrde.epita.fr> writes:
> 
> 
>>>The fundamental thing that you are fighting against here is one of
>>>the basic philosophic differences between say Java and Lisp. Lisp
>>>doesn't try to force the programmer to do things.
> 
> 
>>        Indeed, but it gives you plenty of ways to do so if you wish.
> 
> 
> But you shouldn't use them. Don't try to solve social problems with
> technical means.

So why do I have to have my foot on the brake if I want to take an 
automatic transmission out of "park"? Hang on, wrong NG...

kt

-- 
Cells: http://common-lisp.net/project/cells/

"I'll say I'm losing my grip, and it feels terrific."
    -- Smiling husband to scowling wife, New Yorker cartoon
From: Pascal Bourguignon
Subject: Re: [CLOS] Ensuring a method exists
Date: 
Message-ID: <87sli1o16w.fsf@thalassa.informatimago.com>
Stefan Nobis <······@gmx.de> writes:
> Didier Verna <······@lrde.epita.fr> writes:
>
>>> The fundamental thing that you are fighting against here is one of
>>> the basic philosophic differences between say Java and Lisp. Lisp
>>> doesn't try to force the programmer to do things.
>
>>         Indeed, but it gives you plenty of ways to do so if you wish.
>
> But you shouldn't use them. Don't try to solve social problems with
> technical means.
>
>> The difference is that somebody might be shooting himself in the
>> foot by mistake (for instance, again, by forgetting to write a
>> method), in which case I'd like to help prevent this as much as I
>> can.
>
> But how can you be sure? What if that user on purpose didn't want to
> implement a new point= method? Why do you think you classes are only
> allowed to be used in the way(s) you thought of? Why not give others
> all the freedom and acompany that with really good documentation?

It's a matter of convention. Anything that comes with = in it should
be allowed to work on any entity.

Already, the fact that (= a b) may raise an error because a is not a
number is bad IMO. ( In math, you can write:  {a,b,c} = 42 ==> 0 = 1 ).

But in any case, a function called point= should be callable with any point.

(and (type-of x 'point) (type-of y 'point)) ==> (point= x y) --> boolean


> Please don't force a user of your library to do only those things you
> thought of. I had to use some libraries written in this style and that
> really really sucks! There are much better tools (documentation not
> the worst) to show other what you think should be the default way to
> use your code.

Please choose another name if you don't want to implement the
conventionnal meaning.



Or, write a big comment on the top of your source files indicating
what conventions you are using.

-- 
__Pascal Bourguignon__                     http://www.informatimago.com/

"Our users will know fear and cower before our software! Ship it!
Ship it and let them flee like the dogs they are!"
From: Stefan Nobis
Subject: Re: [CLOS] Ensuring a method exists
Date: 
Message-ID: <871wpljq50.fsf@snobis.de>
Pascal Bourguignon <···@informatimago.com> writes:

> Please choose another name if you don't want to implement the
> conventionnal meaning.

I thought of things like using the same point= for objects of classes
Point and ColorPoint -- why force a user of Point which wants to
subclass it to implement a new point= if the old one suffices? So
document that it may be a good idea to reimplement point=, but don't
force it technically.

-- 
Stefan.
From: Rahul Jain
Subject: Re: [CLOS] Ensuring a method exists
Date: 
Message-ID: <87ac4booer.fsf@nyct.net>
Didier Verna <······@lrde.epita.fr> writes:

> Rahul Jain <·····@nyct.net> wrote:
>
>> You shouldn't be subclassing something if you don't want to get its
>> functionality as default.
>
> Sorry ? Consider the classic binary method example Point <- ColorPoint with
> the point= function. ColorPoint *is* a subclass of Point, and *no*, I don't
> want the implementation of point= for Point as the default functionality in
> ColorPoint. I want to be sure that there is an implementation of point= for
> both classes.

Equality is not an OO concept. You should not be using a g-f to
determine equality. What would it mean for me to compare a point to a
color-point? And I mean OO in the polymorphic sense, not the
encapsulation sense.

Acutally, if I created a point= operator, I would want a point and a
color-point to be compared on coordinates only, disregarding the color
of the color-point, so I _would_ want the funcitonality to be inherited,
but NEVER overridden. So I'd just write a function for point= and allow
the polymorphism to apply at the level of pulling the coords out of the
object. I'd write a color-point-equal function to compare the coords and
colors.

There's a reason why the equality operators in CL are not g-fs.

>> My library just allows a declaration of what a class conforming to a
>> protocol should support and a function to test whether it has gotten to that
>> point after you've loaded all appropriate code.
>
>         How much control do you have on the time at which the check is
> performed ?

You call it explicitly. Total control. Total responsibility. Of course,
this is necessary in a dynamic lanaguage, because the "validity" of the
code according to some criteria changes as definitons are added,
modified, and removed from the system.

It won't help you with trying to change the way the applicable method
list is computed, tho. It just checks that there exists an applicable
method. It's also not going to inspect the code of each method to make
sure that every time it calls call-next-method, there will be a next
method to call. Not sure I could do that in a way that avoids false
negatives anyway.

-- 
Rahul Jain
·····@nyct.net
Professional Software Developer, Amateur Quantum Mechanicist
From: Jack Unrue
Subject: Re: [CLOS] Ensuring a method exists
Date: 
Message-ID: <ii88i25jh09c6h7tmqu49f8m67hkmlnh50@4ax.com>
On Wed, 04 Oct 2006 15:45:48 -0400, Rahul Jain <·····@nyct.net> wrote:
>
> Didier Verna <······@lrde.epita.fr> writes:
> 
> > Rahul Jain <·····@nyct.net> wrote:
> >
> >> You shouldn't be subclassing something if you don't want to get its
> >> functionality as default.
> >
> > Sorry ? Consider the classic binary method example Point <- ColorPoint with
> > the point= function. ColorPoint *is* a subclass of Point, and *no*, I don't
> > want the implementation of point= for Point as the default functionality in
> > ColorPoint. I want to be sure that there is an implementation of point= for
> > both classes.
> 
> Equality is not an OO concept. You should not be using a g-f to
> determine equality. What would it mean for me to compare a point to a
> color-point? And I mean OO in the polymorphic sense, not the
> encapsulation sense.

Agreed. The concept of equality as we understand it to mean in this
discussion is at odds with the Liskov Substitution Principle, which
says:

  "Let q(x) be a property provable about objects x of type T. Then
   q(y) should be true for objects y of type S where S is a subtype
   of T." [1]

We can't substitute any Point for a ColorPoint where point= must be
called, since the following is meaningless according to Didier's
definitions of point=

  (point= a-color-point a-point)

-- 
Jack Unrue

[1] http://en.wikipedia.org/wiki/Liskov_substitution_principle
From: Pascal Costanza
Subject: Re: [CLOS] Ensuring a method exists
Date: 
Message-ID: <4okq9fFf98c8U2@individual.net>
Jack Unrue wrote:

> 
> Agreed. The concept of equality as we understand it to mean in this
> discussion is at odds with the Liskov Substitution Principle, which
> says:
> 
>   "Let q(x) be a property provable about objects x of type T. Then
>    q(y) should be true for objects y of type S where S is a subtype
>    of T." [1]

And why should we follow that principle? Not even Liskov said we should.


Pascal

-- 
My website: http://p-cos.net
Common Lisp Document Repository: http://cdr.eurolisp.org
Closer to MOP & ContextL: http://common-lisp.net/project/closer/
From: Jack Unrue
Subject: Re: [CLOS] Ensuring a method exists
Date: 
Message-ID: <c6eai2t7qap5q3e3dbj9jv7nr6ls15vbfc@4ax.com>
On Thu, 05 Oct 2006 18:30:39 +0200, Pascal Costanza <··@p-cos.net> wrote:
>
> Jack Unrue wrote:
> 
> > 
> > Agreed. The concept of equality as we understand it to mean in this
> > discussion is at odds with the Liskov Substitution Principle, which
> > says:
> > 
> >   "Let q(x) be a property provable about objects x of type T. Then
> >    q(y) should be true for objects y of type S where S is a subtype
> >    of T." [1]
> 
> And why should we follow that principle? Not even Liskov said we should.

OK. Liskov co-authored two papers that provided definitions of subtype
relations with the intention to "precisely capture this subtype requirement."

Would you be happier with:

  "If for each object o1 of type S there is an object o2 of type T such
   that for all programs P defined in terms of T, the behaviour of P is
   unchanged when o1 is substituted for o2 then S is a subtype of T."

?

-- 
Jack Unrue
From: Jack Unrue
Subject: Re: [CLOS] Ensuring a method exists
Date: 
Message-ID: <40pai25l55dgaho4tuea7vnhabdt5gjlkk@4ax.com>
On Thu, 05 Oct 2006 18:07:01 GMT, Jack Unrue <·······@example.tld> wrote:
>
> > 
> > And why should we follow that principle? Not even Liskov said we should.
>
> [snip my comments]

Maybe I'm not understanding what you're saying. Are you disputing
LSP in general or how it's relevant to this thread? Or that a
principle is being attributed to someone that was never actually
stated as such?

-- 
Jack Unrue
From: Pascal Costanza
Subject: Re: [CLOS] Ensuring a method exists
Date: 
Message-ID: <4ol9unFervahU1@individual.net>
Jack Unrue wrote:
> On Thu, 05 Oct 2006 18:07:01 GMT, Jack Unrue <·······@example.tld> wrote:
>>> And why should we follow that principle? Not even Liskov said we should.
>> [snip my comments]
> 
> Maybe I'm not understanding what you're saying. Are you disputing
> LSP in general or how it's relevant to this thread? Or that a
> principle is being attributed to someone that was never actually
> stated as such?

LSP is a good rule of thumb, but shouldn't be followed blindly, as with 
all programming "principles." At least, IMHO. What matters is if 
something solves your problem or not, not if it adheres to some 
aesthetics that may or may not be relevant for your task at hand.


Pascal

-- 
My website: http://p-cos.net
Common Lisp Document Repository: http://cdr.eurolisp.org
Closer to MOP & ContextL: http://common-lisp.net/project/closer/
From: jayessay
Subject: Re: [CLOS] Ensuring a method exists
Date: 
Message-ID: <m3odsqzrh0.fsf@rigel.goldenthreadtech.com>
Rahul Jain <·····@nyct.net> writes:

> Didier Verna <······@lrde.epita.fr> writes:
> 
> > Rahul Jain <·····@nyct.net> wrote:
> >
> >> You shouldn't be subclassing something if you don't want to get its
> >> functionality as default.
> >
> > Sorry ? Consider the classic binary method example Point <- ColorPoint with
> > the point= function. ColorPoint *is* a subclass of Point, and *no*, I don't
> > want the implementation of point= for Point as the default functionality in
> > ColorPoint. I want to be sure that there is an implementation of point= for
> > both classes.
> 
> Equality is not an OO concept. You should not be using a g-f to
> determine equality. What would it mean for me to compare a point to a
> color-point? And I mean OO in the polymorphic sense, not the
> encapsulation sense.

I think this is the key observation and I think KT kind of pointed it
out as well.  Actually it pretty much applies to the entire "binary
method" issue: it's only an issue if you assume "OO" (and class
centric OO at that) as being _the_ fundamentally correct paradigm in
which to cast all "legitimate" solutions.  If you realize that
assumption is nonsense, the "problem" evaporates.


/Jon

-- 
'j' - a n t h o n y at romeo/charley/november com
From: Christophe Rhodes
Subject: Re: [CLOS] Ensuring a method exists
Date: 
Message-ID: <sq1wpmu53b.fsf@cam.ac.uk>
jayessay <······@foo.com> writes:

> I think this is the key observation and I think KT kind of pointed it
> out as well.  Actually it pretty much applies to the entire "binary
> method" issue: it's only an issue if you assume "OO" (and class
> centric OO at that) as being _the_ fundamentally correct paradigm in
> which to cast all "legitimate" solutions.  If you realize that
> assumption is nonsense, the "problem" evaporates.

No, it is an issue if you assume OO, of any form, is capable of
expressing _any_ legitimate solution.  

I'll make the point again, since it didn't seem to get through in this
discussion first time: just as we, having CLOS, recognize that C++'s
object-oriented model is not the only possible one, can we please
recognize that CLOS's object-oriented model is not a superset of all
possible ones?

(I'm sure that people would agree that motherhood, apple pie and code
reuse are good things; and yet I wonder why people are arguing so
strongly against exploration of ways to improve code reusability.
That's the impression that I'm getting, anyway; it seems that people
want to react against implementing a generalized-object-system or
not-quite-object system, irrespective of any possible benefits, and
are appealing to the Turing tarpit to say that it's unnecessary.)

Christophe
From: jayessay
Subject: Re: [CLOS] Ensuring a method exists
Date: 
Message-ID: <m3k63ezore.fsf@rigel.goldenthreadtech.com>
Christophe Rhodes <·····@cam.ac.uk> writes:

> jayessay <······@foo.com> writes:
> 
> > I think this is the key observation and I think KT kind of pointed it
> > out as well.  Actually it pretty much applies to the entire "binary
> > method" issue: it's only an issue if you assume "OO" (and class
> > centric OO at that) as being _the_ fundamentally correct paradigm in
> > which to cast all "legitimate" solutions.  If you realize that
> > assumption is nonsense, the "problem" evaporates.
> 
> No, it is an issue if you assume OO, of any form, is capable of
> expressing _any_ legitimate solution.  

This is unclear - are you saying OO is not capable of expressing
legitimate solutions to any problem?  Or (the more mundane claim) that
OO can't express a legitimate solution to this "problem"?  If the
latter, then you should have said "yes" - as you are just agreeing
with what I said.  If the former, well that's a bit extreme but I
wouldn't argue much with it.


> object-oriented model is not the only possible one, can we please
> recognize that CLOS's object-oriented model is not a superset of all
> possible ones?

Sure - has anyone actually indicated otherwise?


> want to react against implementing a generalized-object-system or
> not-quite-object system, irrespective of any possible benefits, and
> are appealing to the Turing tarpit to say that it's unnecessary.)

Now, here I'd say you have pretty much completely missed what's being
said.


/Jon

-- 
'j' - a n t h o n y at romeo/charley/november com
From: Rahul Jain
Subject: Re: [CLOS] Ensuring a method exists
Date: 
Message-ID: <87bqoqmst7.fsf@nyct.net>
Christophe Rhodes <·····@cam.ac.uk> writes:

> No, it is an issue if you assume OO, of any form, is capable of
> expressing _any_ legitimate solution.  

Right, but we use Lisp. We are allowed to use any paradigm we want. Even
one we invented yesterday.

-- 
Rahul Jain
·····@nyct.net
Professional Software Developer, Amateur Quantum Mechanicist
From: Didier Verna
Subject: Re: [CLOS] Ensuring a method exists
Date: 
Message-ID: <muxlknt23jo.fsf@uzeb.lrde.epita.fr>
Christophe Rhodes wrote:

> I'll make the point again, since it didn't seem to get through in this
> discussion first time: just as we, having CLOS, recognize that C++'s
> object-oriented model is not the only possible one, can we please
> recognize that CLOS's object-oriented model is not a superset of all
> possible ones?

        Amen to that !

-- 
Check out my new jazz CD on http://www.didierverna.com/ !

Didier Verna	EPITA / LRDE, 14-16 rue Voltaire   Tel.+33 (1) 44 08 01 85
             	94276 Le Kremlin-Bic�tre, France   Fax.+33 (1) 53 14 59 22
From: Pascal Costanza
Subject: Re: [CLOS] Ensuring a method exists
Date: 
Message-ID: <4okq79Ff98c8U1@individual.net>
Rahul Jain wrote:
> Didier Verna <······@lrde.epita.fr> writes:
> 
>> Rahul Jain <·····@nyct.net> wrote:
>>
>>> You shouldn't be subclassing something if you don't want to get its
>>> functionality as default.
>> Sorry ? Consider the classic binary method example Point <- ColorPoint with
>> the point= function. ColorPoint *is* a subclass of Point, and *no*, I don't
>> want the implementation of point= for Point as the default functionality in
>> ColorPoint. I want to be sure that there is an implementation of point= for
>> both classes.
> 
> Equality is not an OO concept. You should not be using a g-f to
> determine equality. 

Says who?

> What would it mean for me to compare a point to a
> color-point? And I mean OO in the polymorphic sense, not the
> encapsulation sense.

Comparing a point to a color-point could have different meanings 
depending on context. I can imagine situations in which a default color 
is assumed for non-color points. I can also imagine situations in which 
the color is simply ignored. Even throwing a dedicated exception can be 
a well-defined behavior, especially with the condition handling system 
in CL.

> There's a reason why the equality operators in CL are not g-fs.

The equality operators in CL are generic in the sense that they are 
applicable for several types. You just can't define methods on them (and 
even that is not a given, since the CL spec allows implementations to 
provide all plain functions as CLOS generic functions).

>>> My library just allows a declaration of what a class conforming to a
>>> protocol should support and a function to test whether it has gotten to that
>>> point after you've loaded all appropriate code.
>>         How much control do you have on the time at which the check is
>> performed ?
> 
> You call it explicitly. Total control. Total responsibility. Of course,
> this is necessary in a dynamic lanaguage, because the "validity" of the
> code according to some criteria changes as definitons are added,
> modified, and removed from the system.
> 
> It won't help you with trying to change the way the applicable method
> list is computed, tho. It just checks that there exists an applicable
> method. It's also not going to inspect the code of each method to make
> sure that every time it calls call-next-method, there will be a next
> method to call. Not sure I could do that in a way that avoids false
> negatives anyway.

You can't, due to Rice's Theorem.


Pascal

-- 
My website: http://p-cos.net
Common Lisp Document Repository: http://cdr.eurolisp.org
Closer to MOP & ContextL: http://common-lisp.net/project/closer/
From: Rahul Jain
Subject: Re: [CLOS] Ensuring a method exists
Date: 
Message-ID: <877izemsel.fsf@nyct.net>
Pascal Costanza <··@p-cos.net> writes:

> Rahul Jain wrote:
>> Equality is not an OO concept. You should not be using a g-f to
>> determine equality.
>
> Says who?

Says me. ;)

But seriously. Equality is not just inherited. Note that I qualified my
use of OO below. It's fine to compare objects, just not in a way that
gets inherited by subclasses.

>> What would it mean for me to compare a point to a
>> color-point? And I mean OO in the polymorphic sense, not the
>> encapsulation sense.
>
> Comparing a point to a color-point could have different meanings
> depending on context. I can imagine situations in which a default color
> is assumed for non-color points. I can also imagine situations in which
> the color is simply ignored. Even throwing a dedicated exception can be
> a well-defined behavior, especially with the condition handling system
> in CL.

Right, I tried to make that point before when I described what _I_ would
expect a point= function to do. Of course, all such discussions are
mental masturbation because what really matters is what a specific
application wants to compare. But I don't see how that implies that g-fs
are the way to implement such (a) function(s). In fact, I would think
that it would indicate that g-fs are the wrong way to do it because it
implies that such operators can be arbitrarily augmented by other
libraries. This may not result in expected behavior in all applications.

>> There's a reason why the equality operators in CL are not g-fs.
>
> The equality operators in CL are generic in the sense that they are
> applicable for several types. You just can't define methods on them (and
> even that is not a given, since the CL spec allows implementations to
> provide all plain functions as CLOS generic functions).

Right. I don't like equal or equalp for that exact reason. They're just
a mishmash of other equality operators on specific types. There's no
reason that specific combination should be preferred over any other. I
consider them to be historical artifacts.

-- 
Rahul Jain
·····@nyct.net
Professional Software Developer, Amateur Quantum Mechanicist
From: Pascal Costanza
Subject: Re: [CLOS] Ensuring a method exists
Date: 
Message-ID: <4olajtFf4fjiU1@individual.net>
Rahul Jain wrote:
> Pascal Costanza <··@p-cos.net> writes:
> 
>> Rahul Jain wrote:
>>> Equality is not an OO concept. You should not be using a g-f to
>>> determine equality.
>> Says who?
> 
> Says me. ;)

;)

> But seriously. Equality is not just inherited. Note that I qualified my
> use of OO below. It's fine to compare objects, just not in a way that
> gets inherited by subclasses.
> 
>>> What would it mean for me to compare a point to a
>>> color-point? And I mean OO in the polymorphic sense, not the
>>> encapsulation sense.
>> Comparing a point to a color-point could have different meanings
>> depending on context. I can imagine situations in which a default color
>> is assumed for non-color points. I can also imagine situations in which
>> the color is simply ignored. Even throwing a dedicated exception can be
>> a well-defined behavior, especially with the condition handling system
>> in CL.
> 
> Right, I tried to make that point before when I described what _I_ would
> expect a point= function to do. Of course, all such discussions are
> mental masturbation because what really matters is what a specific
> application wants to compare. But I don't see how that implies that g-fs
> are the way to implement such (a) function(s). In fact, I would think
> that it would indicate that g-fs are the wrong way to do it because it
> implies that such operators can be arbitrarily augmented by other
> libraries. This may not result in expected behavior in all applications.

I think generic functions can be appropriate, but I agree with you that 
they are probably not sufficient the way they are.

I said "depending on context" for a reason: I think something like 
dynamically scoped functions or ContextL can be of use here. For 
example, the different cases could be captured in different 
ContextL-layers and then selected appropriately.

I haven't tried this yet for comparison functions, so take this with a 
grain of salt.

But if it turns out that it could work like that, that would actually be 
an acknowledgment of Christophe's position as well. OOP may not be 
appropriate for such tasks yet, but this could be because we still don't 
have OOP systems that are general enough. (That's not what he said, but 
that's roughly how I understand him. And it resonates with my point of 
view... ;)

>>> There's a reason why the equality operators in CL are not g-fs.
>> The equality operators in CL are generic in the sense that they are
>> applicable for several types. You just can't define methods on them (and
>> even that is not a given, since the CL spec allows implementations to
>> provide all plain functions as CLOS generic functions).
> 
> Right. I don't like equal or equalp for that exact reason. They're just
> a mishmash of other equality operators on specific types. There's no
> reason that specific combination should be preferred over any other. I
> consider them to be historical artifacts.

OK, that's indeed arguable.


Pascal

-- 
My website: http://p-cos.net
Common Lisp Document Repository: http://cdr.eurolisp.org
Closer to MOP & ContextL: http://common-lisp.net/project/closer/
From: Rahul Jain
Subject: Re: [CLOS] Ensuring a method exists
Date: 
Message-ID: <871wpml9xa.fsf@nyct.net>
Pascal Costanza <··@p-cos.net> writes:

> I said "depending on context" for a reason: I think something like
> dynamically scoped functions or ContextL can be of use here. For
> example, the different cases could be captured in different
> ContextL-layers and then selected appropriately.

I don't know if dynamically scoping the equality is the right thing to
do. You don't want your idea of equality for this current situation to
propagate into some other library whose function you happen to be
calling.

Not sure how ContextL really works. Maybe someone can explain it to me
at 7 today. :)

-- 
Rahul Jain
·····@nyct.net
Professional Software Developer, Amateur Quantum Mechanicist
From: Pascal Costanza
Subject: Re: [CLOS] Ensuring a method exists
Date: 
Message-ID: <4olekbFf9vr6U1@individual.net>
Rahul Jain wrote:
> Pascal Costanza <··@p-cos.net> writes:
> 
>> I said "depending on context" for a reason: I think something like
>> dynamically scoped functions or ContextL can be of use here. For
>> example, the different cases could be captured in different
>> ContextL-layers and then selected appropriately.
> 
> I don't know if dynamically scoping the equality is the right thing to
> do. You don't want your idea of equality for this current situation to
> propagate into some other library whose function you happen to be
> calling.

That's what the "grain of salt" bit was there for. ;)

But I see a potential chance that if this specified, that it could be 
handled reasonably.

> 
> Not sure how ContextL really works. Maybe someone can explain it to me
> at 7 today. :)
> 

-- 
My website: http://p-cos.net
Common Lisp Document Repository: http://cdr.eurolisp.org
Closer to MOP & ContextL: http://common-lisp.net/project/closer/
From: Didier Verna
Subject: Re: [CLOS] Ensuring a method exists
Date: 
Message-ID: <muxhcyh23de.fsf@uzeb.lrde.epita.fr>
Pascal Costanza wrote:

> Comparing a point to a color-point could have different meanings depending
> on context. I can imagine situations in which a default color is assumed for
> non-color points. I can also imagine situations in which the color is simply
> ignored. Even throwing a dedicated exception can be a well-defined behavior,
> especially with the condition handling system in CL.

        Amen to that too !

-- 
Check out my new jazz CD on http://www.didierverna.com/ !

Didier Verna	EPITA / LRDE, 14-16 rue Voltaire   Tel.+33 (1) 44 08 01 85
             	94276 Le Kremlin-Bic�tre, France   Fax.+33 (1) 53 14 59 22
From: Didier Verna
Subject: Re: [CLOS] Ensuring a method exists
Date: 
Message-ID: <muxpsd523ne.fsf@uzeb.lrde.epita.fr>
Rahul Jain <·····@nyct.net> wrote:

>> Rahul Jain <·····@nyct.net> wrote:
>
> Equality is not an OO concept. 

        Which equality are you talking about ? Which OO concept are you
talking about ? There is no such thing as equality or OO concept to me. There
are, however, some forms of equality I need to express, some forms of object
orientation I may use in this aim. 

Read again the definition of Point and point=, which /is/ a possible form of
equality, whatever you may think. Users of this class can extend the concept
of Point by subclassing, and provide the appropriate version of point= (very
easily BTW, since they only have to care about what has to be done locally in
the subclass they're creating), which will automatically inherit the needed
behavior from the superclasses. Well, that sounds pretty much OO to me.

The only thing is that I have additionnal constraints in the point= concept. 
Does this mean that OO is not the way ? No ("OO is not the way" doesn't make
any sense anyway). I just means that I need another form of OO. CLOS, by
itself, doesn't allow me to express the concept directly (but who said CLOS is
the panacea anyway ?). However, with a few lines of MOP tweaking, I'm able to
express the contrainsts in question. So I'm actually able to create a new
object system, just for that special concept I need to express, and even make
this OO system coexist with others in the same application. That should be an
Aha! moment for anyone realizing this for the first time.


All in all, why is this discussion going nowhere ? You seem to have a very
narrow-minded view of what OO is or should be[1], ditto for "equality". If you
don't want to acknowledge the fact that point= (the way I defined it, whatever
its name) is a form of equality, or that the way it is expressed (special
inheritance scheme + constraints) is a form of OO, then fine. That's just a
matter of vocabulary then. But I don't see what we have to discuss.

Or maybe, it's like the other poster who's so impressed with Santa Barbara's
principle (probably because it's theoretical and beautiful) that he wants to
stick to it blindly. I don't buy that either. As long as I can tweak the
language to suit my needs, I'm a happy lisper. And if what I do does not fit
such or such theory, well, maybe that's because we need a more complex theory
(we know we lack a bunch of them for dynamic languages anyway...).



Footnotes: 
[1]  this really puzzles me, coming from somebody who's an apparent lisper.

-- 
Check out my new jazz CD on http://www.didierverna.com/ !

Didier Verna	EPITA / LRDE, 14-16 rue Voltaire   Tel.+33 (1) 44 08 01 85
             	94276 Le Kremlin-Bic�tre, France   Fax.+33 (1) 53 14 59 22
From: Pascal Costanza
Subject: Re: [CLOS] Ensuring a method exists
Date: 
Message-ID: <4omnfaFeoq4oU1@individual.net>
Didier Verna wrote:

> As long as I can tweak the
> language to suit my needs, I'm a happy lisper. And if what I do does not fit
> such or such theory, well, maybe that's because we need a more complex theory
> (we know we lack a bunch of them for dynamic languages anyway...).

Indeed. Computer science seems to be the only science where theory 
invalidates evidence, and not the other way around. ;)


Pascal

-- 
My website: http://p-cos.net
Common Lisp Document Repository: http://cdr.eurolisp.org
Closer to MOP & ContextL: http://common-lisp.net/project/closer/
From: Rahul Jain
Subject: Re: [CLOS] Ensuring a method exists
Date: 
Message-ID: <87irixjrpo.fsf@nyct.net>
Didier Verna <······@lrde.epita.fr> writes:

> All in all, why is this discussion going nowhere ? You seem to have a very
> narrow-minded view of what OO is or should be[1], ditto for "equality".

Because I have a broad-minded view of what programming should be. There
is more to programming than OO. If the concept fits the problem, use it. 
If not, use a different one. This is Lisp, not Java or C++. We don't see
thumbs everywhere.

-- 
Rahul Jain
·····@nyct.net
Professional Software Developer, Amateur Quantum Mechanicist
From: Jack Unrue
Subject: Re: [CLOS] Ensuring a method exists
Date: 
Message-ID: <0bvci29q4fe5i6fve1d0ajel9a381kkjd3@4ax.com>
On Fri, 06 Oct 2006 11:29:41 +0200, Didier Verna <······@lrde.epita.fr> wrote:
>
> Or maybe, it's like the other poster who's so impressed with Santa Barbara's
> principle (probably because it's theoretical and beautiful) that he wants to
> stick to it blindly.

At least in this case, there is a theoretical basis I can point to
in order to back up my opinion. I'm not always that lucky :-)

BTW, Pascal made the point about following aesthetics blindly, but
actually I've written plenty of ugly code. So it's not as though I
am unable to appreciate the practicality of any situation.

> I don't buy that either. As long as I can tweak the language to suit my
> needs, I'm a happy lisper. And if what I do does not fit such or such
> theory, well, maybe that's because we need a more complex theory
> (we know we lack a bunch of them for dynamic languages anyway...).

If new theory gets developed, I'll be happy to evaluate it for myself
and see if my opinions should change. I'm not an academic, but I try
to read research papers as much as I can (across different fields),
for inspiration if nothing else.

-- 
Jack Unrue
From: Wade Humeniuk
Subject: Re: [CLOS] Ensuring a method exists
Date: 
Message-ID: <zfvSg.13$N4.12@clgrps12>
Didier Verna wrote:
>         Hi !
> 
> Suppose I have:
> 
> (defgeneric foo (a b) ...)
> 
> (defclass base () ...)
> (defmethod foo ((a base) (b base)) ...)
> 
> 
> 
> I'd like to ensure that if somebody writes a derived class:
> 
> (defclass derived (base) ...)
> 
> she also provides a method for this class:
> 
> (defmethod foo ((a derived) (b derived)) ...)
> 
> 

If someone defines the DERIVED class, how long do you give them
to define the foo method?  The first time foo is called with
and instance of derived??  Or can they use the inherited method
until they determine how they need to specialize on derived.
What you are asking flies in the face of interactive dynamic
development.  You need the fluidity/imprecision during development.
Maybe when "everything is finished" then you can run a consistency
check to see that everything is "proper".

I think I know what you want, if you could be more specific
as what you want to achieve. (is it, I don't trust the programmers
to do the right thing, or, the system is so large I want some
automated check to ease my mind, or, there is a an absolute
technical reason (that I am too daft to see at the moment)).

Wade
From: Ken Tilton
Subject: Re: [CLOS] Ensuring a method exists
Date: 
Message-ID: <gDySg.4$B67.3@newsfe09.lga>
Wade Humeniuk wrote:
> Didier Verna wrote:
> 
>>         Hi !
>>
>> Suppose I have:
>>
>> (defgeneric foo (a b) ...)
>>
>> (defclass base () ...)
>> (defmethod foo ((a base) (b base)) ...)
>>
>>
>>
>> I'd like to ensure that if somebody writes a derived class:
>>
>> (defclass derived (base) ...)
>>
>> she also provides a method for this class:
>>
>> (defmethod foo ((a derived) (b derived)) ...)
>>
>>
> 
> If someone defines the DERIVED class, how long do you give them
> to define the foo method?  The first time foo is called with
> and instance of derived??  Or can they use the inherited method
> until they determine how they need to specialize on derived.
> What you are asking flies in the face of interactive dynamic
> development.  You need the fluidity/imprecision during development.
> Maybe when "everything is finished" then you can run a consistency
> check to see that everything is "proper".
> 
> I think I know what you want, if you could be more specific
> as what you want to achieve. 

Nothing. Apparently Didier and his buddy were in a pub early one morning 
and started arguing over whether Lisp could do anything C++ could do. As 
all the girls moved away from them, they hotspotted into c.l.l and made 
that post...

hth, kenny


-- 
Cells: http://common-lisp.net/project/cells/

"I'll say I'm losing my grip, and it feels terrific."
    -- Smiling husband to scowling wife, New Yorker cartoon
From: Didier Verna
Subject: Re: [CLOS] Ensuring a method exists
Date: 
Message-ID: <muxbqp181er.fsf@uzeb.lrde.epita.fr>
Ken Tilton <·········@gmail.com> wrote:

> Nothing. Apparently Didier and his buddy were in a pub early one morning and
> started arguing over whether Lisp could do anything C++ could do. As all the
> girls moved away from them, they hotspotted into c.l.l and made that post...

Now I'm sure of it. The Ken Tilton of comp.lang.lisp, the David Kastrup of
comp.text.tex and the JWZ of XEmacs'old days are the same person !

-- 
Check out my new jazz CD on http://www.didierverna.com/ !

Didier Verna	EPITA / LRDE, 14-16 rue Voltaire   Tel.+33 (1) 44 08 01 85
             	94276 Le Kremlin-Bic�tre, France   Fax.+33 (1) 53 14 59 22
From: Rahul Jain
Subject: Re: [CLOS] Ensuring a method exists
Date: 
Message-ID: <87ven12pjr.fsf@nyct.net>
Didier Verna <······@lrde.epita.fr> writes:

> Ken Tilton <·········@gmail.com> wrote:
>
>> Nothing. Apparently Didier and his buddy were in a pub early one morning and
>> started arguing over whether Lisp could do anything C++ could do. As all the
>> girls moved away from them, they hotspotted into c.l.l and made that post...
>
> Now I'm sure of it. The Ken Tilton of comp.lang.lisp, the David Kastrup of
> comp.text.tex and the JWZ of XEmacs'old days are the same person !

Now you've offended me! How DARE you put Kenny and JWZ on the same
level. You're sick. A psychopath.

-- 
Rahul Jain
·····@nyct.net
Professional Software Developer, Amateur Quantum Mechanicist
From: Didier Verna
Subject: Re: [CLOS] Ensuring a method exists
Date: 
Message-ID: <muxlknw4kfh.fsf@uzeb.lrde.epita.fr>
Rahul Jain <·····@nyct.net> wrote:

>> Now I'm sure of it. The Ken Tilton of comp.lang.lisp, the David Kastrup of
>> comp.text.tex and the JWZ of XEmacs'old days are the same person !
>
> Now you've offended me! How DARE you put Kenny and JWZ on the same
> level. You're sick. A psychopath.

:-)

-- 
Check out my new jazz CD on http://www.didierverna.com/ !

Didier Verna	EPITA / LRDE, 14-16 rue Voltaire   Tel.+33 (1) 44 08 01 85
             	94276 Le Kremlin-Bic�tre, France   Fax.+33 (1) 53 14 59 22
From: Pascal Costanza
Subject: Re: [CLOS] Ensuring a method exists
Date: 
Message-ID: <4nvvbtFbucgrU1@individual.net>
Wade Humeniuk wrote:
> Didier Verna wrote:
>>         Hi !
>>
>> Suppose I have:
>>
>> (defgeneric foo (a b) ...)
>>
>> (defclass base () ...)
>> (defmethod foo ((a base) (b base)) ...)
>>
>>
>>
>> I'd like to ensure that if somebody writes a derived class:
>>
>> (defclass derived (base) ...)
>>
>> she also provides a method for this class:
>>
>> (defmethod foo ((a derived) (b derived)) ...)
>>
>>
> 
> If someone defines the DERIVED class, how long do you give them
> to define the foo method?  The first time foo is called with
> and instance of derived??  Or can they use the inherited method
> until they determine how they need to specialize on derived.
> What you are asking flies in the face of interactive dynamic
> development.  You need the fluidity/imprecision during development.
> Maybe when "everything is finished" then you can run a consistency
> check to see that everything is "proper".

It seems to me that the latest possible stage to check this is when the 
applicable methods for some generic function call are determined. You 
can then just check whether the most specific primary method is 
specialized on exactly the classes of the arguments. This can be done in 
methods on compute-applicable-methods and 
compute-applicable-methods-using-classes.

It's also possible to do this in a user-defined method combination, but 
then you can only do the check as part of the execution of the effective 
method, whereas in c-a-m and c-a-m-u-c, once the check succeeds, it 
won't be checked again in subsequent calls of arguments of the same classes.


Pascal

-- 
My website: http://p-cos.net
Common Lisp Document Repository: http://cdr.eurolisp.org
Closer to MOP & ContextL: http://common-lisp.net/project/closer/
From: Wade Humeniuk
Subject: Re: [CLOS] Ensuring a method exists
Date: 
Message-ID: <qzHSg.46627$E67.21561@clgrps13>
Pascal Costanza wrote:
> Wade Humeniuk wrote:
>> If someone defines the DERIVED class, how long do you give them
>> to define the foo method?  The first time foo is called with
>> and instance of derived??  Or can they use the inherited method
>> until they determine how they need to specialize on derived.
>> What you are asking flies in the face of interactive dynamic
>> development.  You need the fluidity/imprecision during development.
>> Maybe when "everything is finished" then you can run a consistency
>> check to see that everything is "proper".
> 
> It seems to me that the latest possible stage to check this is when the 
> applicable methods for some generic function call are determined. You 
> can then just check whether the most specific primary method is 
> specialized on exactly the classes of the arguments. This can be done in 
> methods on compute-applicable-methods and 
> compute-applicable-methods-using-classes.
> 
> It's also possible to do this in a user-defined method combination, but 
> then you can only do the check as part of the execution of the effective 
> method, whereas in c-a-m and c-a-m-u-c, once the check succeeds, it 
> won't be checked again in subsequent calls of arguments of the same 
> classes.
> 

That is not what I meant.  In a dynamic environment
(defmethod foo ((a derived) (b derived)) ...) never has-to exist, or..
may exist then be undefined/redefined, or..  foo is redefined
to be a simple defun. Why does a program need
functional completeness?  Why cannot it be left unfinished?

The OP's motives are not clear to me (besides the possible
motive of mimicking C++ virtual classes).
If the intention is that specialzed foos have to be defined
for all subclasses , then this requirement can be overridden
by some smart-ass doing

(defmethod foo ((a derived) (b derived))
    (call-next-method))

Follows the letter of the law but not the intention.

Or...

(defmethod foo :around ((a derived) (b derived))
    (foo-on-you a b))

Wade
From: Rahul Jain
Subject: Re: [CLOS] Ensuring a method exists
Date: 
Message-ID: <87r6xp2pgd.fsf@nyct.net>
Wade Humeniuk <··················@telus.net> writes:

> (defmethod foo ((a derived) (b derived))
>    (call-next-method))
>
> Follows the letter of the law but not the intention.
>
> Or...
>
> (defmethod foo :around ((a derived) (b derived))
>    (foo-on-you a b))

And for even more fun:

(defmethod foo :around ((a derived) (b derived))
   (transmogrify (call-next-method)))

And that's not a made-up example. Look at AMOP's compute-slots.

-- 
Rahul Jain
·····@nyct.net
Professional Software Developer, Amateur Quantum Mechanicist
From: Jack Unrue
Subject: Re: [CLOS] Ensuring a method exists
Date: 
Message-ID: <036lh2hflgb3iq5godu470qpctmn2tjgqt@4ax.com>
On Wed, 27 Sep 2006 09:40:18 +0200, Didier Verna <······@lrde.epita.fr> wrote:
>
> I'd like to ensure that if somebody writes a derived class:
> 
> (defclass derived (base) ...)
> 
> she also provides a method for this class:
> 
> (defmethod foo ((a derived) (b derived)) ...)

Perhaps this constraint should be checked via a wrapper for
calling foo and use that where foo would normally be called
directly? Or use some aspect-oriented approach (maybe AspectL)?

-- 
Jack Unrue
From: Pascal Costanza
Subject: Re: [CLOS] Ensuring a method exists
Date: 
Message-ID: <4o00a7Fcd8mqU1@individual.net>
Jack Unrue wrote:
> On Wed, 27 Sep 2006 09:40:18 +0200, Didier Verna <······@lrde.epita.fr> wrote:
>> I'd like to ensure that if somebody writes a derived class:
>>
>> (defclass derived (base) ...)
>>
>> she also provides a method for this class:
>>
>> (defmethod foo ((a derived) (b derived)) ...)
> 
> Perhaps this constraint should be checked via a wrapper for
> calling foo and use that where foo would normally be called
> directly? Or use some aspect-oriented approach (maybe AspectL)?

A wrapper would have the disadvantage that the check would be done on 
each call.

And don't use AspectL for this. ;) Or better, don't use AspectL for 
anything serious. AspectL was an experiment to better understand AOP. 
Except for very few cases, all of AspectL's functionality is provided in 
better and safer ways in ContextL.

And no, ContextL probably also doesn't give you any advantages for this 
particular case. CLOS is already powerful enough here.


Pascal

-- 
My website: http://p-cos.net
Common Lisp Document Repository: http://cdr.eurolisp.org
Closer to MOP & ContextL: http://common-lisp.net/project/closer/
From: Rahul Jain
Subject: Re: [CLOS] Ensuring a method exists
Date: 
Message-ID: <87ven146fk.fsf@nyct.net>
Didier Verna <······@lrde.epita.fr> writes:

> I'd like to ensure that if somebody writes a derived class:
>
> (defclass derived (base) ...)
>
> she also provides a method for this class:
>
> (defmethod foo ((a derived) (b derived)) ...)

I have written a "protocols" library that allows you to declare this
requirement and provides a function (could be included in a unit test)
to check that the proper methods are implemented.

http://common-lisp.net/cgi-bin/viewcvs.cgi/protocols/?root=rjain-utils

-- 
Rahul Jain
·····@nyct.net
Professional Software Developer, Amateur Quantum Mechanicist