Skip to main content
Commonmark migration
Source Link

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

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, where foo is a dialect and bar is a macro. What should the interpreter do? Depends on foo's arit:

  • If foo accepts a single argument, that means we have two commands: foo x and bar y. So bar y needs to be expanded.
  • If foo accepts three arguments, that means that we have one command, and bar is the second argument of foo. This means bar shouldn't be expanded, and instead passed to foo 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 - but bar 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:

  • It's easy to know where a function/macro begins, because you need to put them in parenthesis. You can't have 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.
  • Lisp doesn't have dialects - only functions and macros. And since functions don't control the evaluation of their arguments - macros always evaluate themselves. If Rebol didn't have dialects, and foo was a function, foo x bar y would require the interpreter to first evaluate x, bar and y, and since bar is a macro it would have expanded regardless of foo's arity, because foo has no control whatsoever on the evaluation of it's arguments.

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, where foo is a dialect and bar is a macro. What should the interpreter do? Depends on foo's arit:

  • If foo accepts a single argument, that means we have two commands: foo x and bar y. So bar y needs to be expanded.
  • If foo accepts three arguments, that means that we have one command, and bar is the second argument of foo. This means bar shouldn't be expanded, and instead passed to foo 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 - but bar 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:

  • It's easy to know where a function/macro begins, because you need to put them in parenthesis. You can't have 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.
  • Lisp doesn't have dialects - only functions and macros. And since functions don't control the evaluation of their arguments - macros always evaluate themselves. If Rebol didn't have dialects, and foo was a function, foo x bar y would require the interpreter to first evaluate x, bar and y, and since bar is a macro it would have expanded regardless of foo's arity, because foo has no control whatsoever on the evaluation of it's arguments.

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, where foo is a dialect and bar is a macro. What should the interpreter do? Depends on foo's arit:

  • If foo accepts a single argument, that means we have two commands: foo x and bar y. So bar y needs to be expanded.
  • If foo accepts three arguments, that means that we have one command, and bar is the second argument of foo. This means bar shouldn't be expanded, and instead passed to foo 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 - but bar 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:

  • It's easy to know where a function/macro begins, because you need to put them in parenthesis. You can't have 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.
  • Lisp doesn't have dialects - only functions and macros. And since functions don't control the evaluation of their arguments - macros always evaluate themselves. If Rebol didn't have dialects, and foo was a function, foo x bar y would require the interpreter to first evaluate x, bar and y, and since bar is a macro it would have expanded regardless of foo's arity, because foo has no control whatsoever on the evaluation of it's arguments.
added 1980 characters in body
Source Link
Idan Arye
  • 12.1k
  • 33
  • 43

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, where foo is a dialect and bar is a macro. What should the interpreter do? Depends on foo's arit:

  • If foo accepts a single argument, that means we have two commands: foo x and bar y. So bar y needs to be expanded.
  • If foo accepts three arguments, that means that we have one command, and bar is the second argument of foo. This means bar shouldn't be expanded, and instead passed to foo 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 - but bar 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:

  • It's easy to know where a function/macro begins, because you need to put them in parenthesis. You can't have 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.
  • Lisp doesn't have dialects - only functions and macros. And since functions don't control the evaluation of their arguments - macros always evaluate themselves. If Rebol didn't have dialects, and foo was a function, foo x bar y would require the interpreter to first evaluate x, bar and y, and since bar is a macro it would have expanded regardless of foo's arity, because foo has no control whatsoever on the evaluation of it's arguments.

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.

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, where foo is a dialect and bar is a macro. What should the interpreter do? Depends on foo's arit:

  • If foo accepts a single argument, that means we have two commands: foo x and bar y. So bar y needs to be expanded.
  • If foo accepts three arguments, that means that we have one command, and bar is the second argument of foo. This means bar shouldn't be expanded, and instead passed to foo 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 - but bar 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:

  • It's easy to know where a function/macro begins, because you need to put them in parenthesis. You can't have 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.
  • Lisp doesn't have dialects - only functions and macros. And since functions don't control the evaluation of their arguments - macros always evaluate themselves. If Rebol didn't have dialects, and foo was a function, foo x bar y would require the interpreter to first evaluate x, bar and y, and since bar is a macro it would have expanded regardless of foo's arity, because foo has no control whatsoever on the evaluation of it's arguments.
Source Link
Idan Arye
  • 12.1k
  • 33
  • 43

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.