From: Pascal Costanza
Subject: Re: CLOS quiz question
Date: 
Message-ID: <5f6a6oF3au2foU1@mid.individual.net>
Madhu wrote:
> Helu
> 
> Let `f' be a generic function.  Is it possible to define n primary
> methods on f and construct a call to f such that all the n methods are
> applicable? 
> 
> The task is to say what `f' specializes on.  
> 
> Any insights welcome

Two methods are considered different by CLOS when they have different 
qualifiers and/or different specializers.

You could implement your own user-defined method combination, similar to 
progn, which takes an additional qualifier just to render the method 
different from other, otherwise similar methods. On top of that, that 
qualifier can be used as a name/reference to such a method.

There are plenty of examples how to implement your own method 
combinations in the HyperSpec.


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: Madhu
Subject: Re: CLOS quiz question
Date: 
Message-ID: <m31wfl25n9.fsf@robolove.meer.net>
* Pascal Costanza <···············@mid.individual.net> :
|> Let `f' be a generic function.  Is it possible to define n primary
|> methods on f and construct a call to f such that all the n methods are
|> applicable?
|>
| Two methods are considered different by CLOS when they have different
| qualifiers and/or different specializers.
|
| You could implement your own user-defined method combination, similar
| to progn, which takes an additional qualifier just to render the
| method different from other, otherwise similar methods. On top of
| that, that qualifier can be used as a name/reference to such a method.

This did the trick (in three lines).

Thanks Pascal, knew I could count on you
--
Madhu
From: Madhu
Subject: Re: CLOS quiz question
Date: 
Message-ID: <m37icy20s1.fsf@meer.net>
[Sorry for resurrecting this old thread, hope Pascal is around]

* Pascal Costanza <···············@mid.individual.net> :
Wrote on Fri, 06 Jul 2007 09:44:24 +0200:

| Madhu wrote:
|> Helu
|>
|> Let `f' be a generic function.  Is it possible to define n primary
|> methods on f and construct a call to f such that all the n methods are
|> applicable? 
|>
|> The task is to say what `f' specializes on.  
|>
|
| Two methods are considered different by CLOS when they have different
| qualifiers and/or different specializers.

Both Allegro and CMUCL signal errors, when calling a generic function,
when two methods have the same specialzers, even thought they have
different qualifiers.  Lispworks did not signal an error. [see eg below]

Is this mandated by the spec?

| You could implement your own user-defined method combination, similar
| to progn, which takes an additional qualifier just to render the
| method different from other, otherwise similar methods. On top of
| that, that qualifier can be used as a name/reference to such a method.

I had used:

(define-method-combination hooks ()
  ((methods identity))
  `(progn ,@(mapcar #'(lambda (method) `(call-method ,method)) methods)))

Which had worked on generic functions with an empty lambda list.
However defining two methods specialized on (t t):

(defgeneric barfoo  (x y) (:method-combination hooks))
(defmethod barfoo :pong (x y) (warn "BAR PONG"))
(defmethod barfoo :kong (x y) (warn "BAR KONG"))
(barfoo 10 20)

Signals an error [in CMUCL (also ACL but nor LW)]
   More than one method of type METHODS
   with the same specializers.
--
Madhu
From: Pascal Costanza
Subject: Re: CLOS quiz question
Date: 
Message-ID: <6b6pviF3b14pkU1@mid.individual.net>
Madhu wrote:
> [Sorry for resurrecting this old thread, hope Pascal is around]
> 
> * Pascal Costanza <···············@mid.individual.net> :
> Wrote on Fri, 06 Jul 2007 09:44:24 +0200:
> 
> | Madhu wrote:
> |> Helu
> |>
> |> Let `f' be a generic function.  Is it possible to define n primary
> |> methods on f and construct a call to f such that all the n methods are
> |> applicable? 
> |>
> |> The task is to say what `f' specializes on.  
> |>
> |
> | Two methods are considered different by CLOS when they have different
> | qualifiers and/or different specializers.
> 
> Both Allegro and CMUCL signal errors, when calling a generic function,
> when two methods have the same specialzers, even thought they have
> different qualifiers.  Lispworks did not signal an error. [see eg below]
> 
> Is this mandated by the spec?
> 
> | You could implement your own user-defined method combination, similar
> | to progn, which takes an additional qualifier just to render the
> | method different from other, otherwise similar methods. On top of
> | that, that qualifier can be used as a name/reference to such a method.
> 
> I had used:
> 
> (define-method-combination hooks ()
>   ((methods identity))
>   `(progn ,@(mapcar #'(lambda (method) `(call-method ,method)) methods)))
> 
> Which had worked on generic functions with an empty lambda list.
> However defining two methods specialized on (t t):
> 
> (defgeneric barfoo  (x y) (:method-combination hooks))
> (defmethod barfoo :pong (x y) (warn "BAR PONG"))
> (defmethod barfoo :kong (x y) (warn "BAR KONG"))
> (barfoo 10 20)
> 
> Signals an error [in CMUCL (also ACL but nor LW)]
>    More than one method of type METHODS
>    with the same specializers.

There is this ugly thing about method groups and roles in the 
description of define-method-combination.

The spec says: "Each specifier selects a subset of the applicable 
methods to play a particular role, either by matching their qualifiers 
against some patterns or by testing their qualifiers with a predicate. 
These method group specifiers define all method qualifiers that can be 
used with this type of method combination."

And later: "Note that two methods with identical specializers, but with 
different qualifiers, are not ordered by the algorithm described in Step 
2 of the method selection and combination process described in Section 
7.6.6 (Method Selection and Combination). Normally the two methods play 
different roles in the effective method because they have different 
qualifiers, and no matter how they are ordered in the result of Step 2, 
the effective method is the same. If the two methods play the same role 
and their order matters, an error is signaled. This happens as part of 
the qualifier pattern matching in define-method-combination."

Since you use 'identity as a predicate, your two methods appear in the 
same method group, so are considered to play the same role. Hence the error.

Did you try this?

(define-method-combination hooks ()
   ((methods *))
   ...)

It seems to me that the * pattern disables this method groups check, at 
least in some implementations.

But note that you indeed probably want a deterministic order between 
your methods. So maybe some more work is required 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: Madhu
Subject: Re: CLOS quiz question
Date: 
Message-ID: <m3ve0fz506.fsf@meer.net>
* Pascal Costanza <···············@mid.individual.net> :
Wrote on Tue, 10 Jun 2008 09:49:06 +0200:
|> |> Let `f' be a generic function.  Is it possible to define n primary
|> |> methods on f and construct a call to f such that all the n methods are
|> |> applicable? |>
|> |> The task is to say what `f' specializes on.  |>
|> |
|> | Two methods are considered different by CLOS when they have different
|> | qualifiers and/or different specializers.
|>
|> Both Allegro and CMUCL signal errors, when calling a generic function,
|> when two methods have the same specialzers, even thought they have
|> different qualifiers.  Lispworks did not signal an error. [see eg below]
|>
|> Is this mandated by the spec?
|>
|> | You could implement your own user-defined method combination, similar
|> | to progn, which takes an additional qualifier just to render the
|> | method different from other, otherwise similar methods. On top of
|> | that, that qualifier can be used as a name/reference to such a method.
|>
| There is this ugly thing about method groups and roles in the
| description of define-method-combination.
|
| The spec says: "Each specifier selects a subset of the applicable
| methods to play a particular role, either by matching their qualifiers
| against some patterns or by testing their qualifiers with a
| predicate. These method group specifiers define all method qualifiers
| that can be used with this type of method combination."
|
| And later: "Note that two methods with identical specializers, but
| with different qualifiers, are not ordered by the algorithm described
| in Step 2 of the method selection and combination process described in
| Section 7.6.6 (Method Selection and Combination). Normally the two
| methods play different roles in the effective method because they have
| different qualifiers, and no matter how they are ordered in the result
| of Step 2, the effective method is the same. If the two methods play
| the same role and their order matters, an error is signaled. This
| happens as part of the qualifier pattern matching in
| define-method-combination."

[example elided]

In the elided example there are two methods with identical specializers
in the same role (specified by the same method group specifier), but
order does not matter.

However IIUC there is no way presently to distinguish this case (where
order does not matter, vs. where order matters) in D-M-C.

| Since you use 'identity as a predicate, your two methods appear in the
| same method group, so are considered to play the same role. Hence the
| error.
|
| Did you try this?
|
| (define-method-combination hooks ()
|   ((methods *))
|   ...)

Yes, my initial implementation had used *, but it should not make a
difference to the point under consideration: There is still one role,
with more than one method in that method group, with the same
specifiers.

| It seems to me that the * pattern disables this method groups check,
| at least in some implementations.

In the implementations I tried, I did not discern any difference.  LW
did not signal an error while CMUCL and ACL did.

| But note that you indeed probably want a deterministic order between
| your methods. So maybe some more work is required here...

Note: When order does not matter, an abitrary ordering would be
acceptable [for me, speaking as the user] with perhaps the stipulation
that once decided, the ordering should not change.

My question was really whether we could get rid of the check which
signals the error -- but doing that would be tantamount to making the
assumption that the ordering of methods with the same specifiers in the
same role does NOT matter.  This seemed reasonable to me, but I suspect
others may have a different view.  

So perhaps a means to specify to D-M-C that ordering is irrerevant, and
an error should not be signalled would be easiest --- [To recap: without
this, even though CLOS treats two methods as different on the basis of
their qualifiers, one cannot use that distinction to solve the problem
stated at the start of this thread]

--
Madhu

PS pls to be excusing if I'm being too verbose :)
From: Pascal Costanza
Subject: Re: CLOS quiz question
Date: 
Message-ID: <6behklF3aq80jU1@mid.individual.net>
Madhu wrote:
> * Pascal Costanza <···············@mid.individual.net> :
> | Since you use 'identity as a predicate, your two methods appear in the
> | same method group, so are considered to play the same role. Hence the
> | error.
> |
> | Did you try this?
> |
> | (define-method-combination hooks ()
> |   ((methods *))
> |   ...)
> 
> Yes, my initial implementation had used *, but it should not make a
> difference to the point under consideration: There is still one role,
> with more than one method in that method group, with the same
> specifiers.
> 
> | It seems to me that the * pattern disables this method groups check,
> | at least in some implementations.
> 
> In the implementations I tried, I did not discern any difference.  LW
> did not signal an error while CMUCL and ACL did.

OK, the specification of define-method-combination is hard to digest, 
but I dug a bit deeper, and I think by now that your original attempt to 
use the identity predicate is correct, and that CMUCL and ACL are buggy.

The spec says: "Each specifier selects a subset of the applicable 
methods to play a particular role, /either/ by matching their qualifiers 
against some patterns /or/ by testing their qualifiers with a 
predicate." (Emphasis added by me.)

And later: "If the two methods play the same role and their order 
matters, an error is signaled. This happens as part of the qualifier 
pattern matching in define-method-combination." This should mean that 
testing with a predicate should not signal an error here.

There is also an example 'example-method-combination which uses a 
predicate positive-integer-qualifier-p, which would be incorrect in case 
the check would be done for such predicates as well.

So complain to your vendors.


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: Madhu
Subject: Re: CLOS quiz question
Date: 
Message-ID: <m363sdziph.fsf@meer.net>
* Pascal Costanza <···············@mid.individual.net> :
Wrote on Fri, 13 Jun 2008 08:15:40 +0200:

|> In the implementations I tried, I did not discern any difference.  LW
|> did not signal an error while CMUCL and ACL did.
|
| OK, the specification of define-method-combination is hard to digest,
| but I dug a bit deeper, and I think by now that your original attempt
| to use the identity predicate is correct, and that CMUCL and ACL are
| buggy.
|
| The spec says: "Each specifier selects a subset of the applicable
| methods to play a particular role, /either/ by matching their
| qualifiers against some patterns /or/ by testing their qualifiers with
| a predicate." (Emphasis added by me.)
|
| And later: "If the two methods play the same role and their order
| matters, an error is signaled. This happens as part of the qualifier
| pattern matching in define-method-combination." This should mean that
| testing with a predicate should not signal an error here.

Thanks Pascal.  The spec's wording did seem to indicate this. 
At the same time I think it would be better to understand the rationale
behind signaling the error, which is phrased in terms of "when their
order matters".  As I pointed out up-thread
<···················································@robolove.meer.net>
the notion of order is not made explicit, nor is it made clear who is
supposed to care about the order.

I was almost able to convince myself that the present behaviour of ACL
and CMUCL is consistent with the rationale that an error should be
signalled if, in the method group, an ordering of methods is not well
defined, [and an such an order is not well defined if there are 2 or
more methods with the same specializers.]  Using a predicate to select
the methods in the group seemed orthogonal to disclaiming order matters,
but I'm happy to accept that is exactly the what the spec is saying:
that no error will be signalled because order does not matter if you use
a predicate.

| There is also an example 'example-method-combination which uses a
| predicate positive-integer-qualifier-p, which would be incorrect in
| case the check would be done for such predicates as well.

They did not define any methods using the method combination, so the
case where the error is signalled is not covered, so this cant be called
incorrect.

| So complain to your vendors.

Maybe sometime later :)
Thanks again
--
Madhu
From: Pascal Costanza
Subject: Re: CLOS quiz question
Date: 
Message-ID: <6bhfmcF3b5b5aU1@mid.individual.net>
Madhu wrote:
> * Pascal Costanza <···············@mid.individual.net> :
> Wrote on Fri, 13 Jun 2008 08:15:40 +0200:
> 
> |> In the implementations I tried, I did not discern any difference.  LW
> |> did not signal an error while CMUCL and ACL did.
> |
> | OK, the specification of define-method-combination is hard to digest,
> | but I dug a bit deeper, and I think by now that your original attempt
> | to use the identity predicate is correct, and that CMUCL and ACL are
> | buggy.
> |
> | The spec says: "Each specifier selects a subset of the applicable
> | methods to play a particular role, /either/ by matching their
> | qualifiers against some patterns /or/ by testing their qualifiers with
> | a predicate." (Emphasis added by me.)
> |
> | And later: "If the two methods play the same role and their order
> | matters, an error is signaled. This happens as part of the qualifier
> | pattern matching in define-method-combination." This should mean that
> | testing with a predicate should not signal an error here.
> 
> Thanks Pascal.  The spec's wording did seem to indicate this. 
> At the same time I think it would be better to understand the rationale
> behind signaling the error, which is phrased in terms of "when their
> order matters".  As I pointed out up-thread
> <···················································@robolove.meer.net>
> the notion of order is not made explicit, nor is it made clear who is
> supposed to care about the order.
> 
> I was almost able to convince myself that the present behaviour of ACL
> and CMUCL is consistent with the rationale that an error should be
> signalled if, in the method group, an ordering of methods is not well
> defined, [and an such an order is not well defined if there are 2 or
> more methods with the same specializers.]  Using a predicate to select
> the methods in the group seemed orthogonal to disclaiming order matters,
> but I'm happy to accept that is exactly the what the spec is saying:
> that no error will be signalled because order does not matter if you use
> a predicate.

Well, at least this is how I interpret it. However, it could be 
interpreted differently, so this is a bit shaky.

But: I have found a different passage in the description of 
define-method-combination which is much stronger:

"The use of method group specifiers provides a convenient syntax to 
select methods, to divide them among the possible roles, and to perform 
the necessary error checking. It is possible to perform further 
filtering of methods in the body forms [...]. It is also possible to 
bypass the method group specifier mechanism and do everything in the 
body forms. This is accomplished by writing a single method group with * 
as its only qualifier-pattern; the variable is then bound to a list of 
all of the applicable methods, in most-specific-first order."

So this is clear and unambiguous statement that this kind of error 
checking shouldn't happen in this case.

> | There is also an example 'example-method-combination which uses a
> | predicate positive-integer-qualifier-p, which would be incorrect in
> | case the check would be done for such predicates as well.
> 
> They did not define any methods using the method combination, so the
> case where the error is signalled is not covered, so this cant be called
> incorrect.

OK, right.

> | So complain to your vendors.
> 
> Maybe sometime later :)

:)



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/