Prism Mechanics, Part 2
Wed, 06 Jan 1999 02:29:08 -0700
Prism Mechanics, Part II:
I Metamodel Once, But She Didn't Even Look At Me
A big part of Prism is its paradigm-independent semantic
meta-metamodel. In a regular compiler specification, this part would be
the language definition. In the Prism compiler specification, it's not
a language definition, it's a semantic meta-metamodel. (I think I
already said that. :) )
So, what IS a meta-metamodel? Well, look at it this way. We don't ever
directly interact with our programs. They consist of electricity. We
interact with MODELS of our programs... source code. A book I own
defines "model" as "a thing in one domain which reflects, simulates, or
controls a thing in another domain." This is an excellent definition --
the source code, which is in the physical, real-world domain, models the
program, which is in the virtual, computer domain.
Okay, so we deal with models of programs, not the programs themselves.
If we're modelling with source code, what does that mean the programming
language is? Well, it's a METAMODEL. It's a thing which defines what
models we can create... what source code we can write.
If you've ever dealt with BNF notation (Backus-Nauer Form, or something
like that), then you might be wondering -- what's the META-METAMODEL?
What's the thing that defines what LANGUAGES we can create?
I'm not entirely sure of the answer, but in the case of most programming
languages, I think the meta-metamodel is "phrase-structure grammar."
Most programming languages are defined with phrase-structure grammar,
which says that you define a grammar by with a phrase and then the
structure that the phrase represents. It's too much to describe here,
but if you've ever looked at a language grammar, then you've probably
looked at a phrase-structure grammar.
I call this type of meta-metamodel a SYNTACTIC meta-metamodel. That's
because it's entirely focused on syntax. Prism, on the other hand,
defines a SEMANTIC meta-metamodel. It defines a set of data types
(which could roughly be described as "bit," "32 bits," and "map") and
then says that any metamodel may be defined with these data types.
So when you create a domain abstraction in Prism, you're actually
defining a SEMANTIC METAMODEL. You take the three data types Prism's
meta-metamodel gives you and you define how they may be arranged, and
most importantly, you define what meaning each arrangement has.
Let's use an example from the Tunes mailing list: Brian's Arrow
language. Now, I don't claim to completely understand it, but I'll give
it a shot.
You could say that Brian's arrow language is a domain abstraction. So
let's define a metamodel for it. Remember, we can only use the data
types defined in our meta-metamodel. Their actual names are _pBit,
_pBits32, and _pMap. _pBit and _pBits32 are pretty self-explanatory, I
think. _pMap is simply a collection of any data type which is indexed
by a _pBits32. It's like a hash table. Given a _pBits32 datum, you can
get the associated datum out of the _pMap.
One important thing about _pMap is that it can contain other _pMaps.
But it can't contain itself, not even indirectly. Think of the _pMap as
physically containing other _pMaps, not just references to them.
So, Brian's Arrow language would be defined in Prism as follows:
_pMap (Arrow Space)
| * | _pMap (Arrow) |
| | +------+------------------------------+ |
| | | 0..n | _pMap (Slot) | |
| | | n>=1 | +---+----------------------+ | |
| | | | | 0 | _pBit (Empty) | | |
| | | | | 1 | _pBits32 (Reference) | | |
| | | | +---+----------------------+ | |
| | +------+------------------------------+ |
(This is a visual language which I use to describe Prism metamodels.
It's not "the" Prism language, however -- you could define any language
you wanted, as long as it could express everything the Prism
Anyway, when you look at the above diagram, you should see three nested
tables. The outermost table is labeled "Arrow Space," the middle table
is labeled "Arrow," and the innermost table is labeled "Slot." This
diagram completely defines the structure of Brian's arrow language, as
far as I know.
Remember what I said about using the meta-metamodel:
* You take the three data types Prism's meta-metamodel gives you and you
define how they may be arranged, and most importantly, you define what
meaning each arrangement has.
So we've defined how the data types may be arranged. Now we need to
define the meaning of the arrangement. Okay, here goes: (you will
probably need to scroll back up and look at the diagram again from time
Brian's metamodel, "Arrow Space," consists of a nearly unlimited number
of "Arrows." These Arrows may be anywhere within Arrow Space -- that
is, they may have any index.
An Arrow consists of references to other arrows. In the metamodel, this
is represented by Slots. An Arrow consists of two or more Slots. Slots
are contiguous -- that is, the first one is at index 0x0, the second at
0x1, the third at 0x2, etc., without any gaps in the sequence.
A Slot defines a reference to another arrow in Arrow Space. A Slot may
also be Empty, in which case it does not contain a reference. In the
metamodel, if the Empty datum is 1, then the Slot is 'empty' and the
Reference datum is ignored. However, if the Empty datum is 0, then the
Slot is not empty and the Reference datum shall contain the index of an
Arrow in Arrow Space.
That's it! That's how metamodels work in Prism. The meta-metamodel
defines a list of data types, and the metamodel describes how they can
fit together and what they mean. It's like a language specification,
but without the language part. :) When you write a program, you define
specific data types within the constraints of the metamodel.
This is a critical part of Prism. For those of you who are interested
in Prism, please respond if you have any criticisms at all, or if there
are any parts that you don't understand or that seem fishy. Thanks!
Jim Little (email@example.com)
Prism is at http://www.teleport.com/~sphere.