Re: Why can't defstructs be redefined?
Alan Ruttenberg <[email protected]> Wed, 13 Jul 2022 17:49:08 -0400
| Newsgroups | gmane.editors.j.devel |
|---|---|
| Message-ID | <CAFKQJ8kkEzun=QoQUgE465OWZ9iFqhEtsfsD-2GXv7PM+xiEAw@mail.gmail.com> |
--000000000000c6807c05e3b6c2c0 Content-Type: text/plain; charset="UTF-8" This is what I came up with: https://github.com/alanruttenberg/abcl/commit/a9c5541d372012d24c0daa704a22fc637398e086 Depending on the value of switch switch sys::*allow-defstruct-redefinition*. In order to allow the structure to be redefined, we delete the structure class, if there is already one. The undefined behavior is now 1. use of an existing struct from before the redefinition. 2. creation of functions with the same name as a structure element that has been removed. 3. running existing compiled code that uses an accessor for a slot that has changed relative position in the structure. #2 can be fixed by removing the source transformation for the accessor. (sys::%set-function-info accessor nil). It's not hard - involves iterating through the accessors just before the defstruct is redefined. I don't think I'm going to bother fixing this at the moment. #3 can be avoided by (declare (notinline accessor)) in the function being defined. Arguably this is what should be done if (declare (optimize (debug 3))). I could also have sys::not-inline-p return true if debug is 3. I may try to do this, since it will be easy to forget to recompile. We could at least provide warnings for such functions if we recorded that the source transform was applied, during compilation BTW, if you have an existing (regular) class and create a defstruct with the same name, it blows away the previous class. That probably deserves a warning. Comments welcome. Alan On Tue, Jul 12, 2022 at 3:44 AM Vibhu Mohindra <[email protected]> wrote: > On 11/07/2022 19:41, Alan Ruttenberg wrote: > > Anyone know this area of the compiler? It's very frustrating during > > development. > > Interesting. The rationale is performance apparently. > CLTL2: 19.2. How to Use Defstruct > https://www.cs.cmu.edu/Groups/AI/html/cltl/clm/node170.html > whose last four paragraphs explain the reason. It concludes with: > "The defstruct feature is intended to provide ``the most efficient'' > structure class. CLOS classes defined by defclass allow much more > flexible structures to be defined and redefined." > > ---- > If you want flexibility, but also don't want to use classes instead of > structs everywhere, one solution may be to define your own defstruct > macro in some package that produces a class and functions/methods. > Import and use that defstruct during development, but switch over to the > real one when development ends (assuming you want its performance). > > > Seems we ought to, at least, be able to blow away all > > traces of the defstruct, ignoring existing structures and redefine it. > > CLTL2 above agrees in its last para, > "Programming environments are allowed and encouraged to permit defstruct > redefinition, [...]" > so it sounds like you'll have made ABCL better once your > structure-definition approach succeeds. Others on this list will know > more about this area and the errors you're seeing. > > Vibhu > > --000000000000c6807c05e3b6c2c0 Content-Type: text/html; charset="UTF-8" Content-Transfer-Encoding: quoted-printable <div dir=3D"ltr"><div>This is what I came up with:</div><div><br></div><div= ><a href=3D"https://github.com/alanruttenberg/abcl/commit/a9c5541d372012d24= c0daa704a22fc637398e086">https://github.com/alanruttenberg/abcl/commit/a9c5= 541d372012d24c0daa704a22fc637398e086</a></div><div><br></div><div>Depending= on the value of switch switch sys::*allow-defstruct-redefinition*. In orde= r to allow the structure to be redefined, we delete the structure class, if= there is already one.</div><div><br></div><div>The undefined behavior is n= ow</div><div>=C2=A01. use of an existing struct from before the redefinitio= n. <br></div><div>=C2=A02. creation of functions with the same name as a st= ructure element that has been removed.=C2=A0 <br></div><div>=C2=A03. runnin= g existing compiled code that uses an accessor for a slot that has changed = relative position in the structure.</div><div><br></div><div><br></div><div= >#2 can be fixed by removing the source transformation for the accessor.</d= iv><div>(sys::%set-function-info accessor=C2=A0 nil). It's not hard - i= nvolves iterating through the accessors just before the defstruct is redefi= ned.</div><div>I don't think I'm going to bother fixing this at the= moment.<br></div><div><br></div><div>#3 can be avoided by (declare (notinl= ine accessor))=C2=A0 in the function being defined. Arguably this is what s= hould be done if (declare (optimize (debug 3))).</div><div>I could also hav= e sys::not-inline-p return true if debug is 3. I may try to do this, since = it will be easy to forget to recompile.<br></div><div>We could at least pro= vide warnings for such functions if we recorded that the source transform w= as applied, during compilation</div><div><br></div><div>BTW, if you have an= existing (regular) class and create a defstruct with the same name, it blo= ws away the previous class. <br></div><div>That probably deserves a warning= .<br></div><div><br></div><div>Comments welcome.</div><div><br></div><div>A= lan<br></div><div><br></div></div><br><div class=3D"gmail_quote"><div dir= =3D"ltr" class=3D"gmail_attr">On Tue, Jul 12, 2022 at 3:44 AM Vibhu Mohindr= a <<a href=3D"mailto:[email protected]">[email protected]<= /a>> wrote:<br></div><blockquote class=3D"gmail_quote" style=3D"margin:0= px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">O= n 11/07/2022 19:41, Alan Ruttenberg wrote:<br> > Anyone know this area of the compiler? It's very frustrating durin= g <br> > development.<br> <br> Interesting. The rationale is performance apparently.<br> CLTL2: 19.2. How to Use Defstruct<br> <a href=3D"https://www.cs.cmu.edu/Groups/AI/html/cltl/clm/node170.html" rel= =3D"noreferrer" target=3D"_blank">https://www.cs.cmu.edu/Groups/AI/html/clt= l/clm/node170.html</a><br> whose last four paragraphs explain the reason. It concludes with:<br> "The defstruct feature is intended to provide ``the most efficient'= ;' <br> structure class. CLOS classes defined by defclass allow much more <br> flexible structures to be defined and redefined."<br> <br> ----<br> If you want flexibility, but also don't want to use classes instead of = <br> structs everywhere, one solution may be to define your own defstruct <br> macro in some package that produces a class and functions/methods. <br> Import and use that defstruct during development, but switch over to the <b= r> real one when development ends (assuming you want its performance).<br> <br> > Seems we ought to, at least, be able to blow away all <br> > traces of the defstruct, ignoring existing structures and redefine it.= <br> <br> CLTL2 above agrees in its last para,<br> "Programming environments are allowed and encouraged to permit defstru= ct <br> redefinition, [...]"<br> so it sounds like you'll have made ABCL better once your <br> structure-definition approach succeeds. Others on this list will know <br> more about this area and the errors you're seeing.<br> <br> Vibhu<br> <br> </blockquote></div> --000000000000c6807c05e3b6c2c0--