From: David E. Young
Subject: ANSI compatibility issue
Date: 
Message-ID: <3ACA57A3.438F2F71@nc.rr.com>
Greetings. I'm trying to clear up a discrepancy involving initialization
arguments that appear in the lambda-list of initialize-instance.

Given the following simplified code fragment:

(defclass rule ()
  ((name :initarg :name
         :initform nil
         :reader get-name)
    (salience :initarg :salience
                       :initform 0
                       :reader get-salience)))

(defmethod initialize-instance :after ((self rule) &key (directives
nil))
  ...)

(defun make-rule (name (directives nil))
  (make-instance 'rule :name name :directives directives))

[ Note the addition of an initialisation argument in
initialize-instance's lambda list. ]

With the above, ACL 6.0, LispWorks 4.1 and CMUCL 18c all work just fine.
However, CLISP fails at runtime with:

*** - EVAL/APPLY: keyword :NAME is illegal for #<COMPILED-CLOSURE
#:COMPILED-FORM-129-1>. The possible keywords are (:DIRECTIVES)
1. Break LISA[5]>

Now, if I read the CLHS correctly it seems that this should work. The
rub, of course, is whether or not I truly understand the spec.

From CLHS section 7.1.2 Declaring the Validity of Initialization
Arguments:

* Initialization arguments that fill slots are declared as valid by
  the :initarg slot option to defclass...

* Initialization arguments that supply arguments to methods are
  declared as valid by defining those methods. The keyword name of
  each keyword parameter specified in the method's lambda list becomes
  an initialization argument for all classes for which the method is
  applicable...

Note that the three LISPs I mentioned above also signal an error if a
keyword that doesn't appear as an initarg or in the lambda-list is
supplied (as one would expect). And, adding &allow-other-keys works as
advertised.

The CLISP folks feel their implementation is correct, and it might very
well be. Please help me clear this up.

Regards,

--
-----------------------------------------------------------------
David E. Young
Fujitsu Network Communications  (defun real-language? (lang)
(········@computer.org)           (eq lang 'LISP))

"But all the world understands my language."
  -- Franz Joseph Haydn (1732-1809)

From: Tunc Simsek
Subject: Re: ANSI compatibility issue
Date: 
Message-ID: <3ACB9A5B.CEDF29C6@robotics.eecs.berkeley.edu>
"David E. Young" wrote:
> 
> Greetings. I'm trying to clear up a discrepancy involving initialization
> arguments that appear in the lambda-list of initialize-instance.
> 
> Given the following simplified code fragment:
> 
> (defclass rule ()
>   ((name :initarg :name
>          :initform nil
>          :reader get-name)
>     (salience :initarg :salience
>                        :initform 0
>                        :reader get-salience)))
> 
> (defmethod initialize-instance :after ((self rule) &key (directives
> nil))
>   ...)
> 
> (defun make-rule (name (directives nil))
>   (make-instance 'rule :name name :directives directives))
> 
> [ Note the addition of an initialisation argument in
> initialize-instance's lambda list. ]
> 
> With the above, ACL 6.0, LispWorks 4.1 and CMUCL 18c all work just fine.
> However, CLISP fails at runtime with:
> 
> *** - EVAL/APPLY: keyword :NAME is illegal for #<COMPILED-CLOSURE
> #:COMPILED-FORM-129-1>. The possible keywords are (:DIRECTIVES)
> 1. Break LISA[5]>
> 
> Now, if I read the CLHS correctly it seems that this should work. The
> rub, of course, is whether or not I truly understand the spec.
> 
> From CLHS section 7.1.2 Declaring the Validity of Initialization
> Arguments:
> 
> * Initialization arguments that fill slots are declared as valid by
>   the :initarg slot option to defclass...
> 
> * Initialization arguments that supply arguments to methods are
>   declared as valid by defining those methods. The keyword name of
>   each keyword parameter specified in the method's lambda list becomes
>   an initialization argument for all classes for which the method is
>   applicable...
> 
> Note that the three LISPs I mentioned above also signal an error if a
> keyword that doesn't appear as an initarg or in the lambda-list is
> supplied (as one would expect). And, adding &allow-other-keys works as
> advertised.
> 
> The CLISP folks feel their implementation is correct, and it might very
> well be. Please help me clear this up.
> 
> Regards,
> 
> --
> -----------------------------------------------------------------
> David E. Young
> Fujitsu Network Communications  (defun real-language? (lang)
> (········@computer.org)           (eq lang 'LISP))
> 
> "But all the world understands my language."
>   -- Franz Joseph Haydn (1732-1809)



My understanding of the CLHS says that your code should work.
See Section 7.6.4:


http://www.xanalys.com/software_tools/reference/HyperSpec/Body/sec_7-6-4.html

The CLHS specifies that the INITIALIZE-INSTANCE is declared as:

initialize-instance instance &rest initargs &key &allow-other-keys =>
instance

Thus, when I write a method for INITIALIZE-INSTANCE I should ensure
that:

(7.6.4, item 3) I either mention &REST or &KEY
(7.6.4, item 4) Since no specific &KEY is specified in the lambda-list
    of the generic function, I can mention any number of &KEYs
(7.6.4, item 5) Since &ALLOW-OTHER-KEYS is mentioned in the lambda-list
    of the generic function, I don't need to repeat it in the
lambda-list
    of my particular method.


Thus, your code is correct.  I've looked at CLISP, I think that
the reason your code may not be working is that &ALLOW-OTHER-KEYS
does not appear in the lambda-list of the generic function

[1]> (describe #'initialize-instance)
 
  #<GENERIC-FUNCTION INITIALIZE-INSTANCE> is a compiled function.
  Argument list: (ARG0 &REST OTHER-ARGS)
  For more information, evaluate (DISASSEMBLE #'INITIALIZE-INSTANCE).


The confusing thing about INITIALIZE-INSTANCE is the following.
The system somehow knows how to check whether keywords argument
given to it are valid initargs to some slot.  On the other hand,
if I write a method for INITIALIZE-INSTANCE with a special &KEY
in its lambda-list, then the system does not get confused.

Regards,
Tunc
From: Kent M Pitman
Subject: Re: ANSI compatibility issue
Date: 
Message-ID: <sfwd7aso503.fsf@world.std.com>
"David E. Young" <·······@nc.rr.com> writes:

> 
> Greetings. I'm trying to clear up a discrepancy involving initialization
> arguments that appear in the lambda-list of initialize-instance.
> 
> Given the following simplified code fragment:
> 
> (defclass rule ()
>   ((name :initarg :name
>          :initform nil
>          :reader get-name)
>     (salience :initarg :salience
>                        :initform 0
>                        :reader get-salience)))
> 
> (defmethod initialize-instance :after ((self rule) &key (directives
> nil))
>   ...)
> 
> (defun make-rule (name (directives nil))
>   (make-instance 'rule :name name :directives directives))
> 
> [ Note the addition of an initialisation argument in
> initialize-instance's lambda list. ]
> 
> With the above, ACL 6.0, LispWorks 4.1 and CMUCL 18c all work just fine.
> However, CLISP fails at runtime with:
> 
> *** - EVAL/APPLY: keyword :NAME is illegal for #<COMPILED-CLOSURE
> #:COMPILED-FORM-129-1>. The possible keywords are (:DIRECTIVES)
> 1. Break LISA[5]>
> 
> Now, if I read the CLHS correctly it seems that this should work. The
> rub, of course, is whether or not I truly understand the spec.
> 
> From CLHS section 7.1.2 Declaring the Validity of Initialization
> Arguments:
> 
> * Initialization arguments that fill slots are declared as valid by
>   the :initarg slot option to defclass...
> 
> * Initialization arguments that supply arguments to methods are
>   declared as valid by defining those methods. The keyword name of
>   each keyword parameter specified in the method's lambda list becomes
>   an initialization argument for all classes for which the method is
>   applicable...
> 
> Note that the three LISPs I mentioned above also signal an error if a
> keyword that doesn't appear as an initarg or in the lambda-list is
> supplied (as one would expect). And, adding &allow-other-keys works as
> advertised.
> 
> The CLISP folks feel their implementation is correct, and it might very
> well be. Please help me clear this up.

There isn't an agency adjudicating whether an implementation is conforming
or not, so ultimately it's up to the marketplace to be the final judge.
However, for what it's worth, I personally think what you did is intended
to work, and that's why all the other implementations support it.  That
behavior (accepting that keyword) is tricky to arrange for but is what users
need in order to get the "right" error-checking behavior.
From: Sam Steingold
Subject: Re: ANSI compatibility issue
Date: 
Message-ID: <uae5v8jhj.fsf@xchange.com>
> * In message <·················@nc.rr.com>
> * On the subject of "ANSI compatibility issue"
> * Sent on Tue, 03 Apr 2001 23:08:52 GMT
> * Honorable "David E. Young" <·······@nc.rr.com> writes:
>
> Greetings. I'm trying to clear up a discrepancy involving
> initialization arguments that appear in the lambda-list of
> initialize-instance.
> ...
> The CLISP folks feel their implementation is correct, and it might
> very well be. Please help me clear this up.

CLISP has just been fixed to accept your code sample.

-- 
Sam Steingold (http://www.podval.org/~sds)
Binaries die but source code lives forever.
From: David E. Young
Subject: Re: ANSI compatibility issue
Date: 
Message-ID: <3ACDC417.3E622748@nc.rr.com>
"David E. Young" wrote:

> Greetings. I'm trying to clear up a discrepancy involving initialization
> arguments that appear in the lambda-list of initialize-instance...

Thanks to everyone for their help. I'm trying to keep my software portable
across a number of Lisp implementations without peppering my code with #+
conditionals; I'm grateful for your assistance.

Regards,

--
-----------------------------------------------------------------
David E. Young
Fujitsu Network Communications  (defun real-language? (lang)
(········@computer.org)           (eq lang 'LISP))

"But all the world understands my language."
  -- Franz Joseph Haydn (1732-1809)