This change removes some ambiguity that existed in MuIL tokens given the
simplistic naming scheme of only using "/" as a delimiter. We could have
resolved this ambiguity through successive name bindings, but I prefer a
more deterministic approach. A module member token now delimits the
package/module name from the member name by a ":" character, as in
"aws/ec2:VM". Furthermore, when reexporting elements from the current
package/module, we will use the self-referential "." character, as in
".:VM".
The stacks.md document used to describe the metadata format. Now that we've
moved away from the old model of YAML + Go templates, and created the MuPack/MuIL
format, this document needed to be overhauled.
It's pretty bare bones now, however it will eventually evolve into a document
describing how the Mu abstractions map down onto MuPack/MuIL concepts. For example,
it describes how subclassing mu.Stack creates a "stack", even though at the MuPack/MuIL
level it's just any old subclass.
Some say the world will end in fire,
Some say in ice.
From what I've tasted of desire
I hold with those who favor fire.
But if it had to perish twice,
I think I know enough of hate
To say that for destruction ice
Is also great
And would suffice.
This change adopts some standard aspects of classes, like statics, abstract,
and virtuals (sealing). It also recognizes records and interfaces as explicit
annotations on classes (both of which can be called "conjurable"); they were
already being treated specially with respect to structural/duck conversions,
and I always hate inferring defining properties of types like this, since simple
edits can completely change the type's semantics and break consumers of it.
This change articulates Mu's packaging format, MuPack, along with its
corresponding intermediate language and type system, MuIL. This is very
much a work in progress.
This documents our latest thinking on Mu languages. At a high level,
there are three classes of language at play:
1. Mu Metadata Languages (MuML): these are the high-level language
subsets that a programmer uses to specify Mu modules, etc. Examples
include MuJS, MuPy, MuRu, and MyGo, each representing a deterministic
subset of JavaScript, Python, Ruby, and Go, respectively.
2. Mu Intermediate Language (MuIL): this is the intermediate form that
all of the above compile down to. It is capable of representing
computations like functions, conditionals, and basic expressions like
string concatenation, etc. This is fully statically analyzable and
can be used to create deterministic plans and topology graphs.
3. Mu Graph Language (MuGL): this is the "final" form in which any Mu
service topology is represented. It never contains computations and
is merely a metadata description of services-as-nodes, dependencies-as-
edges, and all known properties. In the planning form, it may contain
"holes" because output properties aren't known until execution has
occurred, while in the actual applied form, those holes have been
plugged. MuGLs can be diffed, and a MuGL can be generated from an
existing live environment (for bootstrapping and/or drift analysis).
There are several TODOs in here, but this is braindump of where we're at.