-
Notifications
You must be signed in to change notification settings - Fork 31
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Rules for language composition and extension #218
Comments
Thanks Elias! Comments
So, this issue is really about if we should restrict the above definition of language extension or not? Because, as it is written now, it sounds like exactly what I need. At the moment, I believe language extension is really (correct me if I'm wrong) the same as language union in the implementation. That is,
is really
I guess you meant "only one of L2 and L3"? Motivating use caseThe reason for why I brought up this topic is the following simple use case: I have implemented an ANF transformation over MExpr terms, which uses a semantic function
with
in (The above is a bit simplified compared to the actual implementation which composes many language fragments to form |
@dlunde: I agree that this sounds like a fit for your use-case.
Yes, that is exactly right!
Oops! Edited... |
In yesterday's meeting we discussed the issue of overriding cases in semantic functions. Consider the following program:
In our current implementation, this fails because it's not possible to decide which of the
0
patterns that are most specific (i.e. we can't decide which of the branches to pick ifL2.f
is passed0
). Arguably, there are cases where it is useful to override patterns -- but it is also, to paraphrase @elegios, a potential foot canon. This issue is for discussing the semantics of language composition so that we can get closer to a design that is both sound and useful.In @david-broman's "A Vision of Miking" paper, there is an abstract description of language composition which distinguishes between language union
L1 U L2
and language extensionL1 <| L2
. Intuitively, the union between two languages combines the constructors of datatypes and cases of semantic functions so that the resulting language can use constructs from them both. Importantly, the two languages in a union are disjoint, meaning there is no overlap in constructors or cases. In a language extensionL1 <| L2
,L2
knows about the constructors and functions inL1
and can extend it, e.g. via product extension of constructors or by overriding semantic functions. A good place to start this discussion is the properties of these two operations:U
is associative, meaning that(L1 U L2) U L3 = L1 U (L2 U L3)
. Note that if any two of the languages are not disjoint the composition is malformed in both cases.U
is commutative, meaning thatL1 U L2 = L2 U L1
.Because the semantics of
<|
is not as clear, it is harder to say if it is associative. It is definitely not commutative, as inL1 <| L2
L2
knows aboutL1
but not the other way around. I will leave the question of associativity open for now.Intuitively, we should have a distributivity law stating that
(L1 <| L3) U L2 = (L1 U L2) <| L3
wheneverL3
does not mention any constructors or cases inL2
(on the lefthand side this is trivially true, but not on the righthand side).In our implementation we have
+
which works likeU
above. The extension operator is implicit in that when we writewe can think of it as "inlining" the extension as
lang L3 = (L1 + L2) <| { sem foo ... }
. Going back to our initial example then, the definition ofL2
should be fine as we are extendingL1
with the new case for the functionf
. However, the following composition should still fail:The same reasoning lets us avoid the "diamond of death" from languages with multiple inheritance:
The situation is not as clear if only one of
L2
andL3
overrides a case:Here
L2
"inherits" the implementation off
fromL1
without changing it. The question is then if the unionL2 + L3
should be disallowed because they have different semantics forf 0
, or if it should be allowed and understood as the override fromL2
taking precedence because both versions off
have the same provenance. My personal preference is for the former case, but I can see a point in the latter as well.Finally, I want to mention that @elegios argued for having an explicit syntax for overriding cases to avoid accidentally overriding the case of an included language.
The text was updated successfully, but these errors were encountered: