Re: colored point redux (was: Re: What _is_ exciting about generic functions vs. message sending...)
Pascal Costanza <[email protected]> Sat, 24 Feb 2007 22:16:08 +0100
| Newsgroups | gmane.comp.lang.lightweight |
|---|---|
| Message-ID | <[email protected]> |
On 24 Feb 2007, at 21:56, Vadim Nasardinov wrote:
> On Saturday 24 February 2007 11:37, Pascal Costanza wrote:
>> This whole discussion about naming issues has deteriorated. I am
>> sorry about this because I have taken a part in that. Now, I'd like
>> to make an attempt to get this discussion back on track.
>>
>> Here are two or three examples what generic functions buy you:
>>
>> 1) Assume the standard OOP example of points and how to compare
>> points. Here is an implementation in CLOS:
>>
>> (defclass point ()
>> ((x :initarg :x :reader x)
>> (y :initarg :y :reader y)))
>>
>> (defclass color-point (point)
>> ((c :initarg :color :reader color)))
>>
>> (defmethod eqv ((obj1 point) (obj2 point))
>> (and (eql (x obj1) (x obj2))
>> (eql (y obj1) (y obj2))))
>>
>> (defmethod eqv ((obj1 color-point) (obj2 color-point))
>> (and (call-next-method)
>> (eql (color obj1) (color obj2))))
>>
>> All the implementations in single-dispatch languages I have seen are
>> ugly and amount to simulating multiple dispatch.
>
> Ah, the venerable the "colored point" example. I know we've been
> through this before:
>
> http://people.csail.mit.edu/gregs/ll1-discuss-archive-html/
> msg03953.html
> http://people.csail.mit.edu/gregs/ll1-discuss-archive-html/
> msg03983.html
> http://people.csail.mit.edu/gregs/ll1-discuss-archive-html/
> msg04068.html
> http://people.csail.mit.edu/gregs/ll1-discuss-archive-html/
> msg04073.html
>
> ... but here's the thing. I like my EQV relationship to be
>
> (a) Reflexive (check)
> (b) Symmetric (check)
> (c) Transitive (???)
[...]
> No transitivity.
>
> Don't get me wrong. I do appreciate the fact that broken code can be
> much terser in Lisp than it is in Java. That _is_ very exciting.
Well, I haven't given you the specification, so how do you know that
the code was wrong for my purposes? ;)
But thanks for asking:
(defclass point ()
((x :initarg :x :reader x)
(y :initarg :y :reader y)))
(defclass color-point (point)
((c :initarg :color :reader color)))
(defgeneric eqv (obj1 obj2)
(:method-combination and)
(:method and (obj1 obj2)
(eql (class-of obj1) (class-of obj2))))
(defmethod eqv and ((obj1 point) (obj2 point))
(and (eql (x obj1) (x obj2))
(eql (y obj1) (y obj2))))
(defmethod eqv and ((obj1 color-point) (obj2 color-point))
(eql (color obj1) (color obj2)))
(defun compare (point-name1 point1 point-name2 point2)
(format t "eqv(~A ~A): ~A~%" point-name1 point-name2 (eqv point1
point2)))
CL-USER 1 > (let
((p (make-instance 'point :x 1 :y 1))
(p-red (make-instance 'color-point :x 1 :y
1 :color 'red))
(p-blue (make-instance 'color-point :x 1 :y
1 :color 'blue)))
(compare "p-red" p-red "p" p)
(compare "p" p "p-blue" p-blue)
(compare "p-red" p-red "p-blue" p-blue))
eqv(p-red p): NIL
eqv(p p-blue): NIL
eqv(p-red p-blue): NIL
NIL
Better?
Pascal
--
Pascal Costanza, mailto:[email protected], http://p-cos.net
Vrije Universiteit Brussel, Programming Technology Lab
Pleinlaan 2, B-1050 Brussel, Belgium