Hi Ralf,<div><br></div><div>Sorry for the late response. I've been really busy improving some other parts of ABCL which consumed all my time.<br><div class="gmail_quote"><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
<div bgcolor="#FFFFFF"><div class="im"><blockquote type="cite"><div class="gmail_quote"><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">This slot accessor is not to be generated again for "c", of course, as you said. The strange thing this is that, in principle, foo-s1 is not applicable to instances of "a", but to instances of "b" and "c" only. Since new sub-structures of "a" (with conc-name foo-) can be defined at any time, the type for the applicable structures used in the implementation of foo-s1 cannot be statically encoded but must be dynamically determined, or the code for foo-s1 could be dynamically adapted for every new sub-defstruct of "a" with conc-name foo-. I tend to believe this is not easy to implement.</blockquote>
<div><br></div><div>Actually, it's really easy to implement. </div></div></blockquote><div><br></div></div><div>I am afraid, using defmethod for the non-optimized case is not that easy because not all defstructs are necessarily compiled with the same optimization settings (e.g., they might be located in different files). In addition, one has to remove methods if a defstruct is recompiled with other slots or with different optimization settings..... :-(</div>
</div></blockquote><div><br></div><div>The part about the accessors being defined in different files with different optimization strategies: that's correct. However, it's not the context of the definer, but the context of the user which causes the optimized or non-optimized code path to be used.</div>
<div><br></div><div>With respect to recompilation/redefinition of a defstruct: the spec says you can't do that, or at least, you can't portably depend on that ("<span style="font-family:'Times New Roman';font-size:medium">The consequences of redefining a </span><a rel="DEFINITION" href="http://www.lispworks.com/documentation/HyperSpec/Body/m_defstr.htm#defstruct" style="font-family:'Times New Roman';font-size:medium"><b>defstruct</b></a><span style="font-family:'Times New Roman';font-size:medium"> structure are undefined."</span>). ABCL allows it, under certain strict conditions, but it's not required to and doesn't support any "interesting" cases (ie changes in the number of slots).</div>
<div>But the case of method removal is easy: when a defmethod is evaluated, it will cause the original method with the same specializers to be overwritten. That, combined with the explanation that all accessors are always generated (but only sometimes used), should solve it.</div>
<div> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div bgcolor="#FFFFFF"><div class="im"><blockquote type="cite"><div class="gmail_quote"><div>But the runtime cost of doing so is huge, unfortunately: we can simply use DEFMETHOD to define the accessors. That will automatically notice the accessor is already defined and add a method for each additionally defined type.</div>
<div><br></div></div></blockquote></div></div></blockquote><div>[ snip ] </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div bgcolor="#FFFFFF"><div class="im">
<blockquote type="cite"><div class="gmail_quote"><div></div><div>I see multiple options:</div><div><br></div><div>1. Remove the type checks in the inline expansions</div><div> and use DEFMETHOD for the accessor functions, where we need to use the methods</div>
<div> only with sufficiently high SAFETY declarations</div>
<div>2. Use your patch to remove the type checks completely</div><div>3. Come up with a way to add dynamic type checks to the inline expansions and function definitions (ie not methods) - possibly executed conditionally with safety settings.</div>
<div>4. Do nothing (not saying it's a good option, but it's always an option)</div><div><br></div><div>Do you see any others?</div></div></blockquote></div></div></blockquote><div>Actually, I see one other solution, now that I had some time to think about it: we could trace back to the original type and be lenient and allow all descendants of that type access to the slot using the generated slot. That would allow both structures B and C to be read. According to the spec that's too lenient though:</div>
<div><br></div></div></div><blockquote style="margin:0 0 0 40px;border:none;padding:0px"><div><div class="gmail_quote"><div><span style="font-family:'Times New Roman';font-size:medium">The difference between the </span><a rel="DEFINITION" href="http://www.lispworks.com/documentation/HyperSpec/Body/26_glo_r.htm#reader" style="font-family:'Times New Roman';font-size:medium"><i>reader</i></a><span style="font-family:'Times New Roman';font-size:medium"> functions </span><tt>person-name</tt><span style="font-family:'Times New Roman';font-size:medium"> and </span><tt>astro-name</tt><span style="font-family:'Times New Roman';font-size:medium"> is that </span><tt>person-name</tt><span style="font-family:'Times New Roman';font-size:medium"> can be correctly applied to any </span><tt>person</tt><span style="font-family:'Times New Roman';font-size:medium">, including an</span><tt>astronaut</tt><span style="font-family:'Times New Roman';font-size:medium">, while </span><tt>astro-name</tt><span style="font-family:'Times New Roman';font-size:medium"> can be correctly applied only to an </span><tt>astronaut</tt><span style="font-family:'Times New Roman';font-size:medium">. An implementation might check for incorrect use of </span><a rel="DEFINITION" href="http://www.lispworks.com/documentation/HyperSpec/Body/26_glo_r.htm#reader" style="font-family:'Times New Roman';font-size:medium"><i>reader</i></a><span style="font-family:'Times New Roman';font-size:medium"> functions.</span>
</div></div></div></blockquote><font face="arial, helvetica, sans-serif">where "name" is a slot in the 'person' structure which is included in the 'astronaut' structure. </font><div><font face="arial, helvetica, sans-serif">Just to see what other implementations do: I ran this code on clisp (2.47) and it generates the same error. Apparently, the spec doesn't define this case and you can't depend on exact behaviour; the only thing I <i>can</i> find is a section on the relation between including and included structures, not between syblings:</font></div>
<div><font face="arial, helvetica, sans-serif"><br></font></div><blockquote style="margin:0 0 0 40px;border:none;padding:0px"><div><span style="font-family:'Times New Roman';font-size:medium">Whether or not the </span><tt>:conc-name</tt><span style="font-family:'Times New Roman';font-size:medium"> option is explicitly supplied, the following rule governs name conflicts of generated </span><a rel="DEFINITION" href="http://www.lispworks.com/documentation/HyperSpec/Body/26_glo_r.htm#reader" style="font-family:'Times New Roman';font-size:medium"><i>reader</i></a><span style="font-family:'Times New Roman';font-size:medium"> (or </span><a rel="DEFINITION" href="http://www.lispworks.com/documentation/HyperSpec/Body/26_glo_a.htm#accessor" style="font-family:'Times New Roman';font-size:medium"><i>accessor</i></a><span style="font-family:'Times New Roman';font-size:medium">) names: For any </span><a rel="DEFINITION" href="http://www.lispworks.com/documentation/HyperSpec/Body/26_glo_s.htm#structure" style="font-family:'Times New Roman';font-size:medium"><i>structure</i></a><span style="font-family:'Times New Roman';font-size:medium"></span><a rel="DEFINITION" href="http://www.lispworks.com/documentation/HyperSpec/Body/26_glo_t.htm#type" style="font-family:'Times New Roman';font-size:medium"><i>type</i></a><span style="font-family:'Times New Roman';font-size:medium"> S1 having a </span><a rel="DEFINITION" href="http://www.lispworks.com/documentation/HyperSpec/Body/26_glo_r.htm#reader" style="font-family:'Times New Roman';font-size:medium"><i>reader</i></a><span style="font-family:'Times New Roman';font-size:medium"> function named R for a slot named X1 that is inherited by another </span><a rel="DEFINITION" href="http://www.lispworks.com/documentation/HyperSpec/Body/26_glo_s.htm#structure" style="font-family:'Times New Roman';font-size:medium"><i>structure</i></a><span style="font-family:'Times New Roman';font-size:medium"> </span><a rel="DEFINITION" href="http://www.lispworks.com/documentation/HyperSpec/Body/26_glo_t.htm#type" style="font-family:'Times New Roman';font-size:medium"><i>type</i></a><span style="font-family:'Times New Roman';font-size:medium"> S2 that would have a </span><a rel="DEFINITION" href="http://www.lispworks.com/documentation/HyperSpec/Body/26_glo_r.htm#reader" style="font-family:'Times New Roman';font-size:medium"><i>reader</i></a><span style="font-family:'Times New Roman';font-size:medium"> function with the same name R for a slot named X2, no definition for R is generated by the definition of S2; instead, the definition of R is inherited from the definition of S1. (In such a case, if X1 and X2 are different slots, the </span><a rel="DEFINITION" href="http://www.lispworks.com/documentation/HyperSpec/Body/26_glo_i.htm#implementation" style="font-family:'Times New Roman';font-size:medium"><i>implementation</i></a><span style="font-family:'Times New Roman';font-size:medium"> might signal a style warning.)</span>
</div></blockquote><div><div class="gmail_quote"><div><br></div><div>Which suggests that if you used FOO- for the nconc of the A structure as well, that all should be defined and well. Testing that on clisp and ABCL shows that it indeed is.</div>
<blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div bgcolor="#FFFFFF"><div class="im"><blockquote type="cite"><div class="gmail_quote"><div> I'm not sure about the performance impact of dynamic checks, but I do think that if we decide to apply a caching strategy, using the slow-path of updating the cache in case of a type-mismatch, the impact may not be much worse than it is today. After all, the biggest change would be to generate code which allows to check more than one type instead of the current single type.</div>
</div></blockquote></div></div></blockquote><div>Given the performance impact of more complicated checks and the fact that structures are supposed to be geared for high performance (with classes being their flexible counter parts) *and* with the support (for my point) that I find in the spec and "other implementations" (i.e. clisp), I'd rather keep things the way they are at this time, although I'm open to input of the other developers of course.</div>
<div><br></div><div>Is it a solution for you to add the FOO- conc-name option to the A class as well?</div><div><br></div><div><br></div><div>Bye,</div><div><br></div><div>Erik.</div></div></div>