🦋 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. |
|||
lizmat | funny thing is that I don't see a lexical by the name True in the QAST ? | 00:26 | |
so I wonder how that works at all ? | 00:27 | ||
00:29
sena_kun left
|
|||
timo | the core setting is outside of the block that is generated from the QAST, so it should just find stuff in the setting if there's no matching QAST::Var with :decl | 00:43 | |
lizmat | so that would be more work than having a WVal, is what you're saying, and thus a missed optimization opportunity | 00:50 | |
anyways, sleep& :-) | 00:53 | ||
01:11
rakkable left
|
|||
timo | well, for correctness it has to look for cases where it's been overridden in a lexical scope | 01:16 | |
does the WVal come directly from the parse stage or is it put in by the optimizer? | |||
01:29
rakkable joined
07:59
finanalyst joined
09:36
sena_kun joined
10:44
finanalyst left
|
|||
nine | It's looking up that constant in lexical scope and putting it into the WVal | 10:55 | |
11:49
rakkable left,
rakkable joined
|
|||
Geth | rakudo/main: 4 commits pushed by (Stefan Seifert)++ | 12:25 | |
nine | 1234 | ||
Geth | rakudo/main: 0f008a440d | (Elizabeth Mattijsen)++ | src/Raku/ast/literals.rakumod RakuAST: fix ::Literal.from-value for general values Before, if the WHAT of the value did not point to a known class (such as a Bool) then it would instantuate a Mu object and try to set the attributes in that. Now check for the existence of the class first, and if it doesn't exist (and so doesn't have any special handling) make a generic RakuAST::Literal object (which QASTs to a WVal). Found while working on #2599, making .assuming work using RakuAST |
12:29 | |
rakudo/main: 83cac0599a | (Stefan Seifert)++ | src/Raku/ast/variable-declaration.rakumod RakuAST: support late bound array shapes Fixes: my $dims = 4; my @a[$dims]; |
12:50 | ||
nine | 1235 | ||
lizmat | nine: fwiw, in my environment, it's lagging by 2 now | ||
nine | The more tests pass the easer it's gonna be to find that difference ;) | 12:51 | |
lizmat | true | ||
nine | The list of failing spec test file looks a lot more manageable now. Has less of an endless feel to it | 12:52 | |
m: my $a; say $a.VAR.of.^name | 13:06 | ||
camelia | Mu | ||
nine | m: my %h; say %h.of.^name | 13:07 | |
camelia | Mu | ||
lizmat | also, thanks to RakuAST being this mature, looks like .assuming can be made 10x to 50x faster | ||
nine | m: my %h{Int}; say %h.of.^name; | ||
camelia | Any | ||
nine | Why is it Any here but Mu everywhere else? | ||
lizmat | probably an oversight? | 13:08 | |
in the parameterization ? | 13:09 | ||
and/or there are spectests depending on it ? | |||
nine | lizmat: you wrote that spectest in S09-typed-arrays/hashes.t commit 7b7bab4a6c31ebe1b84c623b5d9bc0f48dd1151c | 13:12 | |
linkable6 | (2013-07-05) github.com/Raku/roast/commit/7b7bab4a6c Add tests for typed hashes with key constraints | ||
nine | lizmat: you also changed that default from Mu to Any in rakudo commit 93e96b44e1b9d97efb388d376ad4d3bceb4176c6 | 13:13 | |
lizmat | wow :-) that must have been one of the first things I did | ||
pretty sure I didn't know about the subtleties between Mu and Any at that time | 13:14 | ||
nine | Sadly you also didn't document the reason | 13:16 | |
lizmat | so please go ahead and correct my younger self | ||
yeah :-( perhaps the IRC logs of that day could shine a light | |||
irclogs.raku.org/perl6/2013-05-17.html#07:54 | 13:18 | ||
heh, I didn't even have a commit bit then :-) | 13:19 | ||
Geth | rakudo/main: 24bde349be | (Stefan Seifert)++ | src/Raku/ast/variable-declaration.rakumod RakuAST: make default value type of shaped hashes Any instead of Mu Unfortunately we don't know the actual reason why this is required. There exists a spec tests and a commit in rakudo that changed this default from Mu to Any in this specific case, but neither commit messages explained why. |
13:40 | |
nine | Huh....who'd have thought that a change for a default in a very specific case of a little used feature fixes 3 spec test files? | ||
1238 | |||
Reinforces that even after fixing several hundred spec test files, I have no intuition at all about whether a fix will help with just that one file or fix 10 | 13:41 | ||
Geth | rakudo/main: b5a684d709 | (Stefan Seifert)++ | src/Raku/ast/expressions.rakumod RakuAST: have MetaInfix::Assign curry its arguments Was probably just too conservative when writing the original code. Fixes: * *= 2 |
14:02 | |
nine | Removed code is debugged code! This gets us to 1241! | ||
lizmat | m: sub a() is raw { }; dd &a | 14:40 | |
camelia | sub a { #`(Sub|3557179281496) ... } | ||
lizmat | how can I find out if a Sub has "is raw" specified? | 14:41 | |
ah, it's .rw for now | |||
ok, so I mentioned this before: sub a(:$a) { }, and then my &b = &a.assuming(:a) | 15:25 | ||
now, currently the signature of &b is (:$a) | 15:26 | ||
but I feel that because of the .assuming(:a), the signature of &b should be :(:$a = True) | |||
because if you do not specify a named argument "a" with a call to &b, it will default to True because of the currying | 15:27 | ||
however, t/spec/S06-currying/named.t appears to disagree with this view | |||
nine | Obvious question then is: why does it think otherwise? | 15:29 | |
lizmat | well, I'm not sure: the code that the old .assuming is generating, is rather, convoluted, I'd say :-( | 15:30 | |
(there's a reason the new version is 10x to 50x faster :-) | |||
I assume it's not a default value set on the container | 15:31 | ||
so it probably generates code to assign the default value | |||
my approach is to just use the "default value" approach on the parameter | 15:49 | ||
Geth | rakudo/main: 07514a57b1 | (Stefan Seifert)++ | src/Raku/ast/code.rakumod RakuAST: fix merging of imported proto subs |
15:58 | |
nine | 1242 | ||
lizmat | ok, this definitely feels like the speed of fixiing is increasing | 15:59 | |
[Coke] | what is the target number for number go up there? | 16:21 | |
lizmat | 1355 | ||
nine | For me a normal spectest run reports 1359 files. Of those 10 are for Perl 5 regex support which there seems to be an agreement for dropping, so I won't spend any more time on them. Then there's 4 failing macros tests. Since macros are experimental and the point of RakuAST is to find a better way to support those, I'm inclined to ignore them as well. | 16:27 | |
That brings us to 1345 as the target. | |||
[Coke] | Definitely agree on macros. | 16:28 | |
(and p5regexz0 | |||
... also I need more coffee | 16:29 | ||
m: dd 1242/1355 | |||
camelia | <1242/1355> | ||
[Coke] | m: say 1242/1355 | ||
camelia | 0.916605 | ||
[Coke] | Nice. | ||
nine | More coffee? Oh I could do that! | 16:32 | |
lizmat | meh, it looks like Routines are not aware of their scope | 16:40 | |
m: dd my sub a() { } | |||
camelia | sub a { #`(Sub|5280837439984) ... } | ||
lizmat | m: dd our sub a() { } | ||
camelia | sub a { #`(Sub|3027154178680) ... } | ||
lizmat | in RakuAST they are: | 16:41 | |
m: say Q|our method a() { }|.AST.DEPARSE | |||
camelia | our method a () { } |
||
nine | The AST is aware of the scope, not the meta object | 16:42 | |
lizmat | yet .assuming wants to create the same scope, but I can't find out what the scope is from the Routine object :-( | 16:43 | |
nine | Why? | 16:44 | |
lizmat | heh, good question | ||
when I create a RakuAST::Method object, it defaults to "has" scope | 16:45 | ||
nine | A routine is a routine and what it does is independent of how it is found | ||
lizmat | but then it complains that there is no class scope | ||
I guess I'll just make RakuAST::Method always "my" | |||
even though one of the tests uses "our" | 16:46 | ||
actually, .assuming always creates a Sub, duh :-) | 17:00 | ||
problem solved | |||
timo | it sure would be cool if we could skip parts of optimizing NFAs after adding more stuff to them | 17:53 | |
lizmat | I'm hopeful that any regex in a conditional, consisting of just a string, will be reduced to a nqp::index(...) != -1 | 18:09 | |
we would have all the information for it | |||
timo | not quite what i'm looking at right now, i'm thinking more of the cases where a grammar, especially the raku language grammar, is mixed into | 18:13 | |
we also need a tiny bit more than just nqp::index(...) != -1 since it has to populate $/ with the correct Match object as well | |||
but yeah, should be possible for sure | 18:14 | ||
nine | Hint: any help with getting RakuAST out the door will get us closer to such optimizations | 18:23 | |
Geth | rakudo/main: e84b3efa56 | (Stefan Seifert)++ | src/Raku/Actions.nqp RakuAST: use a SHA instead of full text for comp unit handle |
18:27 | |
rakudo/main: fecb520d20 | (Stefan Seifert)++ | src/Raku/ast/scoping.rakumod RakuAST: fix packages missing from export |
|||
nine | 1244 | ||
lizmat | 101 to go! | 18:47 | |
m: sub a($a, $ where { True }) { $a }; my &b = &a.assuming(42); say b(True) | 19:06 | ||
camelia | 42 | ||
lizmat | so far so good | ||
m: sub a($a, $ where { True }) { $a }; my &b = &a.assuming(42); say b(False) | |||
camelia | 42 | ||
lizmat | that shouldn't dispatch, I'd say | ||
m: sub a($a, $ where { True }) { $a }; my &b = &a.assuming(42); say a(42, False) | |||
camelia | 42 | ||
lizmat | it does ? | ||
timo | i somehow managed to get moar to coredump in a way that makes it eat a whole CPU and stay unkillable the entire time? | 19:15 | |
lizmat | perhaps some kind of IO is involved ? | ||
that's usually the way to get an unkillable process, isn't it ? | |||
timo | yeah, that would put the process in "unkillable wait" or what it's called | 19:18 | |
however, this process is very much not waiting :D | |||
oh it finished | |||
nine | Young people these days.....no patience | 19:20 | |
timo | it has been going for like 20 minutes | 19:21 | |
lizmat | that must be quite a coredump then :-) | 19:22 | |
timo | nope, the process that was supposed to receive the core dump timed out a while ago and got killed itself | ||
grmbl. i can't get !protoregex below the inline size limit | 20:18 | ||
580 bytes, what's the limit? is it much less? | 20:19 | ||
192 apparently >_> | 20:20 | ||
and 384 for raku? | |||
lizmat | yeah, that sounds about right | ||
I wonder if we need a trait to raise the limit for a code object | 20:21 | ||
timo | we could perhaps code-gen the stuff that method !protoregex does into the protoregexes themselves | 20:22 | |
20:26
finanalyst joined
|
|||
Geth | rakudo/main: 6256ce027c | (Stefan Seifert)++ | 2 files RakuAST: support require without module name (i.e. require "file") |
20:49 | |
rakudo/main: 2522225b44 | (Stefan Seifert)++ | 2 files RakuAST: have require return the main package or file name |
|||
rakudo/main: b038ec7af6 | (Stefan Seifert)++ | 3 files RakuAST: fix subs in multi-part required packages not found Fixes: require Foo::Bar; Foo::Bar::baz(1) |
|||
nine | Progress on require implementation, but no new passing files | ||
timo | well, this has been an interesting experiment | 21:48 | |
and it doesn't even seem to cause any spec test failures | 21:58 | ||
mainly i was wondering if it would be possible to have the nfa object that's actually going to be used as a constant for spesh when the nqp::nfarunalt happens. now i do :) | 22:11 | ||
i'm not sure if i could rely on the fates array to also be constant from spesh's view. easy enough with a dispatcher or some other kind of trickery, but would it actually be correct? | 22:12 | ||
nine | Presumably if you used a dispatcher, you'd also add a guard? | 22:23 | |
timo | yes, but guarding on an array being the same object doesn't really prevent someone evil from pushing or popping | ||
nine | Also guard the array's contents? | 22:24 | |
timo | hm, can I? | 22:26 | |
i think i've seen that i could do attribute access on a tracked value | |||
22:27
finanalyst left
|
|||
nine | Well, that'd need a new tracker | 22:29 | |
timo | i moved the code that goes through the fates array and calls the methods into a separate sub so i don't have to turn it into QAST manually, but if I do put it in the QAST bits, it would get a per-proto-token "dispatch cache" kind of thing for the by-name calls | ||
nine | How large can these arrays become? | ||
timo | one entry for every multi token in a proto | 22:30 | |
nine | That doesn't sound like terribly many. So it'd not be absurd to guard each item in that array I guess | 22:32 | |
Depends on how much optimization this would enable | |||
Of course we could also just limit this optimization to reasonable array sizes | 22:35 | ||
timo | maybe it's safe enough to guard on the type of the grammar, since mixing in new methods is how you normally add stuff to a proto token, and that changes the type | 22:36 | |
nine | That sounds quite sensible | 22:37 | |
Is there even another way to add tokens that's not totally abusing your powers to dabble in internals? | 22:38 | ||
timo | i can only think of .^add_method which probably still requires a call to compose and maybe some manual clearing of method caches? | 22:39 | |
a-ha! | 22:42 | ||
moar 2209537 1928618.080570: 158300 cycles:P: | |||
7fbae998f2c1 variable(src/Perl6/Grammar.nqp:1832)+0x32c1 (/tmp/perf-2209537.map) | |||
7fbaec029345 MVM_interp_run+0x14195 (/var/home/timo/raku/prefix/lib/libmoar.so) | |||
i can actually see now that this sample taken inside of nqp_nfa_run in moarvm belongs to the variable proto token | 22:43 | ||
that's from postfix_prefix_meta_operator being inlined into the variable token | 22:45 | ||
postfixish: "Frame size: 14116 bytes (1170 from inlined frames)" | 22:46 | ||
lizmat | ooh... that's an interesting idea! | 23:21 | |
timo | which part exactly? | ||
lizmat | dispatching nfa | 23:22 | |
guarding on the contents of an nfa... and thus make mixing in slangs a lot faster, right ? | 23:24 | ||
timo | no i don't think so | 23:26 | |
a large part of mixing in to the raku grammar is having to build new NFAs and run the optimizer on them i think | |||
lizmat | but wouldn't many be the same ? | 23:28 | |
timo | yes. we don't have any kind of "dirty tracking" or anything at the moment | 23:30 | |
we just clear the entire cache that holds all the NFAs whenever we do a mixin | 23:31 | ||
lizmat | right... and that's *really* slow if you're doing it to the Raku grammar | 23:34 | |
in the order of 300-400 msecs on my M1 | 23:35 | ||
ok, a little less apparently | 23:36 | ||
time raku -e '' # 0.11s | |||
time raku -e 'sub infix:<foo>(|) { dd }' # 0.22s | |||
timo | can you time making a sub foo that's not any grammatical thing? | 23:37 | |
i think we're a little faster to parse compile and run the empty string, so the comparison might not be entirely fair | |||
lizmat | time raku -e 'sub foo(|) { dd }' # .12s | ||
timo | ok, tiny difference :D | 23:38 | |
lizmat | yup | ||
timo | can you try out hyperfine? it will run the program multiple times for you and report std dev and such | 23:39 | |
lizmat | % hyperfine | ||
zsh: command not found: hyperfine | |||
fwiw, off to bed now :-) | |||
timo | gnite! | ||
yeah hyperfine is a third-party utility | |||
github.com/sharkdp/hyperfine | |||
lizmat | % hyperfine "raku -e 'sub infix:<foo>(|) { }'" | 23:45 | |
Benchmark 1: raku -e 'sub infix:<foo>(|) { }' | |||
Time (mean ± σ): 81.6 ms ± 1.0 ms [User: 87.9 ms, System: 9.2 ms] | |||
Range (min … max): 80.7 ms … 85.1 ms 35 runs | |||
% hyperfine "raku -e 'sub foo(|) { }'" | 23:46 | ||
Benchmark 1: raku -e 'sub foo(|) { }' | |||
Time (mean ± σ): 69.9 ms ± 1.1 ms [User: 73.3 ms, System: 8.6 ms] | |||
Range (min … max): 68.8 ms … 74.2 ms 42 runs | |||
and now sleep& :-) | |||
23:50
sena_kun left
|