← Back to context

Comment by tooltower

5 years ago

I wonder how well it handles or rejects syntax-level expansions. E.g. can the outer language produce half an expression for the next level? Do I need to worry about the common pitfalls of macros?

I hope this works out. C++ has been deliberately evolving in the same direction, e.g. using `if constexpr` for conditional compilation. Plus, since the C++ compiler is aware of both levels of the language, it can catch some errors even for compilation paths not taken.

But the C++ syntax for metaprogramming still leaves a fair bit to be desired. So I like that folks are still experimenting in this area.

Terra macros are hygenic in the sense that they follow the Lua scoping rules. So if you do:

    local add1 = macro(function()
      return `x+1
    end)
    terra()
      var x = 12
      add1()
    end

Then this will give you an error because x is not in scope in the add1 macro.

Instead you'd have to write:

    local add1 = macro(function(y)
      return `y+1
    end)
    terra()
      var x = 12
      add1(x)
    end

Note that I changed the variable name to clarify that only the lexical scope matters (i.e., "x" is a symbol passed to the function as argument y).

You should be able to create towers of languages in Terra. I'm not sure if anyone really does more than 2 levels in practice, but most of the common Terra DSLs are basically written as code generators on top of Terra language expressions.

See e.g. the Regent code generator. Here's an example of some nested metaprogramming---not with a nested language or macros, but with an escape that calls a Lua function to generate more code based on the type of the argument:

https://github.com/StanfordLegion/legion/blob/0cf9ddd60c227c...