-
-
Notifications
You must be signed in to change notification settings - Fork 1.7k
Description
#8835 proposes a way to have user-definable methods in the macro language that accept and return AST nodes:
macro def foo(x : StringLiteral) : StringLiteral
"foo#{x.id}"
end
{{ foo "x" }} # => "foox"There is a similar concept that would complement this kind of code reuse. We only need to implement ProcLiteral#call, interpreting the literal's entire body as a macro expression:
Foo = ->(x : StringLiteral) : StringLiteral do
"foo#{x.id}"
end
{{ Foo.call "x" }} # => "foox"Parameter and return types are optional as long as the constant is not referenced in normal code; if present, they are assumed to be AST node names and correspondingly typechecked. (Unlike defs, we do not have to care about overloading here.) This is also doable:
Fib = ->(x) { x <= 2 ? 1 : Fib.call(x - 1) + Fib.call(x - 2) }
{{ (1..10).map { |v| Fib.call(v) } }} # => [1, 1, 2, 3, 5, 8, 13, 21, 34, 55]This requires no changes to the language grammar and can be further enhanced by features that make them closer to Procs in normal code, e.g. closures and macro ProcPointers.
Add a 👍 reaction to issues you find important.