c3d / xl

A minimalist, general-purpose programming language based on meta-programming and parse tree rewrites
GNU General Public License v3.0
270 stars 15 forks source link

Implement metabox notation #10

Open c3d opened 4 years ago

c3d commented 4 years ago

Historically, XL implemented a rule that in patterns, any name that was already visible was seen as a constant. This allowed the following definition of if statements to work as long as true and false were in scope:

if true then X else Y is X
if false then X else Y is Y

The three main problems with this approach were that:

These three problems are solved in the documentation by introducing the notion of metabox. A metabox is written as [[Expr]] and evaluates to Expr in all contexts. With the metabox notation, the proper definition for if becomes:

if [[true]] then X else Y is X
if [[false]] then X else Y is Y

The previous definition will indeed make true a formal parameter.

The metabox notation can also be used in normal evaluation context in cases where evaluation of an expression must be forced. This is the case with the definition of the for loop:

for N:name in R:[range of discrete] loop Body is 
    loop_context is 
        [[N]] : R.type := R.first 
    LoopVar is loop_context.[[N]] 
    while LoopVar <= R.last loop
        (loop_context) (Body) 
        ++LoopVar 

Here, N is a name parameter, which may contain for example I when the pattern matches

for I in 1..5 loop
    print "I=", I

If loop_context was written as:

    loop_context is 
        N : R.type := R.first 

N would not be evaluated in a type annotation, but instead would create a local variable named N.

Similarly, the expression loop_context.N would not evaluate N but look it up in loop_context, where it does not exist since the variable there is called I. Using the metabox forces N to be evaluated, so that this transforms into loop_context.I, which will find I.

Metabox are a recent addition to the language are are not implemented neither in the compiler nor the interpreter.