Closed jdonszelmann closed 5 months ago
I guess the examples should be targeted at (amateur) compiler engineers rather than scientists? Not necessarily with a degree in PL. That is bound to be a challenge for me 🙃.
The very simplest example I can come up with is a series of calculations, where each intermediate result can be stored in a name. E.g. something like:
x = 2
y = x + 19
z = x * y
With a language like that, we can explain
The structure of the graphs will be really simple: just a sequence of scopes. We can initially skip the regular expression and label order, to make the example as easy as possible.
Perhaps, next, we can extend this example with functions:
fun square(x) = x * x
z = square(6) + 6
Scope Graphs in this language will now actually be trees, instead of linear sequences of scopes.
This allows us to explain:
x
is visible in the body of the function onlyNext, I think we can extend the base language with 'records' (or objects/maps) if you wish.
x = 7
r := {
x = 3
}
z = 2 * x * r.x
These scope graphs will be 'disjoint': forest of nodes.
Using this, we can explain:
The discussion until now does not bother with completeness at all: only backward references are supported.
Perhaps, at this point, we could build a language with a module system (non-nested modules, wildcard imports only). This introduces a lot of complications:
A first version of this tutorial could still not use completeness at all.
At a next tutorial, we could introduce a scheduling mistake, and raise the question how to guard against that. Using that, we should introduce ImplicitClose
, as it only adds simple Result
types, which should be well-known by Rust users, and intuitive at the positions they occur.
At a later point, we can argue that implicit closing is not (always) what you want, and shift via explicit to future.
At this point, I think we have covered all basic building blocks of the framework. So the proposals after this should be comprehensible in any order.
We should also have nested modules somehow. That can explain very well how scope graphs regular expressions and label orders give precise control over name resolution.
We can also add record extension: yet a different example where label orders and regular expressions are imported. Also, record extension is akin to transitive imports.
There should be lots of examples on how to do various things using scopegraphs. Both for every function in the API, as well as for more Higher level patterns (#17)