🦋 Welcome to the IRC channel of the core developers of the Raku Programming Language (raku.org #rakulang). This channel is logged for the purpose of history keeping about its development | evalbot usage: 'm: say 3;' or /msg camelia m: ... | Logs available at irclogs.raku.org/raku-dev/live.html | For MoarVM see #moarvm Set by lizmat on 8 June 2022. |
|||
07:12
MasterDuke left
08:14
sena_kun joined
|
|||
Geth | ¦ problem-solving: lizmat unassigned from samcv Issue Add `nomark` for striping accents, `samemark` is counterintuitive and slow for that purpose. github.com/Raku/problem-solving/issues/427 | 08:43 | |
nine | Timing remains the hardest thing in RakuAST. E.g. signatures on methods create the implicit parameter for the invocant. To do this at the time the signature decides whether to do this it must already know wheter it is on a method. That generated parameter will look for its "owner", i.e. the block it's attached to. | 09:43 | |
Begin time is loosely defined as running when we are done parsing an element, e.g. that method. Now if at this begin time we trigger BEGIN for this implicitly created parameter, the resolver will be just outside that method, so the parameter will find the wrong owner. | 09:44 | ||
I got around this by violating that BEGIN definition and re-entering the method's scope before triggering BEGIN. Of course if it's good for methods it should be good for other routines as well, right? But doing the same on other routines causes us to look for protos in the wrong scope. Because, you know, BEGIN is supposed to happen just after we parsed the element so the current scope should be the | 09:46 | ||
routine's surroundings, i.e. a good place to look for a proto. | |||
You might think that maybe BEGIN is just too late for creating that implicit invocant parameter? After all, isn't the point of rakuast-phase-cleanup to introduce a separate PARSE phase? But PARSE for a method is defined as the time when we're entering it. It's far too early to process a signature as we haven't even parsed it yet. | 09:51 | ||
And even if I move routine's PARSE to after parsing the signature (after all, rakuast-phase-cleanup gives us that kind of control), it's still too early. Because we have placeholder parameters, i.e. the full signature is really only known after we're done parsing the full routine body. | 09:52 | ||
09:58
finanalyst joined
|
|||
ab5tract | Ahh.. that is mega complex | 10:21 | |
I don’t suppose the answer could bee a new phase? | 10:24 | ||
Probably not, if the goal is to enter only once.. | |||
nine | A reasonable question would be: how does this work on current main then? The answer is that there the Parameter's (and other's) attach method gets called multiple times. It just so happens that later invocations usually get the right environment. This reliance on luck is a thing that the branch tries to fix. | 10:30 | |
How can later invocation get the right environment when we have long left that scope? While IMPL-CHECK traverses the tree and call's IMPL-CHECK on children it also pushes lexical scopes onto the resolver's stack. I.e. we enter and exit scopes as we traverse. | 10:33 | ||
In that sense my workaround may not be all that wrong. It's the method's PERFORM-BEGIN that calls the signature's IMPL-ENSURE-IMPLICITS. I.e. this happens outside the normal tree traversal that would keep track of lexical scopes. | 10:36 | ||
So adding this enter-scope to the Actions would restore the original system. But still it feels fragile and makes me wonder if there's a more regular way to get this. | 10:37 | ||
Actually there is :) I realized that I had a .to-begin-time($resolver, $context) right where I created that implicit parameter. Usually that's the right thing to do for such artificial nodes as that's the equivalent timee to having just parsed them. But in this case we are just not in the right state of the resolver. Later on we will be. | 10:44 | ||
11:01
finanalyst left
|
|||
ab5tract | \m/ | 11:19 | |
11:35
finanalyst joined
|
|||
Geth | rakudo/lizmat-nomark: 04547b813f | (Elizabeth Mattijsen)++ | src/core.e/Fixups.rakumod Add Cool.nomark in 6.e As suggested in github.com/Raku/problem-solving/issues/427 Notes on implementation: - Cool.nomark converts to string and delegates to Str.nomark - in Str.nomark: check if empty string, return invocant if so ... (8 more lines) |
11:47 | |
rakudo: lizmat++ created pull request #5562: Add Cool.nomark in 6.e |
|||
12:33
finanalyst left
|
|||
[Coke] | lizmat: should it be #!jvm or #moar ? Are we ignoring JS these days (which makes sense given it has no maintainers) | 14:21 | |
14:28
sjn left
|
|||
nine | Of course when you change anything about timing, the whole whatever currying house of card immediately falls down :/ | 15:12 | |
The current implementation relies on IMPL-BEGIN-BEFORE-CHILDREN running after the whole expression has been parsed but on the way down the tree. | 15:13 | ||
ab5tract: I seem to remember that thing working bottom up at some point? I.e. we'd curry the inner most expression first and when processing its parent, uncurry that inner expression and instead curry the parent. | 15:15 | ||
ab5tract | I couldn’t expand it to work on all the cases it wasn’t working for :( | 15:22 | |
I tried to design something sturdier than a house of cards, but perhaps I failed | |||
nine | AFAICT what you did is actually eschew the standard tree traversal entirely and instead traverse it yourself at the earliest opportunity after its fully assembled | 15:27 | |
The standard traversals we have all really happen bottom up. But then we at least now got two of those, so I wonder if we can make use of this. So my first attempt was also bottom up, but really in a single phase, i.e. do all the work for a node and then undo that work at a higher node. Maybe we can split the work: first collect information bottom up and then use this information to decide where to apply | 15:30 | ||
the transformation on the second bottom up run. | |||
ab5tract | ISTR it being mostly impossible to align the argument positions going bottom up | 15:35 | |
nine | It wouldn't at all be that much different from what we have now. I'd still have the outer most parent do the actual currying. All we need is to be able to tell the child "don't bother, I'll take care of the curry". | 15:40 | |
This communication happens implicitly on main by virtue of the parent replacing the child's Whatever argument with a WhateverCode::Argument | 15:41 | ||
We have one mechanism that allows for a node to get information about its parent, that's $resolver.find-attach-target. I think we could use this also for the child to determine whether it needs to curry or not. | 15:43 | ||
Alas attach target currently is very much tied to scopes. I.e. we only even ask whether to push an attach target when entering a scoep | 15:46 | ||
ab5tract | I can’t recall why I stayed away from the find attach target method, but I do remember trying to figure out how introspect the parent node | ||
Do all nodes actually attach? | 15:55 | ||
nine | ? | 15:57 | |
ab5tract | Not at all computer at the moment so I can’t check easily | 16:00 | |
nine | I somehow doubt that I'd be able to add some enter-expr/leave-expr like think into the expression parsing code, so that kinda kills the attach-target idea. | ||
That brings us back to bottom up which we know can't work. Or can it? All the current code needs to succeed is for the children to be returned to their original state once we determined that the parent should do all the currying. | 16:01 | ||
That's basically just un-thunking (which we already can do) and replacing those WhateverCode::Arguments back with Whatevers | 16:02 | ||
Then the current code is good to go again. | |||
ab5tract | Hmm, yeah that should work | 16:07 | |
nine | Actually there are still quite a few IMPL-UNCURRY calls left even now | 16:08 | |
ab5tract | Only piece I’m missing conceptually is doing the check on the parent node. If it’s always only one level up, I suppose it should be manageable but the “should we” logic can be a bit complex | 16:10 | |
One thing that’s good here is that deeply nested whatevercodes are possible, but also uncommon | 16:11 | ||
So some back and forth on the thunking shouldn’t be too bad performance wise | 16:12 | ||
nine | I'm no longer proposing having the child check the parent as we simply don't have a good way of doing that. | ||
I'd just let IMPL-CURRY-ACROSS-ALL-CHILDREN to the cleanup in its initial fact finding run | 16:13 | ||
Though to be honest I still wonder what the exact trouble with the bottom up approach was? Adjusting argument numbers is certainly tedious, but couldn't we just have the parent re-assign them? I.e. have the parent do a DFS traversal on its children and assign new numbers as it finds WhateverCode::Arguments? | 16:21 | ||
lizmat | [Coke]: I just followed the same conditional that samemark has | 16:55 | |
[Coke] | lizmat: so, nothing new - perfecto. | 17:20 | |
Thanks for letting me know | |||
lizmat | yw :-) | ||
17:34
finanalyst joined
|
|||
ab5tract | nine: now that whatevercode argument is a thing, that might work. Before that everything used Var::Lexical, which was unwieldy in a DFS | 17:50 | |
Here’s the final commit before I implemented whatever applicable: github.com/rakudo/rakudo/commit/b4...f634135d03 | |||
nine | Yes, I think your refactors including that role make things a lot easier to grok | 17:57 | |
18:26
finanalyst left
19:22
finanalyst joined
21:20
finanalyst left
23:26
sena_kun left
|