<div dir="ltr">I am following the discussion, although I am still feeling confused about a few parts. I don't have much to add all of this, except fleshing out the "dynamic" approach to solving the problem. Below I touch on what's currently wrong my translation of Grace inheritance into SOMns; and then, I describe a potential solution for resolving inheritance at runtime. It's a terrible idea, but if you are interested it's there - I won't be offended if it's ignored :)<div><br></div><div><div><div><div><br></div><div>Up until now, I had simply translated inherit clauses by invoking the request to create the object to be inherited; then I had used a platform class mirror to obtain the platform class used to create that object; and finally, the installation of the inherited slots, methods, and initer expressions was handled by the platform. That approach was working well in cases where the expressions of the initialization method (of the inherited object) did not refer to the scope enclosing the *declaration* of the inherited object. </div><div><br></div><div>The minigrace tests I was hoping to run include class declarations whose initer expressions refer to an object whose initer expressions need access to the scope enclosing (the inherited) objects declaration. Once I realized my translation was invalid in these situations, I started thinking more about the problem. In particular, I'm completely at a loss for how to translate the "unreversible" methods when requested by inheritance clauses - although from the discussion above it seems I might not need to think about that for some time. Unfortunately, the minigrace tests </div><div><br></div><div>I did think of one dynamic solution that resolves inheritance at run time, but it requires changing Grace's inheritance semantics. Here's the change:</div><div><br></div><div><b>if no inherit expression declared, </b><br></div><div> 1 - make a fresh object</div><div><b>else </b></div><div> 1 - call inherit expression (if found).</div><div> 1.1 invoke the request declared in the inheritance clause</div><div> 1.2 assign the object to self.</div><div><br></div><div>2 - process trait expressions (if found).</div><div><b> for each trait</b></div><div> 2.1 invoke the request declared in the uses clause </div><div> 2.2 add each trait object to a secret slot on the object</div><div> 2.3 add a method alias each method of the trait (can resolve excludes and alias expressions here too) </div><div> </div><div>3 - run the initer expressions </div><div><br></div><div>I've thought about this for about 2 minutes (so not very long) but I can't see how this would necessarily change the behaviour. In particular, (1) all of the initialization expressions `self` still refers to the fresh object and (2) the initialization expressions declared by the inherited object still run in the expected scope (where the inherited object is declared) and (3) the structural type check should work as expected (provided that the secret slots for the traits are ignored). </div><div><br></div><div>Anyway, I get the feeling it might be better to think more about what manifest means and resolve the inheritance at compile time. Or take the OCAML approach (that easy for me at least). Or yet another idea, we could just a fresh object for each trait and superclass, and forwarding messages up the chain when they fail, but then we need to think more carefully about how to manage slots. </div><div><br></div></div></div></div><div class="gmail_extra"><br><div class="gmail_quote">On Wed, Nov 29, 2017 at 11:47 PM, Stefan Marr <span dir="ltr"><<a href="mailto:S.Marr@kent.ac.uk" target="_blank">S.Marr@kent.ac.uk</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">Hi:<br>
<br>
I tried to read up a bit to be able to have an informed opinion on how to coerce SOMns into providing what you need.<br>
But, after a while, I gave up. So, I don’t understand all the details, I am not even sure yet I get the subtle points of your examples.<br>
<br>
To implement this efficiently, I think, Richards “wants” to take SOMns’ object model, or at least the instantiation part, apart and properly adapt it to your needs.<br>
I suppose scoping etc are much easier to get right that way, and the resulting interpreter/object model code is hopefully a more direct representation of your spec. Which hopefully means it is going to be more maintainable in the long run.<br>
<br>
Can it be implemented efficiently? I don’t see why not. The key here seems to be that you require to statically know the shape of the resulting object/class. To me this means the actual object factory can be created lazily on first use, and then be reused.<br>
<br>
<br>
What I don’t really understand is where all the restrictions are supposed to be tested.<br>
<br>
Inheritance is always done via the `inherit` keyword? (I suppose it is a keyword).<br>
<br>
For the evil example, I don’t see an issue. It’s just that one would remember an object has a certain structure, and then error if that’s violated, right?<br>
<br>
What I am not clear about is what’s a fresh object, and how to test for that?<br>
Is that a property of the method? So, I can check method.objectFactoryInTailPosi<wbr>tion == true?<br>
I don’t see how this would work. Grace got late binding, right?<br>
<br>
With respect to scoping, are there restrictions on where the inherit can appear in an object/class?<br>
Is the expression after it restricted somehow?<br>
I suppose that’s what Richard had problems with to properly map to Newspeak.<br>
I guess the best solution would be just to change what SOMns does for Grace, because currently, the relevant expression for Newspeak’s superclass resolution is evaluated strictly outside of the object/class body.<br>
<br>
Not sure this is of much help, for me, this might be better discussed via Skype so I can ask more questions…<br>
<br>
Best regards<br>
Stefan<br>
<div class="m_614753130751421594HOEnZb"><div class="m_614753130751421594h5"><br>
> On 29 Nov 2017, at 09:10, kjx <<a href="mailto:kjx@ecs.vuw.ac.nz" target="_blank">kjx@ecs.vuw.ac.nz</a>> wrote:<br>
><br>
>> A system where methods become inheritable or not based on the values of their arguments seems dubious to me.<br>
><br>
> :-)<br>
><br>
>> (if I can override “random”, evil is no longer reliable).<br>
><br>
> so I should've said I was assuming random here was a module.<br>
> Although (modulo types & exceptions) it's not clear it matters what<br>
> that expression does, so long as it returns a boolean.<br>
><br>
>> def x = object {<br>
>> method p { object { } }<br>
>> }<br>
>> method parent(o) { o.p }<br>
>> object { inherit parent(x) }<br>
><br>
> perhaps.<br>
> arguably, at the top level of a module, this may well meet the definition of inheritable / manifest.<br>
> If you can't override x or parent(_), why is this much worse than<br>
><br>
> object { inherit x.p }<br>
><br>
><br>
>> It also pushes the “cannot be overridden” criterion deeply through the entire potential call stack<br>
><br>
> not sure I follow this.<br>
><br>
>> Otherwise, yes.<br>
><br>
> Umm OK.<br>
><br>
> James<br>
><br>
<br>
</div></div><span class="m_614753130751421594HOEnZb"><font color="#888888">--<br>
Stefan Marr<br>
School of Computing, University of Kent<br>
<a href="http://stefan-marr.de/research/" rel="noreferrer" target="_blank">http://stefan-marr.de/research<wbr>/</a><br>
<br>
<br>
</font></span></blockquote></div><br></div></div>