From: Chaitanya Gupta
Subject: Why is EQL specializer evaluated only once?
Date: 
Message-ID: <f48hfe$bkk$1@registered.motzarella.org>
CLHS 7.6.2 says...

> (eql form)
> 
> denotes a parameter specializer which satisfies the type specifier
> (eql object), where object is the result of evaluating form. The form
> form is evaluated in the lexical environment in which the
> method-defining form is evaluated. Note that form is evaluated only
> once, at the time the method is defined, not each time the generic
> function is called.


My question is, why should form be evaluated only once? What are the 
benefits of evaluating form at the time defmethod is defined over 
evaluating it each time the generic function is called?

IMHO, evaluating it at the time the function is called is better than 
evaluating only once. But since I know so little, can anyone explain 
what are the flaws of this approach? Or was it an arbitrary choice to 
use the other one?

Thanks,

Chaitanya

From: Barry Margolin
Subject: Re: Why is EQL specializer evaluated only once?
Date: 
Message-ID: <barmar-807A49.09020107062007@comcast.dca.giganews.com>
In article <············@registered.motzarella.org>,
 Chaitanya Gupta <····@chaitanyagupta.com> wrote:

> CLHS 7.6.2 says...
> 
> > (eql form)
> > 
> > denotes a parameter specializer which satisfies the type specifier
> > (eql object), where object is the result of evaluating form. The form
> > form is evaluated in the lexical environment in which the
> > method-defining form is evaluated. Note that form is evaluated only
> > once, at the time the method is defined, not each time the generic
> > function is called.
> 
> 
> My question is, why should form be evaluated only once? What are the 
> benefits of evaluating form at the time defmethod is defined over 
> evaluating it each time the generic function is called?

Performance.  Method dispatch is typically implemented using hash 
tables, and this would require that all the EQL specializers be 
evaluated every time you call the generic function.

Also, what happens if two of them evaluate to the same thing?  At method 
definition time it can simply replace the old method (perhaps with a 
warning if the forms aren't similar), but at call time there's no 
obvious way to specify priority.

-- 
Barry Margolin, ······@alum.mit.edu
Arlington, MA
*** PLEASE post questions in newsgroups, not directly to me ***
*** PLEASE don't copy me on replies, I'll read them in the group ***
From: Kent M Pitman
Subject: Re: Why is EQL specializer evaluated only once?
Date: 
Message-ID: <uvedzhp8n.fsf@nhplace.com>
Chaitanya Gupta <····@chaitanyagupta.com> writes:

> CLHS 7.6.2 says...
> 
> > (eql form)
> > denotes a parameter specializer which satisfies the type specifier
> > (eql object), where object is the result of evaluating form. The form
> > form is evaluated in the lexical environment in which the
> > method-defining form is evaluated. Note that form is evaluated only
> > once, at the time the method is defined, not each time the generic
> > function is called.
> 
> My question is, why should form be evaluated only once? What are the
> benefits of evaluating form at the time defmethod is defined over
> evaluating it each time the generic function is called?

Well, if you do that, you are talking about a potentially enormous
additional cost in dispatch time.  The user is already capable of
writing something that does runtime dispatch by just making a regular
function and doing arbitrary processing and dispatch on the argument.
What an object system provides, at its core, is efficient dispatch and
modular definition.  

Making the form evaluate at call time would thwart the ability to do
hashed indexing or some other clever strategy based on examining the
space of fixed objects over which one is indexing, it's just not worth
it for the object system to do that.

And as for modular definition, that also means modular redefinition.
This is more subtle, but you should note that it would be hard to tell
when you had redefined something or how to order the definitions.  For
example, suppose you've done:

 (defmethod foo ((x (eql *foo*))) x)
 (defmethod foo ((x (eql *bar*))) (list x))

where, unlike actual CL, *foo* and *bar* are evaluated at call time.
How would you know if these were two different methods, one redefining
the other, or if they were two different cases for the same method?

> IMHO, evaluating it at the time the function is called is better than
> evaluating only once. But since I know so little, can anyone explain
> what are the flaws of this approach? Or was it an arbitrary choice to
> use the other one?

I suspect (though I wasn't in on the actual discussion leading to this
decision, I had seen some similar discussions in other arenas) the choice
to evaluate them at all was a grudging accommodation to do the fact that
if you're going to case on an arbitrary object, some of which have no read
syntax, you have to construct them.  That leaves you either using #. or
else evaluating an expression, and #. tends to be something that while we
support it, we don't want to make central to programming.

And once you've admitted that some evaluation will happen, the issue of
redefinition becomes central.

So it's probably the result of constraint analysis that led to pretty much
only one rational conclusion.
From: Chaitanya Gupta
Subject: Re: Why is EQL specializer evaluated only once?
Date: 
Message-ID: <f48t7i$81q$1@registered.motzarella.org>
Chaitanya Gupta wrote:
> CLHS 7.6.2 says...
> 
>> (eql form)
>>
>> denotes a parameter specializer which satisfies the type specifier
>> (eql object), where object is the result of evaluating form. The form
>> form is evaluated in the lexical environment in which the
>> method-defining form is evaluated. Note that form is evaluated only
>> once, at the time the method is defined, not each time the generic
>> function is called.
> 


Just realized the context might not be so obvious from the above 
paragraph alone. Its related to defmethod and specialized lambda lists. 
Here's the relevant link from the hyperspec - 
http://www.lispworks.com/documentation/HyperSpec/Body/07_fb.htm

Chaitanya
From: Pascal Costanza
Subject: Re: Why is EQL specializer evaluated only once?
Date: 
Message-ID: <5csbegF30uriuU1@mid.individual.net>
Chaitanya Gupta wrote:
> CLHS 7.6.2 says...
> 
>> (eql form)
>>
>> denotes a parameter specializer which satisfies the type specifier
>> (eql object), where object is the result of evaluating form. The form
>> form is evaluated in the lexical environment in which the
>> method-defining form is evaluated. Note that form is evaluated only
>> once, at the time the method is defined, not each time the generic
>> function is called.
> 
> 
> My question is, why should form be evaluated only once? What are the 
> benefits of evaluating form at the time defmethod is defined over 
> evaluating it each time the generic function is called?
> 
> IMHO, evaluating it at the time the function is called is better than 
> evaluating only once. But since I know so little, can anyone explain 
> what are the flaws of this approach? Or was it an arbitrary choice to 
> use the other one?

The idea of object-oriented programming is that you can associate 
methods with objects, such that when you send a message, an appropriate 
method will be selected and executed based on what object you send the 
message to. Generalizations of this idea include that you can associate 
methods with classes (sets of similar objects), or in multiple dispatch 
systems, associate methods with several objects and/or several classes 
at the same time.

In class-based object-oriented languages, you can (typically) 
non-ambiguously refer to classes via their names. That's why it's 
sufficient to mention class names as specializers in CLOS method 
definitions. However, you typically cannot refer to objects via some 
naming mechanism because objects are typically first-class values only. 
So the only way to determine what object to specialize a method on is to 
give an expression that evaluates to such an object.

However, the link between methods and their objects (and classes) is a 
static one, unless explicitly redefined. That's why these expressions 
are always only evaluated once. It's not the expression that counts but 
the object(s) on which a method will eventually be defined.


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: Kent M Pitman
Subject: Re: Why is EQL specializer evaluated only once?
Date: 
Message-ID: <uhcpjudvv.fsf@nhplace.com>
Pascal Costanza <··@p-cos.net> writes:

> However, the link between methods and their objects (and classes) is a
> static one, unless explicitly redefined. That's why these expressions
> are always only evaluated once. It's not the expression that counts
> but the object(s) on which a method will eventually be defined.

Actually, there's another view of this in which it's evaluated not at all,
and that's perhaps the better model... or, at least, an alternate model.
That is, to say that the evaluation is _incidental_ to "teeing up" (in the
sense of a golf metaphor) the method definition, rather than _intrinsic_
to the definition process.

Just as Lisp is defined in terms of list structure, not character
syntax, so too CLOS can be thought of as defined in terms of object
relations, not list structure.  So while there is an evaluation that
yields the object in question, the fact of the MOP and the whole model
of how method structures are set up allows another view in which the
macro expands into calls to functions that, in this case, do some
evaluation in order to achieve the actual arguments which really
become the subject of the relational structure that is never evaluated
at the level of the object system--that is, it is evaluated "on the
way to" the object system in the same sense as the arguments to a
function are evaluated by the evaluator, and yet the action of the
APPLY function does not really involve any notion of evaluation.
So if you can understand why one might say of this:

 (let ((x '(a a)))
   (apply #'equal x))

that "there was no argument evaluation involved in the application of equal",
or if you can understand why it's proper to say that in

 (+ 3 5)
 => 8

"there was no call to print" _even though_ obviously print does get
called somewhere or you wouldn't see the 8, then in that same
specialized sense sense, you can understand why in at least some view
you could say there is no argument evaluatino involved in adding EQL
methods.

I'm not sure if that's helpful or not, but it occurred to me that maybe 
thinking of it as "no evaluation" rather than "only one evaluation" might
be emotionally more satisfying for some people.
From: Vassil Nikolov
Subject: Re: Why is EQL specializer evaluated only once?
Date: 
Message-ID: <kaabvazlo1.fsf@localhost.localdomain>
On 08 Jun 2007 03:03:16 -0400, Kent M Pitman <······@nhplace.com> said:
| ...
| I'm not sure if that's helpful or not,

  It must have been, especially with the analogies to APPLY and to the
  P in REPL.  (How can we get it to an FAQ?)

  I (think I) could even figure out, from the context, what "teeing
  up" meant.

| but it occurred to me that maybe 
| thinking of it as "no evaluation" rather than "only one evaluation" might
| be emotionally more satisfying for some people.

  As far as I remember, when I first read about EQL specializers, I
  wasn't surprised that they were not evaluated at method dispatch
  time---I was surprised that they were evaluated at all (at method
  definition time), so to me, it is not "only one evaluation", but
  "one whole evaluation" (which is, of course, incidental, as Kent
  explained).

  ---Vassil.


-- 
The truly good code is the obviously correct code.
From: Chaitanya Gupta
Subject: Re: Why is EQL specializer evaluated only once?
Date: 
Message-ID: <f4blsb$h6j$1@registered.motzarella.org>
Kent M Pitman wrote:
> 
> Just as Lisp is defined in terms of list structure, not character
> syntax, so too CLOS can be thought of as defined in terms of object
> relations, not list structure.  So while there is an evaluation that
> yields the object in question, the fact of the MOP and the whole model
> of how method structures are set up allows another view in which the
> macro expands into calls to functions that, in this case, do some
> evaluation in order to achieve the actual arguments which really
> become the subject of the relational structure that is never evaluated
> at the level of the object system--that is, it is evaluated "on the
> way to" the object system

I was breaking my head around this for sometime, but I think I've got 
what you mean.

> in the same sense as the arguments to a
> function are evaluated by the evaluator, and yet the action of the
> APPLY function does not really involve any notion of evaluation.
> So if you can understand why one might say of this:
> 
>  (let ((x '(a a)))
>    (apply #'equal x))
> 
> that "there was no argument evaluation involved in the application of equal",

Again, I think I understand what you mean, but just to clear up my 
thoughts, does the above statement also hold true for this case:

(let ((x '(a))
       (y 'b))
   (apply #'equal y x))

OR this one:

(let ((x 'a)
       (y 'b))
   (funcall #'equal y x))

?

> or if you can understand why it's proper to say that in
> 
>  (+ 3 5)
>  => 8
> 
> "there was no call to print"

This is quite clear.

> 
> I'm not sure if that's helpful or not, but it occurred to me that maybe 
> thinking of it as "no evaluation" rather than "only one evaluation" might
> be emotionally more satisfying for some people.

Its been very helpful. Thanks a lot.

Chaitanya
From: Chaitanya Gupta
Subject: Re: Why is EQL specializer evaluated only once?
Date: 
Message-ID: <f4b2qa$6n7$1@registered.motzarella.org>
Thank you Barry, Kent and Pascal. Your replies have been very helpful in 
clearing my doubts over this issue.

Chaitanya