|
6macros: discussing the finer points of Perl 6 macros, Qtrees, and how to stay sane | irclog: irclog.perlgeek.de/6macros/today Set by moderator on 28 July 2015. |
|||
|
02:57
ilbot3 joined
09:10
cgfbee joined
09:25
cgfbee joined
09:45
Ven`` joined
|
|||
| Ven`` | masak: are you not gonna say? :) | 09:46 | |
| masak | I explained it to sergot in privmsg the other day. let me make you a gist | 10:38 | |
| Ven``: gist.github.com/masak/4ed7ec0fe455...eb20cb113a | 10:43 | ||
| Ven`` | oh, ok. it's been a while since I've seen sergot write here. | 10:44 | |
| OK, I see | 10:46 | ||
| masak | makes sense? | 10:47 | |
| I still rope sergot++ in via privmsg quite a lot. he doesn't have a lot of time to hack on 007, but he's often available as a sounding-board | |||
| Ven`` | sure, makes sense. | 10:49 | |
| masak | I'm still not 100% sure of what the "new thing" is, the one that has a different $.outer-frame each time | 10:58 | |
| Ven`` | I still feel like this is one of those self-inflicted issues by choosing to do it "The Perl Way". | 11:08 | |
| 14:36 <masak> to make that clear, if we don't do anything about that, the output would be "1\\nNone\\n" 14:37 <masak> because at compile time, the value of `z` is None | |||
| that really ought to be irrelevant. in `macro moo(z){} var y = 2; moo(z)`, what we pass to moo isn't 2. it's a "variable" | 11:09 | ||
| I'm not sure I agree with the foo/bar nested sub examples. There's nothing to "refresh", unless we suppose "our" semantics. | 11:13 | ||
| (and I've always been vocal about forbidding our subs in subs, method in method, etc) | |||
| masak | ok, one thing at a time | 11:31 | |
| first off, I had no idea you were against subs in subs. I find it hard to imagine a world without them. I have no idea why you would want to forbid them. | 11:32 | ||
| yes, of course we're taking on self-inflicted issues by choosing to do it The Perl Way. that's basically the whole raison d'ĆŖtre for 007 ;) | 11:33 | ||
| if I just wanted to do Lisp macros the Lisp way, we'd been done a long time ago | |||
| I disagree on a factual basis with "There's nothing to 'refresh'", and I'm willing to back it up with proof | 11:34 | ||
| in fact, that last bit feels like the most pressing one to find common ground on, if you're up for it | 11:35 | ||
| conceptually, even though that's not at all the implementation in 007, named subs are "hoisted", like in JavaScript. which is why you can call a sub before its declaration. | 11:36 | ||
| and so `sub bar() { say(y) }` is equivalent to `my bar = sub() { say(y) };`, except that the code inside `foo` becomes more equivalent to `my y; my bar = sub() { say(y) }; y = x + 1; return bar;` | 11:38 | ||
| either way, `bar` refreshes because it gets assigned every time on `foo` entry. which is twice in the example in question. | 11:39 | ||
| Ven`` | masak: I'm against *our* subs in subs. The keyword "our"/ | 11:48 | |
| not the english word "our". | 11:49 | ||
| masak | ah | 11:52 | |
| sorry, missed the "our" in there | |||
| now it makes a whole lot more sense | |||
| yes, all sane people are against `our` subs in subs. can't put a bigger thing in a smaller thing, after all | |||
| methods in methods are dubious, I agree. I don't really know how I feel about them. they won't be syntactically allowed in 007 ;) | 11:53 | ||
| but I do maintain there is something to refresh, as above | 11:54 | ||
| S04 even has a long section on it, `=head1 When is a closure not a closure` | 11:55 | ||
| Ven`` | by hoisted, you mean that `my x = 1; sub bar { say(x) }` becomes `my x; sub bar { say(x) }; x = 1;`? | ||
| masak | aye | ||
| Ven`` | right | ||
| masak | but more than that | ||
| there's an *assignment* in there, to `bar` | |||
| Ven`` | it means you can actually do `bar(); sub bar {print(1); }` then? | ||
| oh yeah, i forgot to rewrite the assignment | 11:56 | ||
| masak | yes, you can call before defining. it's worked in 007 for ages. try it. | ||
| the assignment is the important bit, because it happens once per `foo` call | |||
| Ven`` | well, JS hoists every single declaration. I sometimes get caught trying to cheat when writing lua. | ||
| the foo is the outer sub, aye? | 11:57 | ||
| masak | the only thing that gets hoisted in 007 is statement subs | ||
| aye | |||
| Ven`` | that's where we disagree, then. I don't believe in "reusing" structure. | ||
| I'm not sure I can explain this properly. But what you say sounds wrong to me on a fundamental level, because it assumes that there's a "bar" that lives, even after foo returns | |||
| masak | not the name, but the value in that variable, absolutely | 11:58 | |
| Ven`` | yes, but the *variable* surviving makes no sense to me. | ||
| masak | it's a functional value, which in this case means function + environment | ||
| I'm not talking about the variable surviving. maybe we're still at cross purposes | |||
| I'm talking about the mechanism behind the thing in `bar` knowing its OUTER | |||
| Ven`` | i'm saying there's a new bar every single time that foo is called. | 11:59 | |
| masak | well, yes and no | ||
| Ven`` | so there's nothing to "refresh", because bar was created when foo was entered, and thus keeps its everything | ||
| masak | there's only ever one declaration in the code | ||
| Ven`` | BRB food | ||
| masak | but there are two memory allocations | ||
| because two `foo` calls | |||
| if you disagree with the usage of the word "refresh", then I'll grant you that | 12:00 | ||
| they are completely distinct things; they only share the same underlying function code | |||
| but this is exactly where I'm not 100% clear with the Q::Expr::BlockAdapter for the macro argument; because it presumably *does* stick around and needs to be refreshed | 12:01 | ||
| ...I'm not sure how it will work, exactly | 12:02 | ||
| it feels wrong to modify anything inside a Q node at runtime | |||
| though my desperation meter is set at "pretty desperate" at this point, and I'd like to merge `macro infix:<ff>` even if it means taking on some technical debt to sort out later | 12:16 | ||
|
12:31
Ven`` joined
|
|||
| Ven`` | masak: where does the Q::Expr::BlockAdapter come in? | 12:32 | |
| in the argument? | |||
| at this point it's pretty clear I don't understand what "refresh" is supposed to mean in this context | 12:35 | ||
| masak | I wrote ā¦z⦠in the gist becuase `z` comes from the mainline, and the ā¦...ā§ already switched us into the injectile's scope | 12:40 | |
| both of those types of scope switching are done with Q::Expr::BlockAdapter | |||
| (modulo the fact that I haven't implemented it for the macro args yet, not even in the infix:<ff> branch) | 12:41 | ||
| Q::Expr::BlockAdapter contains a Q::Block, which has a $.frame | 12:42 | ||
| the macro expansion leaves the $.frame of ā¦z⦠as the mainline's static frame -- that's both a best effort kind of thing and really the only option | 12:43 | ||
| but at runtime, it needs to be the mainline's runtime frame | |||
| hence "refresh" | |||
| notice that if the macro argument that was inserted was ā¦do BEGIN { z }⦠(*handwave*), then it's actually correct that the OUTER is the mainline's static frame | 12:45 | ||
| Ven`` | well | 13:46 | |
| macro moo(y){var x = 2; quasi { print(x + {{{y}}}); } }; var z = 3; moo(z); | 13:54 | ||
| desugars, to, basically, var SCOPEOUTER::z; var SCOPEMACRO::x; z = 3; BEGIN SCOPEMACRO::x = 2; print(SCOPEMACRO::x + SCOPEOUTER::z); | 13:55 | ||
| that's the very basic premise | 13:57 | ||
| now the point is ā here, the frame doesn't appear on the *frame*, it appears on *variables* | |||
| masak | because... when the macro expands, `z` has been replaced by `SCOPEOUTER::z`, some kind of variable-in-a-package? | 14:14 | |
| trying to understand here | |||
| Ven`` | yes. that was also what I was trying to explain when linking to some racket stuff | 14:25 | |
| the variable isn't just a identifier, it's also a "where from". | |||
| masak | 007 had that model for a long time. we're now sort of leaving it behind again. | 14:28 | |
| it's not completely too late to halt that process, but I've documented fairly well why we're doing so | |||
| Ven`` | I need to go (re)read that then. Because it seems like it | 14:37 | |
| 's what schemes do. | |||
| github.com/masak/007/issues/212 | 15:10 | ||
| is that the issue I need to re-read, masak ? | |||
| > The pathology can be summarized as "attach all identifiers in the quasi (regardless of depth) to the scope outside the quasi (typically the macro's scope)". This is wildly, hilariously wrong. | 15:12 | ||
| I think I can sum up the issue with this, here. | |||
| I think this is perfectly correct. | 15:13 | ||
| ...to one extent. | |||
| when you see macro moo(y){var x;}, *both* should be variables with moo's lexical scope as their scope | |||
| y's *value*, however, is an identifier, with a different scope. Namely the outer scope. | 15:14 | ||
| this is *partly* why we need {{{ }}}, anyway. | |||
| to sum up the first (reduced) case: | 15:17 | ||
| macro moo(a) { return quasi { my x = {{{a}}} } }; moo(7) | |||
| here, in moo, a is an identifier with scope=the macro's. then we have the quasi, which creates a new scope inheriting the macro's. it declares x with this scope as a parent, and it "melts" a. a is NOT looked up in this scope, but in the macro's | 15:19 | ||
| this is what I meant by "the lisp way". | 15:20 | ||
| (I didn't mean without hygiene) | |||
| ah, that one example was fixed anyway | |||
| OK, only the unreduced OP code is still broken | 15:21 | ||
| gist.github.com/vendethiel/9e20afc...b5604a158f | 15:24 | ||
| basically, this | |||
|
18:17
Ven`` joined
|
|||
| masak | I am pleased to announce I agree with all of the above | 19:32 | |
| also, I believe you've found the issue in question | |||
| but let me find/quote another bit from it | |||
| (from a 2015 commit) "Wrapping everything in carefully crafted blocks doesn't seem to be enough." (so giving identifiers a frame instead) | 19:34 | ||
| (from the Aug 2017 comment in that issue) "Seems we've been walking in a circle for the past two years... but that's fine too as long as we come back to the original point having learned something." | |||
|
19:56
Ven`` joined
19:57
Ven`` joined
22:29
Ven`` joined
22:38
Ven`` joined
|
|||