As a 'seasoned' Rebol developer with some knowledge of the world outside, I'd be curious as to the utility/pitfalls of implementing Lisp-style macros in Rebol (and/or Red).
My understanding (always happy to revise) is that Lisp is able to preprocess code prior to evaluation/compilation, modifying that code according to the rules of the applicable macros. This can allow for more complex/expressive statements than otherwise, with efficiencies as those statements are expanded only once as a body of code is loaded. The macro rules themselves are relatively straightforward as the homoiconicity of Lisp allows the code to be manipulated by the same terms one would modify data.
As Rebol is also a homoiconic language, it stands that it too could accommodate macros between loading and evaluation with similarly expressive transformation grammar (though I'd posit that Rebol's more freeform evaluation model—statements not generally bound by parentheses—makes it harder to identify the portions of code to be transformed).
My own inclination is that in the main, macros aren't really necessary in Rebol—you can already create complex code structures that are fairly efficient, and where more efficiency is desired, Rebol has the capabilities to accommodate without significant loss of expressivity. On the other had, 'fairly' and 'no significant loss' could be considered weasel words and macros do offer an efficiency/expressivity bump, but at what implementation cost?
Also, as in Rebol you can load code prior to evaluation, it would be possible to implement a mechanism for load-expand-evaluate at the user-level permitting third-party macro implementations.
This post is partly a response to this question and everything (pretty much) I know about macros comes from this exchange.
Update
Red introduced a rudimentary macro system in version 0.6.2. I have used them effectively to create cross-compatible scripts that target both the Ren-C branch of Rebol 3 and Red.
Best Answer
This is the first time I hear about Rebol, but from a quick look at the Wikipedia page it seems to me that Rebol dialects are just like Lisp macros: they both receive ordinary code of the language that has passed lexical and syntactic(but not semantic!) processing, and process it with their own semantical rules.
So, Rebol will not benefit from Lisp macros, because it already has that feature under a different name, and having two core-language features that do exactly the same thing is bad - especially for languages that rely on Homoiconicity, where uniform simplicity in the syntax is the key to their magic.
Update
The asker explainer in the comments that macros have the advantage that they are expanded once, before the code execution, and injected into the code.
This, IMO, will make things worse, because it would mess up the order of parsing!
For example, let's say we have the Rebol command
foo x bar y
, wherefoo
is a dialect andbar
is a macro. What should the interpreter do? Depends onfoo
's arit:foo
accepts a single argument, that means we have two commands:foo x
andbar y
. Sobar y
needs to be expanded.foo
accepts three arguments, that means that we have one command, andbar
is the second argument offoo
. This meansbar
shouldn't be expanded, and instead passed tofoo
as-is.The rules are clear - for a human, and probably for static compilers as well. But Rebol is dynamic and interpreted, so
foo
is only evaluated when it needs to be executed - butbar
should be expanded before that happens! So now the interpreted needs to evaluate the dialects before it expands the macros, so it can expand the macros before it evaluated the dialect, and round and round the interpreted goes trying to resolve the circle...Lisp doesn't have this problem, because:
foo x bar y
- you need to either have(foo x bar y)
or(foo x) (bar y)
or even(foo x (bar y))
, so it's easy for the interpreter to know what you are trying to do.foo
was a function,foo x bar y
would require the interpreter to first evaluatex
,bar
andy
, and sincebar
is a macro it would have expanded regardless offoo
's arity, becausefoo
has no control whatsoever on the evaluation of it's arguments.