masak / alma

ALgoloid with MAcros -- a language with Algol-family syntax where macros take center stage
Artistic License 2.0
138 stars 15 forks source link

BEGIN blocks in quasi blocks run too early #216

Open masak opened 7 years ago

masak commented 7 years ago

Hey, this is a funny one:

$ bin/007 -e='macro moo(x) { return quasi { BEGIN { say({{{x}}}) } } }'
Should never hit an unquote at runtime
[...]

The error message is of the "this situation is impossible and should never happen" variety. BEGIN blocks should by their nature run ASAP, which is usually just as we parse the } of the BEGIN block.

But not in this case, because of the unquote inside of it. It needs to wait until it's expanded in real code somewhere. (I asked #perl6 whether we expect the BEGIN block to fire only at the first expansion, or at each one.)

Just to be clear, here's the expected semantics:

masak commented 7 years ago

Actually, after some further discussion on #perl6, TimToady surprisingly supported (and arnsholt and vendethiel champion) the approach of letting all BEGIN blocks defer until expansion time. (Even ones that don't have unquotes.)

As I pointed out, it's all about which type of consistency we prefer. So I'm fine with always deferring the BEGIN blocks. On reflection, that might be easier both to implement and to explain than the alternative.

vendethiel commented 7 years ago

sorry I hadn't replied earlier. I'm indeed in the camp of "always defer until expansion time". I don't see BEGIN as very different from a macro that evals its ast, tbh.

masak commented 7 years ago

That's an interesting interpretation of BEGIN. Hadn't thought of it that way.

Unfortunately, there's no way to express that in pure 007. The closest I get is "hand the AST to an ambient runtime", which sort of comes down to the same thing:

macro statement:<BEGIN>(block_ast) is parsed /"BEGIN" <block> <.eat_terminator>/ {
    runtime.run(block_ast);
}
masak commented 5 years ago

That <.eat_terminator> shouldn't be there; that's handled on the statementlist level.

masak commented 5 years ago

Coming back to this issue done two years later, I'm happy to report that my brain has now been so warped by macro thinking that I'm also fully in the "always defer until expansion time" camp. (Ping @vendethiel.) I think what swayed me was the realization (covered at length here and then elaborated in #334) that quasis are not code and unquotes are not Qnodes.

masak commented 5 years ago

Also, shout-out to #467.

vendethiel commented 5 years ago

(Ping @vendethiel.)

I think I once said defmacro BEGIN(x) { melt(x); } ;-).