Closed kjx closed 6 years ago
Yes, you basically have the right idea, and this is basically what minigrace currently does. The differences are:
alias
and exclude
, so there are three extra parameters to each method, not one. (These extra parameters can't be optional, because the type parameters are already optional).But this has nothing at all to do with the issue at hand, which is whether we should or should not require the shape of the object produced by a constructor to be statically known. At least, I thought that was the issue at hand ... it seems to be getting lost in implementation concerns, which are not even in scope for this issue tracker! If we discard that restriction, we have "Delft Grace" — the language defined by Eelco and Vlad in their SPLASH paper. This language requires that name resolution be deferred until runtime, because it's not until runtime that one knows what methods are in self. For example, the binding of if(_)then(_)else(_)
is now dynamic. Of course, as Ungar demonstrated with the Self language, it is possible to get reasonable performance for such a language by inventing the techniques of JIT compilation ... I didn't think that we were in that business. Note also that our semantics is inherently trickier to implement than NewSpeak's — we have to find the set of all resolutions, and complain if it isn't a singleton set, whereas NewSpeak needs to find just the first (in some ordering).
Yes, you basically have the right idea, and this is basically what minigrace currently does.
Apparently this is what Kernan used to do, before alias & exclude went in. I take it you mean "this is minigrace's intended semantics" because this description is rather different from how I understand minigrace implements things.
You have forgotten about alias and exclude
I haven't forgotten about them - I just left them out - along with multiple inheritance / traits, default methods, overriding, structure errors, and no doubt some other stuff as well. I may try to write out do a version somehow including the lot --- Tim's semantics didn't, I don't know about the SPOOFAX version (although I should also read up on that too).
This is also making me realise again that we have quite a complicated design, with lots of twisty little corners.
But this has nothing at all to do with the issue at hand, which is whether we should or should not require the shape of the object produced by a constructor to be statically known. At least, I thought that was the issue at hand
I think it's one of the issues at hand. (Perhaps I'm broadening my crusade.) For example, if we could only come up good description of the semantics incorporating the statically known restriction, then that would mean the restriction was fundamental and we didn't have a choice. My description above omits a bunch of stuff, including the manifest restriction --- but adding that restriction into this description of the semantics would just make the semantics appear more complex to me, not less.
If we discard that restriction, we have "Delft Grace" — the language defined by Eelco and Vlad in their SPLASH paper. This language requires that name resolution be deferred until runtime, because it's not until runtime that one knows what methods are in self. For example, the binding of if()then()else(_) is now dynamic.
I don't see why: you always know at compile time what is in your lexical scope. Without a manifest superclass, you can't catch a bunch of errors with self requests - but without static types, you can't catch a bunch of errors with receiver requests. Either way, the operational semantics are clear, and a dialect checker could enforce manifest requirements and then do the checks if it wanted.
... it seems to be getting lost in implementation concerns, which are not even in scope for this issue tracker!
I'm trying to stay away from implementation concerns --- although I think implementation assumptions lurk more closely behind our decisions than I often realise.
Of course, as Ungar demonstrated with the Self language, it is possible to get reasonable performance for such a language by inventing the techniques of JIT compilation ... I didn't think that we were in that business.
Moth is explicitly in that business - that's the point of running on top of Truffle. Now that your minigrace no longer supports the C backend, the only implementations we have or that are on the horizon are also in that business: minigrace and hopper (such as it is) on JS, Kernan on CLR or JS, potentially another try at RPython if I can find another gullible student. So yes there is an architectural question here, but in Grace, that goes to the architecture of the specification as well as the implementation: how much is in the language core vs how much is implemented in dialects & checkers.
I've been thinking about inheritance again. Tim's models in this thesis and the ECOOP papers work OK in a calculus (reducing to a literal object constructor) but I thought I'd like a more practical operational version, something that would capture the minimum necessary restrictions essential in full Grace.
Note that: