[lnkForumImage]
TotalShareware - Download Free Software

Confronta i prezzi di migliaia di prodotti.
Asp Forum
 Home | Login | Register | Search 


 

Forums >

comp.lang.lisp

11.1.2.1.2 #19 Restrictons on methods on standardized generic functions

Madhu

2/3/2016 6:02:00 AM


I noticed this comment from Pascal Costanza on lisphug in a response to
rpgoldman last december -

* Pascal Costanza <9411B892-AA56-4798-8389-8E531D13345C@p-cos.net> :
|
|> Note also that you might not have to replace calls to MAKE-INSTANCE
|> with calls to make-foo -- the MOP says MAKE-INSTANCE is a generic
|> function, so you could add EQL methods for the (names of) the
|> structure classes you need, again, conditionally compiling for those
|> lisps that need them.
|
| No, you canâ??t. ANSI CL already specifies make-instance as a generic
| function, and bullet 19 of
| http://www.lispworks.com/documentation/HyperSpec/Body/11_abab.h...
| you from defining such methods.

The section 11.1.2.1.2 says

19. Defining a method for a standardized generic function which
is applicable when all of the arguments are direct instances of
standardized classes.

If I understand Pascal correctly, he is saying that the consequences are
undefined in this following example:

(defstruct foo)
(defmethod make-instance ((class-name (eql 'foo)) &key)
(make-foo)))

But I do not see how it follows from the cited text. Isn't the EQL
method which is being defined in this example specializing on the symbol
EQL FOO?

Put another way: if this #19 point applies to this, then then ALL eql
methods on ALL data types would be non-conforming... clearly my logic is
incorrect but what am I missing or misunderstanding? Could you explain
what the direct instance of the standardized class is in this case?
---Madhu
4 Answers

Madhu

2/3/2016 2:09:00 PM

0


[Following up to myself]

* Madhu <m3io26jpqv.fsf@leonis4.robolove.meer.net> :
Wrote on Wed, 03 Feb 2016 11:32:16 +0530:

| I noticed this comment from Pascal Costanza on lisphug in a response to
| rpgoldman last december -
|
| * Pascal Costanza <9411B892-AA56-4798-8389-8E531D13345C@p-cos.net> :
| |
| |> Note also that you might not have to replace calls to MAKE-INSTANCE
| |> with calls to make-foo -- the MOP says MAKE-INSTANCE is a generic
| |> function, so you could add EQL methods for the (names of) the
| |> structure classes you need, again, conditionally compiling for
| |> those lisps that need them.
| |
| | No, you canâ??t. ANSI CL already specifies make-instance as a generic
| | function, and bullet 19 of
| | http://www.lispworks.com/documentation/HyperSpec/Body/1...
| | prevents you from defining such methods.
|
| The section 11.1.2.1.2 says
|
| 19. Defining a method for a standardized generic function which
| is applicable when all of the arguments are direct instances of
| standardized classes.
|
| If I understand Pascal correctly, he is saying that the consequences are
| undefined in this following example:
|
| (defstruct foo)
| (defmethod make-instance ((class-name (eql 'foo)) &key)
| (make-foo)))
|
| But I do not see how it follows from the cited text. Isn't the EQL
| method which is being defined in this example specializing on the
| symbol EQL FOO?

Nevermind, It looks obvious to me now..

| Put another way: if this #19 point applies to this, then then ALL eql
| methods on ALL data types would be non-conforming... clearly my logic
| is incorrect but what am I missing or misunderstanding? Could you
| explain what the direct instance of the standardized class is in this
| case?

[To answer my own question. The symbol 'foo would be the instance of the
system class SYMBOL. The question now is was this particular case an
intended consequence of the statement of the spec? I can believe it
from performance arguments...
The problem in the original thread was about making

(make-instance 'foo) => #S(FOO)

in lisps that don't allow it.. I think that can be done conformantly
like this

(defclass foo-standard-class (standard-class) ())
(defclass foo-class () () (:metaclass foo-standard-class))
(defstruct foo)
(defmethod make-instance ((class foo-standard-class) &key) (make-foo))
(make-instance 'foo-class)
(setf (find-class 'foo) (find-class 'foo-class))
(make-instance 'foo)

Marco Antoniotti

2/3/2016 7:27:00 PM

0

On Wednesday, February 3, 2016 at 6:08:08 AM UTC-8, Madhu wrote:
> [Following up to myself]
>
> * Madhu <m3io26jpqv.fsf@leonis4.robolove.meer.net> :
> Wrote on Wed, 03 Feb 2016 11:32:16 +0530:
>
> | I noticed this comment from Pascal Costanza on lisphug in a response to
> | rpgoldman last december -
> |
> | * Pascal Costanza <9411B892-AA56-4798-8389-8E531D13345C@p-cos.net> :
> | |
> | |> Note also that you might not have to replace calls to MAKE-INSTANCE
> | |> with calls to make-foo -- the MOP says MAKE-INSTANCE is a generic
> | |> function, so you could add EQL methods for the (names of) the
> | |> structure classes you need, again, conditionally compiling for
> | |> those lisps that need them.
> | |
> | | No, you can't. ANSI CL already specifies make-instance as a generic
> | | function, and bullet 19 of
> | | http://www.lispworks.com/documentation/HyperSpec/Body/1...
> | | prevents you from defining such methods.
> |
> | The section 11.1.2.1.2 says
> |
> | 19. Defining a method for a standardized generic function which
> | is applicable when all of the arguments are direct instances of
> | standardized classes.
> |
> | If I understand Pascal correctly, he is saying that the consequences are
> | undefined in this following example:
> |
> | (defstruct foo)
> | (defmethod make-instance ((class-name (eql 'foo)) &key)
> | (make-foo)))
> |
> | But I do not see how it follows from the cited text. Isn't the EQL
> | method which is being defined in this example specializing on the
> | symbol EQL FOO?
>
> Nevermind, It looks obvious to me now..
>
> | Put another way: if this #19 point applies to this, then then ALL eql
> | methods on ALL data types would be non-conforming... clearly my logic
> | is incorrect but what am I missing or misunderstanding? Could you
> | explain what the direct instance of the standardized class is in this
> | case?
>
> [To answer my own question. The symbol 'foo would be the instance of the
> system class SYMBOL. The question now is was this particular case an
> intended consequence of the statement of the spec? I can believe it
> from performance arguments...
> The problem in the original thread was about making
>
> (make-instance 'foo) => #S(FOO)
>
> in lisps that don't allow it.. I think that can be done conformantly
> like this
>
> (defclass foo-standard-class (standard-class) ())
> (defclass foo-class () () (:metaclass foo-standard-class))
> (defstruct foo)
> (defmethod make-instance ((class foo-standard-class) &key) (make-foo))
> (make-instance 'foo-class)
> (setf (find-class 'foo) (find-class 'foo-class))
> (make-instance 'foo)

Yes it works, but you are now loosing the status of FOO as a STRUCTURE-CLASS.

MA

Kalle Olavi Niemitalo

2/3/2016 10:54:00 PM

0

Marco Antoniotti <marcoxa@gmail.com> writes:

> On Wednesday, February 3, 2016 at 6:08:08 AM UTC-8, Madhu wrote:
>> (defclass foo-standard-class (standard-class) ())
>> (defclass foo-class () () (:metaclass foo-standard-class))

In SBCL 1.0.57.0.debian, that signals an error unless I also do

(defmethod sb-mop:validate-superclass ((class foo-standard-class)
(superclass standard-class))
t)

>> (setf (find-class 'foo) (find-class 'foo-class))
>> (make-instance 'foo)
>
> Yes it works, but you are now loosing the status of FOO as a STRUCTURE-CLASS.

In this version of SBCL, the reader signals an error for "#S(FOO)":
FOO is not a defined structure type.

If I did (defparameter *real-foo* (make-instance 'foo)) before
defining a method on MAKE-INSTANCE, then after SETF FIND-CLASS,
(typep (make-foo) 'foo) is NIL and (typep *real-foo* 'foo) is T.
I don't think the latter is required. 4.3.7 says "The proper name
of every class is a valid type specifier", but the symbol FOO is
no longer the proper name of any class. OTOH, I don't know
whether anything forbids treating it as a type specifier still.

Pascal Costanza

2/6/2016 11:45:00 AM

0

On 03/02/2016 15:08, Madhu wrote:
>
> [Following up to myself]
>
> * Madhu <m3io26jpqv.fsf@leonis4.robolove.meer.net> :
> Wrote on Wed, 03 Feb 2016 11:32:16 +0530:
>
> | I noticed this comment from Pascal Costanza on lisphug in a response to
> | rpgoldman last december -
> |
> | * Pascal Costanza <9411B892-AA56-4798-8389-8E531D13345C@p-cos.net> :
> | |
> | |> Note also that you might not have to replace calls to MAKE-INSTANCE
> | |> with calls to make-foo -- the MOP says MAKE-INSTANCE is a generic
> | |> function, so you could add EQL methods for the (names of) the
> | |> structure classes you need, again, conditionally compiling for
> | |> those lisps that need them.
> | |
> | | No, you canâ??t. ANSI CL already specifies make-instance as a generic
> | | function, and bullet 19 of
> | | http://www.lispworks.com/documentation/HyperSpec/Body/1...
> | | prevents you from defining such methods.
> |
> | The section 11.1.2.1.2 says
> |
> | 19. Defining a method for a standardized generic function which
> | is applicable when all of the arguments are direct instances of
> | standardized classes.
> |
> | If I understand Pascal correctly, he is saying that the consequences are
> | undefined in this following example:
> |
> | (defstruct foo)
> | (defmethod make-instance ((class-name (eql 'foo)) &key)
> | (make-foo)))
> |
> | But I do not see how it follows from the cited text. Isn't the EQL
> | method which is being defined in this example specializing on the
> | symbol EQL FOO?
>
> Nevermind, It looks obvious to me now..
>
> [To answer my own question. The symbol 'foo would be the instance of the
> system class SYMBOL. The question now is was this particular case an
> intended consequence of the statement of the spec?

Yes, I think so, but I think it could be relaxed without any negative
consequences.

I believe the primary motivation for bullet 19 is to avoid different
third-party libraries providing conflicting method definitions. The
restriction in bullet 19 roughly means that you can only define methods
on "your own" classes - well, at least one of the arguments needs to be
specialized on one of "your own" classes. (I put "your own" in quotes
because this is a fuzzy requirement, but should be mostly clear in
practice.)

eql specializers don't add a lot of "ownership." Two libraries could
define, say, a method for make-instance specialized on (eql 'foo), and
then it's not clear which of the two has precedence and gets used
effectively. (It could be resolved by library load order, but that's
semantically meaningless.) That's why eql specializers are not
explicitly covered in bullet 19.

However, you could relax the requirement for symbols specifically by
requiring that eql specializers on symbols are ok as long as they are
symbols interned in one of "your own" packages. This would specifically
enable the, IMHO, very useful case of specializing make-instance for
particular class names. Maybe that's a useful CDR.

Pascal

--
My website: http:/...
Common Lisp Document Repository: http://cdr.eu...
Closer to MOP & ContextL: http://common-lisp.net/proje...
The views expressed are my own, and not those of my employer.