Re: Why can't defstructs be redefined?

Alan Ruttenberg <[email protected]> Wed, 13 Jul 2022 23:45:10 -0400
Newsgroups gmane.editors.j.devel
Message-ID <CAFKQJ8kPQZORrccmyNkC7FwF_=xaCmFkQhSCy0UF84G_03prww@mail.gmail.com>
--0000000000000ac6dc05e3bbbcc2
Content-Type: text/plain; charset="UTF-8"
Content-Transfer-Encoding: quoted-printable

On Wed, Jul 13, 2022 at 11:40 PM Robert P. Goldman <[email protected]>
wrote:

> Given that structure accessors can be open coded you need a solution that
> can force recompilation. You could get that with a build system like asdf=
.
> You=E2=80=99d have to remember to rebuild the system instead of just reco=
mpiling
> the defstruct form, but that would work
>

Thanks. Yes. I use asdf and was thinking that if I do get into the losing
situation I would just do a forced reload of my system. It needs to be
forced because the files that need to be recompiled haven't necessarily
changed.

Alan


>
> --
> Robert P. Goldman
>
> On July 13, 2022 at 20:40:33, Ville Voutilainen (
> [email protected]) wrote:
>
>> On Thu, 14 Jul 2022 at 00:50, Alan Ruttenberg <[email protected]>
>> wrote:
>>
>>
>> This is what I came up with:
>>
>>
>> https://github.com/alanruttenberg/abcl/commit/a9c5541d372012d24c0daa704a=
22fc637398e086
>>
>> 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 bein=
g
>> defined. Arguably this is what should be done if (declare (optimize (deb=
ug
>> 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 tha=
t
>> 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.
>>
>>
>> Greetings from the (for the two decades of it) other side of the
>> fence, where compilations and one-definition-rules
>> are rather more static than here. :)
>>
>> Sure, this looks plausible, and it probably works in many cases. But
>> if you COMPILE something with one definition
>> of a defstruct, then defstruct again, what happens if you try to call
>> the thing you compiled before?
>>
>> I don't claim to claim it "can't work". But I have a vague
>> understanding why there might be a reason for "this might not work".
>> :P
>>
>> As an unsubstantiated rumination, it might be *more* difficult to make
>> this work in a language that can do dynamic compilation
>> at any point in a program than it is in a language that is more static
>> as far as struct definitions and their compilations are concerned.
>> My architecture-brain can't tell how you could possibly know where all
>> the 'references' to the old defstruct could possibly be,
>> considering that compilations with the old one and uses of those can
>> be so dynamic, and where the uses that would expect
>> the newer redefinitions might be, and how you'd track that.
>>
>> Again, I'm not saying this can't work. I just find it daunting to even
>> ponder what sort of funny situations where your program
>> manages to confuse itself about which struct is which you can end up
>> with. Maybe that's a theoretical problem, but it hurts my brain. :D
>>
>>

--0000000000000ac6dc05e3bbbcc2
Content-Type: text/html; charset="UTF-8"
Content-Transfer-Encoding: quoted-printable

<div dir=3D"ltr"><div dir=3D"ltr"><br></div><br><div class=3D"gmail_quote">=
<div dir=3D"ltr" class=3D"gmail_attr">On Wed, Jul 13, 2022 at 11:40 PM Robe=
rt P. Goldman &lt;<a href=3D"mailto:[email protected]">[email protected]<=
/a>&gt; 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"><=
div>Given that structure accessors can be open coded you need a solution th=
at can force recompilation. You could get that with a build system like asd=
f. You=E2=80=99d have to remember to rebuild the system instead of just rec=
ompiling the defstruct form, but that would work<br></div></blockquote><div=
><br></div><div>Thanks. Yes. I use asdf and was thinking that if I do get i=
nto the losing situation I would just do a forced reload of my system. It n=
eeds to be forced because the files that need to be recompiled haven&#39;t =
necessarily changed.</div><div><br></div><div>Alan<br></div><div>=C2=A0<br>=
</div><blockquote class=3D"gmail_quote" style=3D"margin:0px 0px 0px 0.8ex;b=
order-left:1px solid rgb(204,204,204);padding-left:1ex"><div> <br><div><div=
>--=C2=A0<br>Robert P. Goldman</div></div> <p class=3D"gmail_quote" style=
=3D"color:rgb(0,0,0)">On July 13, 2022 at 20:40:33, Ville Voutilainen (<a h=
ref=3D"mailto:[email protected]" target=3D"_blank">ville.voutilai=
[email protected]</a>) wrote:</p> <blockquote type=3D"cite" class=3D"gmail_quot=
e"><span><div><div></div><div>On Thu, 14 Jul 2022 at 00:50, Alan Ruttenberg=
 &lt;<a href=3D"mailto:[email protected]" target=3D"_blank">alanrutt=
[email protected]</a>&gt; wrote:
<br><blockquote type=3D"cite">
<br>This is what I came up with:
<br>
<br><a href=3D"https://github.com/alanruttenberg/abcl/commit/a9c5541d372012=
d24c0daa704a22fc637398e086" target=3D"_blank">https://github.com/alanrutten=
berg/abcl/commit/a9c5541d372012d24c0daa704a22fc637398e086</a>
<br>
<br>Depending on the value of switch switch sys::*allow-defstruct-redefinit=
ion*. In order to allow the structure to be redefined, we delete the struct=
ure class, if there is already one.
<br>
<br>The undefined behavior is now
<br>1. use of an existing struct from before the redefinition.
<br>2. creation of functions with the same name as a structure element that=
 has been removed.
<br>3. running existing compiled code that uses an accessor for a slot that=
 has changed relative position in the structure.
<br>
<br>
<br>#2 can be fixed by removing the source transformation for the accessor.
<br>(sys::%set-function-info accessor  nil). It&#39;s not hard - involves i=
terating through the accessors just before the defstruct is redefined.
<br>I don&#39;t think I&#39;m going to bother fixing this at the moment.
<br>
<br>#3 can be avoided by (declare (notinline accessor))  in the function be=
ing defined. Arguably this is what should be done if (declare (optimize (de=
bug 3))).
<br>I could also have sys::not-inline-p return true if debug is 3. I may tr=
y to do this, since it will be easy to forget to recompile.
<br>We could at least provide warnings for such functions if we recorded th=
at the source transform was applied, during compilation
<br>
<br>BTW, if you have an existing (regular) class and create a defstruct wit=
h the same name, it blows away the previous class.
<br>That probably deserves a warning.
<br>
<br>Comments welcome.
<br></blockquote>
<br>Greetings from the (for the two decades of it) other side of the
<br>fence, where compilations and one-definition-rules
<br>are rather more static than here. :)
<br>
<br>Sure, this looks plausible, and it probably works in many cases. But
<br>if you COMPILE something with one definition
<br>of a defstruct, then defstruct again, what happens if you try to call
<br>the thing you compiled before?
<br>
<br>I don&#39;t claim to claim it &quot;can&#39;t work&quot;. But I have a =
vague
<br>understanding why there might be a reason for &quot;this might not work=
&quot;.
<br>:P
<br>
<br>As an unsubstantiated rumination, it might be *more* difficult to make
<br>this work in a language that can do dynamic compilation
<br>at any point in a program than it is in a language that is more static
<br>as far as struct definitions and their compilations are concerned.
<br>My architecture-brain can&#39;t tell how you could possibly know where =
all
<br>the &#39;references&#39; to the old defstruct could possibly be,
<br>considering that compilations with the old one and uses of those can
<br>be so dynamic, and where the uses that would expect
<br>the newer redefinitions might be, and how you&#39;d track that.
<br>
<br>Again, I&#39;m not saying this can&#39;t work. I just find it daunting =
to even
<br>ponder what sort of funny situations where your program
<br>manages to confuse itself about which struct is which you can end up
<br>with. Maybe that&#39;s a theoretical problem, but it hurts my brain. :D
<br>
<br></div></div></span></blockquote></div></blockquote></div></div>

--0000000000000ac6dc05e3bbbcc2--