🦋 Welcome to the MAIN() IRC channel of the Raku Programming Language (raku.org). Log available at irclogs.raku.org/raku/live.html . If you're a beginner, you can also check out the #raku-beginner channel!
Set by lizmat on 6 September 2022.
guifa_ Anton: ty btw, for some reason my current setup is hitting all sorts of edge cases and I'm fixing quite a few little bugs 00:30
Homer_Simpson nm fixed, comma wants you to manually give it the file extention 00:48
coleman Who owns raku.org? 01:58
guifa_ I believe the TPRF 02:03
coleman That stands for The Perl and Raku Foundation?
guifa_ Is there a way to obtain the original method of a wrapped method when doing, e.g. $foo.^find_method('bar') ? .is-wrapped returns True, but wanting to see if there's a way that I can check to see if a method may have been accidentally double wrapped
Yeah. Don't quote me, but I believe they have it. codesections probably knows a bit more on that end 02:04
Anton: stuff should be updated now enough that you can use Intl::Format::DateTime 02:22
Voldenet m: sub bar { }; &bar.wrap({callsame}); my $foo = &bar; my $foo = &bar.clone; &bar.restore; say &bar.is-wrapped 02:58
camelia Potential difficulties:
Redeclaration of symbol '$foo'.
at <tmp>:1
------> rap({callsame}); my $foo = &bar; my $foo⏏ = &bar.clone; &bar.restore; say &bar.is
No such method 'restore' for invocant of type 'Sub+{Routine::Wrap…
Voldenet m: sub bar { }; &bar.wrap({callsame}); my $foo = &bar.clone; &bar.restore; say &bar.is-wrapped
camelia No such method 'restore' for invocant of type 'Sub+{Routine::Wrapped}'
in block <unit> at <tmp> line 1
guifa_ hmm that's an idea 03:07
Voldenet unfortunately, no go 03:10
m: sub foo {42}; my $x = &foo.wrap(->{24}); my &bar = &foo.clone; say foo; &bar.unwrap($x); say foo;
camelia 24
42
Voldenet yeah, doesn't work
guifa_ I guess I could make a dummy sub that returns 1 if it's the final candidate, and otherwise returns 1+ that 03:19
but that feels like overkill for a test
Voldenet It could be structurally tested by touching attributes, but moar impl is different than others… 03:20
it'd be easier if there was `unwrap` that returned unwrapped routine instead of replacing it 03:21
Voldenet m: sub foo {42}; my $spooky = &foo; my $x = &foo.wrap(->{24}); $spooky.is-wrapped.say 03:25
camelia True
Voldenet m: sub foo {42}; my $spooky = &foo.clone; my $x = &foo.wrap(->{24}); $spooky.is-wrapped.say 03:28
camelia False
Voldenet wrapped method keeps being WrapHandle though 03:29
s/WrapHandle/Sub+{Wrapped}/ 03:30
jaguart wrap/unwrap has scope for handle hiccups 03:44
m: sub foo(){'f'};sub bar(){'b'};my $f=&foo.wrap(->{'F'});my $b=&bar.wrap(->{'B'}); &foo.unwrap($b); say foo; say bar;
camelia F
b
jaguart seems the handle is more important than the sub 03:46
m: sub foo(){'f'};sub bar(){'b'};my $f=&foo.wrap(->{'F'});my $b=&bar.wrap(->{'B'}); $b.restore; say foo; say bar;
camelia F
b
guifa_ I didn't even realize restore was a method. 04:01
it's not documented
jaguart yeah - and you can't introspect Routine::WrapHandle 04:34
Voldenet it is documented, but docs.raku.org/type/Routine::WrapHandle 04:55
the class it's on is somewhat odd
jaguart hmmm - actually you can - gist.github.com/jaguart/35ab71ade4...3f3a3a5554 04:57
guifa_ I feel like I'm about to do th hackiest code ever 05:04
jaguart I think I have something for you to try...
guifa_ oh wait
jaguart .WRAPPERS METHOD 05:05
guifa_ I won't have access to the wrap handler
oh i just scrolled down ha 05:06
jaguart m: sub foo(){'f'};my $f=&foo.wrap(->{'bar'});say &foo.WRAPPERS; $f.restore; say &foo.WRAPPERS; 05:07
camelia (-> { #`(Block|3569926561016) ... }, sub foo { #`(Sub|3569926161664) ... }).IterationBuffer
(sub foo { #`(Sub|3569926161664) ... },).IterationBuffer
jaguart m: sub foo(){'f'};my $f=&foo.wrap(->{'bar'});say &foo.WRAPPERS; say $f.restore; say &foo.WRAPPERS;
camelia (-> { #`(Block|3594085752056) ... }, sub foo { #`(Sub|3594085352704) ... }).IterationBuffer
True
(sub foo { #`(Sub|3594085352704) ... },).IterationBuffer
jaguart So you can count .WRAPPERS to see if you are still wrapped? 05:08
guifa_ yeah that's perfect
nice find
jaguart It's weird how that method doesn't show in the Class but does on a wrapped instance 05:10
guifa_ I'll take it for now ha 05:11
basically I do a bunch of wrapping on DateTime methods so I can upgrade old core ones to newer fancy ones 05:12
but if multiple files or scopes `use` my module, the methods could get wrapped several times
I've got them wrapped in once blocks, but this will give me extra confidence 05:13
jaguart: there we go github.com/alabamenhu/DateTimeTime...e.rakutest 05:22
Homer_Simpson does raku have structs and enums 05:26
err unions and structs
jaguart guifa++ :) 05:27
guifa_ github.com/alabamenhu/DateTimeTime...e.rakutest
errr sorry didn-t mean to double post that link 05:28
Homer_Simpson it has unions for native call stuff 05:29
I *think* there may be a way to pull more interesting things off with non-native objects via is repr(…), but right now all valid values there seem to be hard coded 05:30
Homer_Simpson what about typedefs 05:33
guifa_ yes 05:43
m: constant DT = DateTime; DT.now.say
camelia 2022-12-27T06:43:51.346203+01:00
jaguart given this: 07:00
m: module b { our $a=1; my $b=2; our sub x { my $i=0; .say for OUTER::.pairs.grep({$_.key ~~ /^^ . <[a..z]>+ /}); }}; b::x()
camelia $b => 2
&x => &x
$a => 1
jaguart How do I enumerate the my-vars from outside the package? 07:01
including lexical subs?
Nemokosch Jaguart: sounds like something to do with stashes 09:19
There is the MY pseudostash, for example 09:21
Our CALLER 09:22
Or
moritz you don't get access to lexicals from the outside though 10:52
Nemokosch How sure are you on a 1 to 10 scale? 😅 Like this seems to be the kind of topic only ~ 3 people are up-to-date with 10:58
moritz I'm, like 99% certain that you don't get language-mandated, reliable access to foreign lexical scopes 11:12
compilers are free to optimize away lexical variables, if they can
if there are ways in current rakudo, I wouldn't rely on them in code that's meant to last a long time 11:13
there's a reason that lexicals are delcared with "my" :-) 11:14
Nemokosch that makes sense 11:18
even if there is a way, it might not be a good idea...
moritz m: sub f { say CALLER::MY::.keys }; { my $x = 42; f() } 11:28
camelia ($_ $x)
moritz rakudo doesn't forbid it, but it might in future 11:29
lizmat a lot of the P5-xxx modules in the ecosystem use this to be able to mimic Perl semantics 13:11
I guess I should mark them explicitely v6.c so that a future language version can get rid of CALLER:: 13:12
as it blocks just about any optimization you can think of
lizmat clickbaits rakudoweekly.blog/2022/12/26/2022-...ntonovmas/
leont I'm very confused about some supply behavior I'm seeing. It seems my «supply { whenever $foo.lines { ... } } gets run for every tap I put on it (including the $supply.Promise). That is … not what I had expected 13:44
grondilu I can't do a cartesian product of a list of pairs for some reason : 13:49
m: my @k = foo => "bar"; for @k X @k 13:50
camelia ===SORRY!=== Error while compiling <tmp>
Missing block
at <tmp>:1
------> my @k = foo => "bar"; for @k X @k⏏<EOL>
expecting any of:
block or pointy block
grondilu ah sorry
m: my @k = foo => "bar"; for @k X @k -> $, $ { }
camelia Too few positionals passed; expected 2 arguments but got 1
in block <unit> at <tmp> line 1
grondilu m: my @k = foo => "bar"; for @k X @k -> ($, $) { }
camelia Too few positionals passed to '<anon>'; expected 2 arguments but got 0 in sub-signature
in block <unit> at <tmp> line 1
grondilu what am I missing?
leont I guess that's intentional given what I read in method share, but adding share to it doesn't seem to solve anything either 13:52
fg
Nemokosch grondilu: if I were to guess, it's passed as named argument... 13:55
if that's really true, I still wouldn't be sure if it's a feature
let's make it worse: 13:57
Nemokosch m: for ((foo => 'bar', foo => 'baz'),) -> (*%_) { dd %_ } 13:58
camelia {:foo("baz")}
Nemokosch the second pair overwrote the first one
leont: I think atm only Jonathan or Stefan would know enough about this topic... 14:00
leont Possibly I should ask in #cro, not because it's a cro question but because that's where all the experts on this area seem to hang out 14:05
lizmat except maybe this time of year
leont lizmat: How dare people have a life and priorities and such! /s 14:06
lizmat leont: isn't it because the "supply" "keyword" creates a non-live supply ?
leont Yeah, I had come to a similar conclusion, but wasn't sure how to fix it, other than not tap on the supply more than once 14:07
What I thing I need is .share(:preserving), but somehow that isn't an option 14:09
Nemokosch by the way: do y'all happen to know how to pass a pair (or multiple pairs) to a for loop when named argument semantics isn't sufficient? 14:11
Nemokosch m: my @k = foo => "bar"; for @k X @k -> @sad { dd @sad[0], @sad[1]; } 14:22
camelia Pair @k = :foo("bar")
Pair @k = :foo("bar")
Nemokosch not much but it's honest work...
leont I've been using supplies since 2014, and apparently I still don't fully understand them. The documentation is less-than-helpful much of the time. 14:28
grondilu unrelated: 14:30
m: say (pi but role { multi method AT-POS { 3, 1, 4, 2 } })[]
camelia 3.141592653589793
grondilu m: say class { method AT-POS { rand xx * } }.new[] 14:31
camelia <anon|1>.new
grondilu m: say class { method AT-POS($n) { rand } }.new[0]
camelia 0.8613574568742635
grondilu m: say class { method list { rand xx * } }.new[]
camelia <anon|1>.new
leont On the bright side, next version of TAP should be faster because it's no longer double parsing the input 14:32
grondilu how do I override &postcircumfix:[] without arguments? 14:34
Nemokosch why do you want to, if I may? 14:36
iirc there are multi candidates that force it to act like bare decontainerisation 14:38
grondilu I have a class where it would make sense to do so 14:39
Nemokosch how would it be called? why [] in particular? 14:42
github.com/rakudo/rakudo/blob/704a...e.pm6#L281 this is the candidate to beat, for that matter 14:46
pippo Hello Raku people. Is there a peek-one method on Iterable to take a sneak on the neext value witout pulling it out? 16:37
pippo p6: say "Hello"; 16:39
camelia Hello
pippo p6: my $iter = [1,2,3,4].iterator; $iter.pull-one() 16:42
camelia ( no output )
pippo p6: my $iter = [1,2,3,4].iterator; say $iter.pull-one() 16:43
camelia 1
pippo p6: my $iter = [1,2,3,4].iterator; say $iter.peek-one()
camelia No such method 'peek-one' for invocant of type
'Rakudo::Iterator::ReifiedArrayIterator'
in block <unit> at <tmp> line 1
pippo p6: my $iter = [1,2,3,4].iterator; say $iter.peek(1)
camelia No such method 'peek' for invocant of type
'Rakudo::Iterator::ReifiedArrayIterator'
in block <unit> at <tmp> line 1
Nemokosch maybe in module space? I don't know, iterators are fairly low-level. I wouldn't know by heart but I have the impression that in languages like C++, Java, Python, Javascript, that also wasn't a thing 16:49
pippo It would be useful if raku architects could decide to implement that. 16:54
Nemokosch Bluntly put, one could create a top 20 list if things that "would be useful (...)" any day, and I'm not sure how many times this apparently unorthodox iterator feature would appear. 16:57
Having said that, I'm curious what you have in mind. Why would it be useful for iterators to do that? 16:58
pippo Abhoerschutz _________ on a case statement (or any other test). Depending on the value of peek-one perform the correct action;case $iter.peek-one() { 1 {sub1($iter.pull-one)}; 2 {sub2($iter.pull-one()}} 17:02
on a case statement (or any other test). Depending on the value of peek-one perform the correct action;case $iter.peek-one() { 1 {sub1($iter.pull-one)}; 2 {sub2($iter.pull-one()}}
Abhoerschutz ^^ Sorry for that. Unintended mess-up! 17:03
Nemokosch but you can just pull the value, store it in a variable (bind it) and then decide, no? 17:04
Abhoerschutz pippo: No problem.
Nemokosch it might even work with given-when directly (`given` binds to the topic variable iirc) 17:05
Xliff \o 17:06
tonyo m: role A does Iterator { method pull-one { }; method peek-one { } }; my $iter = [1,2,3,4] does A; $iter.peek-one.say # pippo 17:07
camelia Nil
Xliff My complements to Anton Antonov for his work on Javascript::D3. I am trying to get the Mandala test notebook to run, however it is not generating the Mandalas.
Can someone tell me what I am likely missing? 17:08
I think I have all of the modules installed, but would appreciate it if someone else has run into... and solved... this issue.
Nemokosch ~~let me guess: another Mac user~~ 17:09
pippo <Nemokosch> Yes. But it does not work if I want to pass the $iterable to a function depending on its nex value. case $iter.peek-one() { 1 {sub1($iter)}; 2 {sub2($iter}}
tonyo in your example there is no implementation of peek-one 17:10
Nemokosch Javascript::D3 worked for me offhand, Ubuntu 20.04, iirc tried inside WSL 17:11
tonyo that is how you'd implement it
pippo p6: role A does Iterator { method pull-one { }; method peek-one { } }; my $iter = [1,2,3,4] does A; say $iter.peek-one(); say $iter.pull-one(); 17:12
camelia Nil
Nil
Nemokosch and it would always just return Nil? 😄 17:13
pippo p6: role A does Iterator { method peek-one { } }; my $iter = [1,2,3,4] does A; say $iter.peek-one(); say $iter.pull-one(); 17:14
camelia Method 'pull-one' must be implemented by Array+{A} because it is required by roles: A.
in block <unit> at <tmp> line 1
tonyo m: role A does Iterator { method pull-one { self.shift; }; method peek-one { self[0]; } }; my $iter = [1,2,3,4] does A; $iter.peek-one.say; dd $iter; $iter.pull-one.say; dd $iter # pippo
camelia 1
Array+{A $iter = $[1, 2, 3, 4]
1
Array+{A $iter = $[2, 3, 4]
Nemokosch pippo: why not? do something like my $following := $iter.pull-one; and then dispatch over it. That should work, no?
pippo That is good idea. But the subs to which I pass $iter are called recursively and doing that will just defeat what I am trying to do: preserve memory. 17:17
tonyo pippo: and then for easier use in funcs you can do something like: 17:19
m: role A does Iterator { method pull-one { self.shift; }; method peek-one { self[0]; }; method COERCE(*@_) { @_ does A; } }; my $iter = [1,2,3,4]; sub WHAT-I-WANT (A() $x) { dd $x.peek-one; }; WHAT-I-WANT($iter)
camelia 1
moritz doesn't List both persist elements *and* keep iterator tails? Sounds like the perfect type for when you want to be able to peek 17:23
pippo tonyo that does seem to work for me. Although not sure to understand completely what you wrote. I need to do some meditations on that :-) 17:24
pippo Thank you tonyo. thank you all. Cheers! 17:32
Nemokosch is it not an overkill way to use a List?
🍻 17:32
moritz using the best tool for the job doesn't sound like overkill to me :-) 17:33
Nemokosch perhaps I didn't phrase it clearly. To build an Iterator on top of a List and then use it like an Iterator... now that seems like an overkill version of a List 17:34
Xliff <Nemokosch> - Were you able to see the mandalas? 17:39
Xliff Where I am supposed to see scribbles and mandalas, I am seeing nothing. 17:40
Javascript error adding output! 17:41
SyntaxError: Unexpected identifier 'routine'
See your browser Javascript console for more details.
Nemokosch where did you see that?
Anton asked me to run this: 17:42
`js-d3-graphics random-mandala 32 --margins=5 -h=300 -w=300 --color='rgb(120,120,120)' --background='white' > ~/out.html`
Xliff I'm seeing this in the Jupyter notebook. 17:43
Nemokosch and the generated html looked like this: media.discordapp.net/attachments/8...height=599 17:44
Xliff Aha! Now that did work.
So it might be something in the Jupyter setup then. Thanks.
Nemokosch 🍬 17:49
Anton Antonov <@742445366489645080> Using "JavaScripdt::D3" with the Jupyter Raku kernel requires a particular JavaScript code to be executed first in a cell marked to use the JavaScript magic (`%%javascript`). 19:34
<@742445366489645080> See the notebook here: nbviewer.org/github/antononcube/Ra...alas.ipynb 19:35
pippo m: sub peek-one(Iterator $it is copy) {return $it.pull-one}; my @a = [1,2,3,4,7]; my $it1 = @a.iterator; pull-one($it1); $it1.pull-one; 21:38
camelia ===SORRY!=== Error while compiling <tmp>
Undeclared routine:
pull-one used at line 1. Did you mean 'peek-one'?
pippo m: sub peek-one(Iterator $it is copy) {return $it.pull-one}; my @a = [1,2,3,4,7]; my $it1 = @a.iterator; peek-one($it1); $it1.pull-one; 21:39
camelia ( no output )
pippo m: sub peek-one(Iterator $it is copy) {return $it.pull-one}; my @a = [1,2,3,4,7]; my $it1 = @a.iterator; say peek-one($it1); say $it1.pull-one;
camelia 1
2
pippo ^^ apparently is copy does not work for iterators?
vrurg_ pippo: copy only means that you get a copy of the container. Not what it contains. In other words, if you want a duplicate which you can replace without affecting the original. 21:41
pippo That is what I looking for. I was expecting $it1.pull-one to give 1 but gave 2 instead. 21:42
vrurg_ pippo: once again, wrong. Gimme a second. 21:43
m: sub nc($v) { say $v.VAR.WHICH; }; sub c($v is copy) { say $v.VAR.WHICH }; my $foo = 1; say $foo.VAR.WHICH; nc($foo); c($foo)' 21:44
camelia ===SORRY!=== Error while compiling <tmp>
Two terms in a row
at <tmp>:1
------> 31; say $foo.VAR.WHICH; nc($foo); c($foo)⏏'
expecting any of:
infix
infix stopper
statement end
statement…
vrurg_ m: sub nc($v) { say $v.VAR.WHICH; }; sub c($v is copy) { say $v.VAR.WHICH; }; my $foo = 1; say $foo.VAR.WHICH; nc($foo); c($foo)' 21:45
camelia ===SORRY!=== Error while compiling <tmp>
Two terms in a row
at <tmp>:1
------> 31; say $foo.VAR.WHICH; nc($foo); c($foo)⏏'
expecting any of:
infix
infix stopper
statement end
statement…
vrurg_ m: sub nc($v) { say $v.VAR.WHICH; }; sub c($v is copy) { say $v.VAR.WHICH; }; my $foo = 1; say $foo.VAR.WHICH; nc($foo); c($foo);
camelia Scalar|3875479669520
Scalar|3875479671104
Scalar|3875479671200
vrurg_ Ah, no, bad example. Ok, anyway, `is copy` gives you a writable variable made off a parameter. It differs from `is rw` in a way that `is rw` binds the parameter to the original variable, `is copy` gives you a new one. 21:47
m: sub nc($v is rw) { say $v.VAR.WHICH; }; sub c($v is copy) { say $v.VAR.WHICH; }; my $foo = 1; say $foo.VAR.WHICH; nc($foo); c($foo);
camelia Scalar|3090965449632
Scalar|3090965449632
Scalar|3090965451264
vrurg_ pippo: like this. But each Scalar contains the same iterator in your case – the same object, in general case. 21:48
vrurg m: sub nc($v is rw) { $v = 13; say "nc:$v" }; sub c($v is copy) { $v = 12; say "c:$v"; }; my $foo = 1; say $foo.VAR.WHICH; nc($foo); c($foo); 21:49
camelia Scalar|3693077322448
nc:13
c:12
vrurg m: sub nc($v is rw) { $v = 13; say "nc:$v"; }; sub c($v is copy) { $v = 12; say "c:$v"; }; my $foo = 1; say $foo; c($foo); say "after c: $foo"; nc($foo); say "after nc: $foo"; 21:50
camelia 1
c:12
after c: 1
nc:13
after nc: 13
vrurg pippo: does it make the case clearer?
pippo m: sub peek-one(Iterator $it is copy) {return $it.VAR.WHICH}; my @a = [1,2,3,4,7]; my $it1 = @a.iterator; say peek-one($it1); say $it1.VAR.WHICH; 21:51
camelia Scalar|5609505824496
Scalar|5609505825984
Nemokosch could one say that Iterable doesn't have value semantics? 21:52
vrurg pippo: I think you need to read through this section of the docs: docs.raku.org/language/containers 21:53
pippo reading...
vrurg Nemokosch: how could it? Iterables are mutable by definition. 21:54
tellable6 vrurg, I'll pass your message to Nemokosch
Nemokosch I mean, it's pretty simple then, no? Something that doesn't act like a value, cannot be copied by value. 21:57
Regarding an Iterator in particular: pippo think about it what it would mean for an Iterator to be copied 21:59
if you consider two copies two completely isolated Iterators that produce the same values respectively - how could that work? Firstly, many Iterators are lazy so the semantics wouldn't even be easy to define 22:01
Moreover, how do you achieve that *without* pulling all the values from the original iterator? 22:02
pippo m: my @a = [1,2,3,7]; my $itr1 = @a.iterator; my $itr2 = @a.iterator; say $itr1.pull-one; say $itr2.pull-one; 22:03
camelia 1
1
Nemokosch Don't forget that an Iterator is a very simple interface with no particular data structure backing it up.
basically it only promises that you can get a subsequent value - or you will know when you can't get more values 22:04
pippo OK. thank you Nemokosch.  I think i'll drop iterators and try to work my way with something else. Cheers. 22:06
Nemokosch the two biggest takeaways imo are: 1. `is copy` is not super useful for something that isn't used as a value (i.e deeply immutable and hence re-assignment is all the mutation you need to calculate with) 2. Iterators are like, "hollow" or something. Black boxes that can give you a value some magical way. There is not a lot you can do with something like that, and this isn't Raku specific from all I know. 22:09
moritz fun fact, recently had a bug in a Python application; root cause was that some boolean test used "value in iterator" (inside a loop), and in python, the "in" operator exhausts the iterator until it finds a value, or the end 22:22
so if the iterator had the values (1, 2, 3, 4), and the first test was "3 in iterator", then later tests for "2 in iterator" failed 22:23
the fix was to construct a set from the iterator
Nemokosch and this makes quite a lot of sense if you think about it 22:33
how else could an iterator know if 3 is present? and iterators generally don't have any structure that could allow putting values back, let alone in front 22:34
github.com/2colours/Raku-ideas/blo...0reborn.md for what it's worth, I wrote a little vision of new squashathons. Feedback is appreciated ^^ 23:03