Lisp HUG Maillist Archive

calling MAKE-INSTANCE on a structure-class

I'm trying to get the current version of CL-SDL2 to work in Lispworks 7 and I ran into an issue where MAKE-INSTANCE is being called on a structure class.  For example, this works in SBCL and CCL:

CL-USER> (defstruct foo)
FOO
CL-USER> (make-instance (find-class 'foo))
#S(FOO)
CL-USER> (make-instance 'foo)
#S(FOO)

When running the same code in Lispworks 7 I get:

No applicable methods for #<STANDARD-GENERIC-FUNCTION MAKE-INSTANCE 4100096004> with args (#<STRUCTURE-CLASS FOO 4020352373>)

I cannot find anything in the CLHS indicating that structures can be instantiated with MAKE-INSTANCE so I'm not sure if this is a bug in Lispworks or just a feature of SBCL/CCL. 

Any ideas?

Re: calling MAKE-INSTANCE on a structure-class



On 24/12/15 20:34, Anthony Fairchild wrote:
> I'm trying to get the current version of CL-SDL2 to work in Lispworks 
> 7 and I ran into an issue where MAKE-INSTANCE is being called on a 
> structure class.  For example, this works in SBCL and CCL:
>
> CL-USER> (defstruct foo)
> FOO
> CL-USER> (make-instance (find-class 'foo))
> #S(FOO)
> CL-USER> (make-instance 'foo)
> #S(FOO)
>
> When running the same code in Lispworks 7 I get:
>
> No applicable methods for #<STANDARD-GENERIC-FUNCTION MAKE-INSTANCE 
> 4100096004> with args (#<STRUCTURE-CLASS FOO 4020352373>)
>
> I cannot find anything in the CLHS indicating that structures can be 
> instantiated with MAKE-INSTANCE so I'm not sure if this is a bug in 
> Lispworks or just a feature of SBCL/CCL.
>
> Any ideas?

There's nothing in the CLHS that prevents structures to be implemented 
as CLOS classes either.

But it is not conforming, for a program to depend on it.
This CL-SDL2 library is not conforming!  It should not have been called 
CL- something!

The only way to create a structure is to call one of the structure 
constructors (or one of the structure copiers), that can be declared in 
the defstruct structure options; by default, it's MAKE-FOO for a 
structure named FOO.


Now, you have basically two choices:

- either make the code conforming by replacing the calls to 
make-instance to calls to make-foo; but there may have other places 
where they have taken advantage of structures as CLOS objects; notably, 
the structure accessors are not (necessarily) generic functions! So you 
may prefer to:

- implement a DEFSTRUCT macro that will define CLOS classes instead, and 
shadow CL:DEFSTRUCT, to use it instead. Depending on how packages are 
used by the source base, this may be more or less work, and it is also 
indiscriminate since it would apply to all the structures defined in 
those packages, but it may be preferable to do that.  Notice that 
DEFSTRUCT is not a trivial macro (it defines a lot of functions, 
computing a lot of names, and you must be careful with case, and 
packages where those symbols are interned), and there's a big stubbling 
block: :INCLUDE may refer structures that have not been defined with 
your DEFSTRUCT macro (and therefore that are NOT CLOS classes).  I guess 
you can fall back to CL:DEFSTRUCT if there's an :INCLUDE referencing a 
structure you don't know and have generated as a DEFCLASS.

See 
http://informatimago.com/articles/usenet.html#Improved-DEFSTRUCT-macro--run-time-access-to-the-fields 
for a few examples, notably DEFINE-STRUCTURE-CLASS in the 
DEFINE-WITH-STRUCTURE 
<http://groups.google.com/group/comp.lang.lisp/msg/f687db3424753775> page.


Probably, making the code conforming would be the simpliest option, even 
if it could be laborious on a big code base.

-- 
__Pascal J. Bourguignon__
http://www.informatimago.com/

_______________________________________________
Lisp Hug - the mailing list for LispWorks users
lisp-hug@lispworks.com
http://www.lispworks.com/support/lisp-hug.html


Re: calling MAKE-INSTANCE on a structure-class

On 12/24/15 Dec 24 -1:57 PM, Pascal J. Bourguignon wrote:
> 
> 
> 
> On 24/12/15 20:34, Anthony Fairchild wrote:
>> I'm trying to get the current version of CL-SDL2 to work in Lispworks
>> 7 and I ran into an issue where MAKE-INSTANCE is being called on a
>> structure class.  For example, this works in SBCL and CCL:
>>
>> CL-USER> (defstruct foo)
>> FOO
>> CL-USER> (make-instance (find-class 'foo))
>> #S(FOO)
>> CL-USER> (make-instance 'foo)
>> #S(FOO)
>>
>> When running the same code in Lispworks 7 I get:
>>
>> No applicable methods for #<STANDARD-GENERIC-FUNCTION MAKE-INSTANCE
>> 4100096004> with args (#<STRUCTURE-CLASS FOO 4020352373>)
>>
>> I cannot find anything in the CLHS indicating that structures can be
>> instantiated with MAKE-INSTANCE so I'm not sure if this is a bug in
>> Lispworks or just a feature of SBCL/CCL.
>>
>> Any ideas?
> 
> There's nothing in the CLHS that prevents structures to be implemented
> as CLOS classes either.
> 
> But it is not conforming, for a program to depend on it.
> This CL-SDL2 library is not conforming!  It should not have been called
> CL- something!
> 
> The only way to create a structure is to call one of the structure
> constructors (or one of the structure copiers), that can be declared in
> the defstruct structure options; by default, it's MAKE-FOO for a
> structure named FOO.
> 
> 
> Now, you have basically two choices:
> 
> - either make the code conforming by replacing the calls to
> make-instance to calls to make-foo; but there may have other places
> where they have taken advantage of structures as CLOS objects; notably,
> the structure accessors are not (necessarily) generic functions! So you
> may prefer to:
> 
> - implement a DEFSTRUCT macro that will define CLOS classes instead, and
> shadow CL:DEFSTRUCT, to use it instead. Depending on how packages are
> used by the source base, this may be more or less work, and it is also
> indiscriminate since it would apply to all the structures defined in
> those packages, but it may be preferable to do that.  Notice that
> DEFSTRUCT is not a trivial macro (it defines a lot of functions,
> computing a lot of names, and you must be careful with case, and
> packages where those symbols are interned), and there's a big stubbling
> block: :INCLUDE may refer structures that have not been defined with
> your DEFSTRUCT macro (and therefore that are NOT CLOS classes).  I guess
> you can fall back to CL:DEFSTRUCT if there's an :INCLUDE referencing a
> structure you don't know and have generated as a DEFCLASS.

Note that this can be *conditionally* implemented.  You can retain code
that uses MAKE-INSTANCE on structure classes for those implementations
that you know to support it.

I don't know who wrote this, or what their motivations were, but
replacing all structures with CLOS objects *might* have an adverse
effect on the efficiency of the code, so you might not want to replace
structures with classes.

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.

The accessors might be more of a nuisance, and require some macrology,
but this would depend on whether you really rely on them being treated
as GFs.  If someone's fussed about efficiency, my guess is that they
would be using the accessors in ways that are consistent with them not
being GFs.

hth

_______________________________________________
Lisp Hug - the mailing list for LispWorks users
lisp-hug@lispworks.com
http://www.lispworks.com/support/lisp-hug.html


Re: calling MAKE-INSTANCE on a structure-class

Pascal Costanza <pc@p-cos.net> writes:

>> On 24 Dec 2015, at 21:13, Robert Goldman <rpgoldman@sift.net> wrote:
>> 
>> 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.htmprevents
> you from defining such methods.


Indeed. I was about to propose a third solution consisting in having a
CLOS wrapper over structures, but this opens three more cans of worms,
so really, the library should be rewritten in conforming CL code instead
of sbclese.

-- 
__Pascal Bourguignon__                 http://www.informatimago.com/
“The factory of the future will have only two employees, a man and a
dog. The man will be there to feed the dog. The dog will be there to
keep the man from touching the equipment.” -- Carl Bass CEO Autodesk

_______________________________________________
Lisp Hug - the mailing list for LispWorks users
lisp-hug@lispworks.com
http://www.lispworks.com/support/lisp-hug.html


Re: calling MAKE-INSTANCE on a structure-class

Thanks for the help everyone.  I'll work on rewriting the code to be be CL conforming which will mean changing the make-instance calls to make-<structure-name> calls.

Thanks!

Anthony

On Thu, Dec 24, 2015 at 5:27 PM Pascal J. Bourguignon <pjb@informatimago.com> wrote:

Pascal Costanza <pc@p-cos.net> writes:

>> On 24 Dec 2015, at 21:13, Robert Goldman <rpgoldman@sift.net> wrote:
>>
>> 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.htmprevents
> you from defining such methods.


Indeed. I was about to propose a third solution consisting in having a
CLOS wrapper over structures, but this opens three more cans of worms,
so really, the library should be rewritten in conforming CL code instead
of sbclese.

--
__Pascal Bourguignon__                 http://www.informatimago.com/
“The factory of the future will have only two employees, a man and a
dog. The man will be there to feed the dog. The dog will be there to
keep the man from touching the equipment.” -- Carl Bass CEO Autodesk

_______________________________________________
Lisp Hug - the mailing list for LispWorks users
lisp-hug@lispworks.com
http://www.lispworks.com/support/lisp-hug.html

Re: calling MAKE-INSTANCE on a structure-class

Just out of curiosity I looked for but couldn't find an occurrence of
make-instance in https://github.com/lispgames/cl-sdl2, does it occur
in some other code using that library?

On 25 December 2015 at 06:04, Anthony Fairchild
<fairchild.anthony@gmail.com> wrote:
> I'm trying to get the current version of CL-SDL2 to work in Lispworks 7 and
> I ran into an issue where MAKE-INSTANCE is being called on a structure
> class.  For example, this works in SBCL and CCL:
>
> CL-USER> (defstruct foo)
> FOO
> CL-USER> (make-instance (find-class 'foo))
> #S(FOO)
> CL-USER> (make-instance 'foo)
> #S(FOO)
>
> When running the same code in Lispworks 7 I get:
>
> No applicable methods for #<STANDARD-GENERIC-FUNCTION MAKE-INSTANCE
> 4100096004> with args (#<STRUCTURE-CLASS FOO 4020352373>)
>
> I cannot find anything in the CLHS indicating that structures can be
> instantiated with MAKE-INSTANCE so I'm not sure if this is a bug in
> Lispworks or just a feature of SBCL/CCL.
>
> Any ideas?

_______________________________________________
Lisp Hug - the mailing list for LispWorks users
lisp-hug@lispworks.com
http://www.lispworks.com/support/lisp-hug.html


Re: calling MAKE-INSTANCE on a structure-class

The issue I'm seeing is in https://github.com/rpav/cl-autowrap  which is a dependency.   You can repro the issue by running:

(sdl2-examples:renderer-test)

I plan on submitting a pull request within the next few days.

On Sat, Dec 26, 2015 at 9:24 PM Andrew Kirkpatrick <ubermonk@gmail.com> wrote:
Just out of curiosity I looked for but couldn't find an occurrence of
make-instance in https://github.com/lispgames/cl-sdl2, does it occur
in some other code using that library?

On 25 December 2015 at 06:04, Anthony Fairchild
<fairchild.anthony@gmail.com> wrote:
> I'm trying to get the current version of CL-SDL2 to work in Lispworks 7 and
> I ran into an issue where MAKE-INSTANCE is being called on a structure
> class.  For example, this works in SBCL and CCL:
>
> CL-USER> (defstruct foo)
> FOO
> CL-USER> (make-instance (find-class 'foo))
> #S(FOO)
> CL-USER> (make-instance 'foo)
> #S(FOO)
>
> When running the same code in Lispworks 7 I get:
>
> No applicable methods for #<STANDARD-GENERIC-FUNCTION MAKE-INSTANCE
> 4100096004> with args (#<STRUCTURE-CLASS FOO 4020352373>)
>
> I cannot find anything in the CLHS indicating that structures can be
> instantiated with MAKE-INSTANCE so I'm not sure if this is a bug in
> Lispworks or just a feature of SBCL/CCL.
>
> Any ideas?

Re: calling MAKE-INSTANCE on a structure-class

For those interested this is the change I made to get the CL-SDL2 example working in Lispworks.  Feedback welcome.

https://github.com/anthonyf/cl-autowrap/commit/5385f479d1e9494a8fd212ba50479f36906deedc

On Sun, Dec 27, 2015 at 6:25 AM Anthony Fairchild <fairchild.anthony@gmail.com> wrote:
The issue I'm seeing is in https://github.com/rpav/cl-autowrap  which is a dependency.   You can repro the issue by running:

(sdl2-examples:renderer-test)

I plan on submitting a pull request within the next few days.

On Sat, Dec 26, 2015 at 9:24 PM Andrew Kirkpatrick <ubermonk@gmail.com> wrote:
Just out of curiosity I looked for but couldn't find an occurrence of
make-instance in https://github.com/lispgames/cl-sdl2, does it occur
in some other code using that library?

On 25 December 2015 at 06:04, Anthony Fairchild
<fairchild.anthony@gmail.com> wrote:
> I'm trying to get the current version of CL-SDL2 to work in Lispworks 7 and
> I ran into an issue where MAKE-INSTANCE is being called on a structure
> class.  For example, this works in SBCL and CCL:
>
> CL-USER> (defstruct foo)
> FOO
> CL-USER> (make-instance (find-class 'foo))
> #S(FOO)
> CL-USER> (make-instance 'foo)
> #S(FOO)
>
> When running the same code in Lispworks 7 I get:
>
> No applicable methods for #<STANDARD-GENERIC-FUNCTION MAKE-INSTANCE
> 4100096004> with args (#<STRUCTURE-CLASS FOO 4020352373>)
>
> I cannot find anything in the CLHS indicating that structures can be
> instantiated with MAKE-INSTANCE so I'm not sure if this is a bug in
> Lispworks or just a feature of SBCL/CCL.
>
> Any ideas?
Updated at: 2020-12-10 08:32 UTC