🦋 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.
El_Che weekly: rakudo-pkg for 2023.04 released. Addition of newly released Fedora 38 and Ubuntu 2023.04 00:38
notable6 El_Che, Noted! (weekly)
Geth docker/2023.04: a25034533b | (Daniel Mita)++ | 5 files
Bump to 2023.04
12:57
docker: m-dango++ created pull request #54:
Bump to 2023.04
12:58
aru_ let's say I'm putting together a module which has a library part and a script that uses said library, library goes under lib/, script goes under bin/, but how do I make the load path to include whatever is in lib in the script? 13:03
lizmat if both are installed, you don't need to worry about it 13:07
if they aren't installed yet, use -I. instead of -Ilib
aru_ thank you 13:13
lizmat for example: if you haven't got zef installed, you'd get the zef repo, go to its directory, then do "raku -I. bin/zef install ." 13:14
note that you'd only need to specify -I. the zef script in bin knows where to find its modules then, and is able to install itself 13:15
afk&
falsifian Hot take: 'foo' ~ Empty should be Empty. Compare: 14:15
m: sub f{$^a eq '.'|'..'??Empty!!"rm $^a"};.say for map &f, <. .. foo.txt bar.jpg>;
camelia rm foo.txt
rm bar.jpg
falsifian m: sub f{$^a eq '.'|'..'??Empty!!"rm $^a"};say f($_) for <. .. foo.txt bar.jpg>;
camelia ()
()
rm foo.txt
rm bar.jpg
falsifian For the same reason, 'foo' ~ |<bar baz> should be |<foobar foobaz>. 14:16
In general, it would be nice if ( do_something f($_) for @x ) and ( do_something $_ for map &f, @x ) did the same thing. 14:17
Full disclosure: this did not come up in a real application. But the current behaviour seems kind of arbitrary in comparison.
tonyo . 14:27
falsifian Actually, I missed up my example and now I'm a little confused.
Voldenet >'foo' ~ Empty should be Empty 14:28
sure why not
m: multi infix:<~>(Str $s, Positional $p) { $p.map($s ~ *) }; say "foo" ~ Empty
camelia ()
Voldenet m: multi infix:<~>(Str $s, Positional $p) { $p.map($s ~ *) }; say "foo" ~ <bar baz> 14:29
camelia (foobar foobaz)
Voldenet I sort of agree that current behavior doesn't make much sense for collections 14:30
m: say "foo" ~ <bar baz>
camelia foobar baz
Voldenet m: say <foo oof> ~ <bar baz> 14:32
camelia foo oofbar baz
Voldenet m: say <foo oof> Z~ <bar baz>
camelia (foobar oofbaz)
Voldenet m: say "foo" X~ <bar baz>
camelia (foobar foobaz)
Voldenet But you can sort of control ~ in array contexts 14:33
m: say <foo oof> X~ <bar baz>; say <foo oof> Z~ <bar baz>
camelia (foobar foobaz oofbar oofbaz)
(foobar oofbaz)
falsifian m: 'rm ' ~ Empty
camelia WARNINGS for <tmp>:
Useless use of "~" in expression "'rm ' ~ Empty" in sink context (line 1)
falsifian m: say( 'rm ' ~ Empty ); 14:34
camelia rm
Voldenet m: say 'rm ' X~ Empty
camelia (rm )
Voldenet hmm mmmmm
falsifian That's different on my rakudo
I get 'rm ' ~ Empty is ().
v2022.12 14:35
Voldenet probably because it's not well-defined behavior or anything 14:36
after all ~ is for string concat only
falsifian I don't feel so strongly about "foo" ~ <bar baz>. It feels like a type error. But Empty is this weird value that reaches into the list it's added to and pretends it was never there. So, saying Empty ~ 'foo' is Empty would add a sort of consistency that wasn't there before. 14:37
Voldenet it makes a lot more sense when you see that ~ was only defined for Str, Buf and Blob and Junction (…huh?) 14:39
m: say "foo" ~ <bar baz>.any 14:40
camelia any(foobar, foobaz)
Voldenet m: say "foo" ~ Empty.any
camelia any()
Voldenet Huh…
falsifian m: sub cmd{'rm '~$^a}; sub filename{$^a eq '.'|'..'??Empty!!$^a~'.txt'}; say cmd filename $_ for <. .. foo bar> 14:43
camelia rm
rm
rm foo.txt
rm bar.txt
falsifian m: sub cmd{'rm '~$^a}; sub filename{$^a eq '.'|'..'??Empty!!$^a~'.txt'}; say cmd $_ for map &filename, <. .. foo bar>
camelia rm foo.txt
rm bar.txt
Geth docker: a25034533b | (Daniel Mita)++ | 5 files
Bump to 2023.04
docker: 908f33d76c | Altai-man++ (committed using GitHub Web editor) | 5 files
Merge pull request #54 from Raku/2023.04

Bump to 2023.04
falsifian m: sub cmd{'rm '~$^a}; sub filename{$^a eq '.'|'..'??Empty!!$^a~'.txt'}; say (cmd filename $_ for <. .. foo bar>) 14:45
camelia (rm rm rm foo.txt rm bar.txt)
falsifian multi infix:<~>(Str $s,Empty){Empty};sub cmd{'rm '~$^a}; sub filename{$^a eq '.'|'..'??Empty!!$^a~'.txt'}; say (cmd filename $_ for <. .. foo bar>)
(rm foo.txt rm bar.txt)
evalable6 (rm foo.txt rm bar.txt)
falsifian m: multi infix:<~>(Str $s,Empty){Empty};sub cmd{'rm '~$^a}; sub filename{$^a eq '.'|'..'??Empty!!$^a~'.txt'}; say (cmd filename $_ for <. .. foo bar>)
camelia (rm foo.txt rm bar.txt)
falsifian There, that's the example I wanted where the behaviour helps.
The current behaviour on Junctions makes sense to me. I guess I'm proposing to have Slips behave sort of like Junctions when you try operations intended for single values. 14:47
m: if 'foo.txt' eq ('foo'|'bar')~'.txt' { say 'found it' } 14:48
camelia found it
Voldenet I'd say that most operators expecting scalars ($a <op> $b) could simply use $a.map(* <op> $b) or $b.map($a <op> *) depending on which is Positional
m: say 1 + <2 3>
camelia 3
Voldenet vs 14:49
m: my multi:<+>(Int $a, Positional $b) { $b.map($a + *) }; say 1 + <2 3>
camelia ===SORRY!=== Error while compiling <tmp>
Whitespace required after keyword 'multi'
at <tmp>:1
------> my multi:<⏏+>(Int $a, Positional $b) { $b.map($a +
expecting any of:
colon pair
quote words
Voldenet m: my multi infix:<+>(Int $a, Positional $b) { $b.map($a + *) }; say 1 + <2 3>
camelia (3 4)
falsifian Hm, that might be handy. I do think it would be good if slip-ness were preserved, though; Slip.map seems to produce a non-slip. 14:54
Voldenet that's separate issue, Slip.map probably becomes reified list at some point 14:56
since Slip doesn't have map defined
falsifian I guess either change would cause trouble for people who depend on the current behaviour of +. I'm sure people rely on it for Arrays; wouldn't be surprised if Slips end up getting used in arithmetic too. 14:58
Thanks for your thoughts, Voldenet. 14:59
aru_ looking at docs.raku.org/language/create-cli , I'm failing to express "a named argument which needs to be provided". Any tips on that? 15:19
Voldenet `people who depend on the current behaviour of +` (´_ゝ`) 15:33
I understand it can be used that way, but while it's a nice shorthand it seriously obfuscates the code 15:34
calling `.elems` on things makes everything a lot more obvious
in perl5 `1 + [2, 3]` returns extremely wild result 15:36
compared to `1 + (2, 3)` 15:37
(not that either of those behaviours make sense) 15:38
Nemokosch Lol 15:56
There is just too much of these voluntaristic ideas, .Numeric as .elems is a good example... 15:59
But .elems as empty-check is also a common mistake that will be hard to get rid of 16:00
aru: :$my-required-argument! 16:04
Or: :$my-required-argument is required
aru_ oh, thank you 16:10
Nemokosch falsifian: I think you mistook prefix | as in slips for infix | as in disjunctions 16:33
falsifian Nemokosch Why do you say that? I understand a|b is a disjunction, totally different from |<a b>, a Slip. I was suggesting operations should auto-map over slips like they do over junctions, for a different reason. 16:35
Voldenet > .elems as empty-check is also a common mistake
Positional only provides .elems 16:36
well, .EXISTS-POS(0) maybe but perhaps that's even weirder than .elems
in fact using coercions automatically (to Int, Str or Bool) obfuscates things 16:39
Nemokosch Does Positional provide .elems? I don't think it should 16:41
Voldenet m: my role Eh does Positional { method elems { 0 } }; my @x is Eh; say (if @x.elems { "non-" }) ~ "empty"
camelia empty
Voldenet the above works as expected
m: my role Eh does Positional { method elems { 0 } }; my @x is Eh; say (if @x { "non-" }) ~ "empty"
camelia non-empty
Voldenet …doesn't but it should 16:42
so I'd say using .elems is actually good if that's what you mean
Nemokosch And I for one surely don't agree that coercions obfuscate things, quite the contrary
Voldenet as demonstrated above, .elems works, coercing doesn't
Nemokosch You exicitly defined elems though 16:43
Voldenet m: my role Eh does Positional { method elems { 0 }; method Bool { .elems == 0 } }; my @x is Eh; say (if @x { "non-" }) ~ "empty"
camelia empty
Nemokosch If you never overload a method/operator and your only implementation coerces, that's not just safe but I'd say nothing can be safer 16:44
Voldenet uh 16:46
m: my role Eh does Positional { method elems { 0 }; method Bool { self.elems > 0 } }; my @x is Eh; say (if @x { "non-" }) ~ "empty"
camelia empty
Voldenet that's more correct 16:47
obviously `.elems == 0` isn't 0
_obviously_
Nemokosch self.elems is possibly costly and can even fail on lazy or infinite data
Voldenet Indeed, but `if @x` needs to somehow determine whether it's empty 16:48
in the most simple cases Positional has .elems that works reliably
lizmat Array.Bool and List.Bool are optimized for that afaik
Voldenet things fall apart when you stop using built-ins 16:49
Nemokosch Because again, Any provides a lot of methods that it just shouldn't 16:51
Voldenet In case where `@ means Positional` using .elems makes sense
for `unless/if @x.elems { }` 16:52
Nemokosch If you know for sure that you have a safe implementation of .elems/a data structure where it cannot cause trouble
Voldenet Well, returning `Inf` from elems is an option 16:54
Voldenet otoh if Positional simply had .is-empty, it would be more obvious 16:55
lizmat docs.raku.org/language/subscripts#method_elems 16:56
"Expected to return a number indicating how many subscriptable elements"
Voldenet setting speed side aside for a second, this would be saner perhaps 17:00
m: my role Positional2 { method is-empty { self.elems == 0 }; method Bool { !self.is-empty }; }; my role Eh does Positional2 { method elems { 0 } }; my @x is Eh; say (if @x { "non-" }) ~ "empty"
camelia empty
Voldenet m: my role Pos { method elems { … }; method is-empty { self.elems == 0 }; method Bool { !self.is-empty }; }; my role Eh does Pos { }; my @x is Eh; say (if @x { "non-" }) ~ "empty" 17:07
camelia non-empty
Voldenet that is… peculiar
lizmat I guess because Any.elems exists, the implementation check doesn't fire 17:08
m: role A { method elems { ... } }; A.new
camelia ( no output )
lizmat m: role A { method elemz { ... } }; A.new
camelia Method 'elemz' must be implemented by A because it is required by roles: A.
in block <unit> at <tmp> line 1
Voldenet Yes, well, it's implemented obviously 17:09
still, Positional could be more strict about its implementations
lizmat m: role A is Mu { method elems { ... } }; A.new 17:10
camelia Method 'elems' must be implemented by A because it is required by roles: A.
in block <unit> at <tmp> line 1
lizmat that could be a way out ?
Voldenet Ah, that works
m: my role Pos is Mu { method elems { … }; method is-empty { self.elems == 0 }; method Bool { !self.is-empty }; }; my role Eh does Pos { method elems { 0 } }; my @x is Eh; say (if @x { "non-" }) ~ "empty"
camelia empty
Voldenet given that, `my @x is Something` could warn if the implementation wasn't Positional then 17:11
in which case, `if @x { }` would be always safe to use 17:12
Voldenet (now that I see it, @x.elems is not safe either, because it's 1 by default) 17:13
Nemokosch Is there a critical mass of these problems after which they won't be wiped off the table? 17:14
It's absolutely not like they cannot be fixed 17:15
lizmat Nemokosch then please fix them 17:16
Voldenet The comment explains the "Why" behind Positional github.com/rakudo/rakudo/blob/a757...nal.pm6#L5 17:19
Nemokosch That would imply that we have a design or even review process. 17:25
Anybody is able to delete a method from Any.pm6 17:26
lizmat without affecting spectest and/or blin runs ? 17:30
Nemokosch The spectest has been used and abused by Rakudo staff, it cannot be used as things stand either way. It is indeed a "minefield" 17:33
lizmat together with blin, it's the best we have 17:35
lizmat also, what is this "Rakudo staff" you speak of? 17:35
Voldenet all the volunteeers that decided to create pull requests 17:36
evil volunteers consortium
Nemokosch Yeah, like myself, sure
Check the people who commit to both Rakudo and Roast directly 17:37
lizmat "staff" implies employment
at least according to my dictionary
so I think the word "staff" is incorrect in the context of "Rakudo staff" 17:38
Voldenet no person has "final voice" in all this, so I see no problems in trying to change spectests while removing .elems from Any 17:39
as long as everyone considers it a good change 17:40
lizmat such a change should be done at a language level, though
Nemokosch The problem is that "language versions" are used as a dummy for Rakudo breaking changes, and hold back a lot 17:42
lizmat agreeing on the holding back a lot, *NOT* that it is used as a dummy 17:43
Nemokosch A huge discussion sparked from a fixed bug with infinite ranges, remember? 17:45
That fix was meant to be version c
But that would mean that Rakudo doesn't pass the spectest so I guess it didn't even appear as an option 17:46
lizmat you mean the is-monotonically-increasing patch to Iterator ? 17:47
Nemokosch No, the mistake with .elems 😛 17:50
Voldenet at the end good ideas are stopped by needing to deal with the fallout of broken things… 17:58
Nemokosch Exactly, and this is amplified by the fact that the people with actual power to just decide and do something, are predominantly interested in Rakudo and not much besides 18:11
lizmat It's true: I want to see a working implementation of the Raku Programming Language 18:21
today: using Rakudo for this, is the best bet
so yes, Rakudo has focus
Nemokosch Do you think Rakudo is a good enough foundation to attract people by its sole presence? 18:28
lizmat I would prefer to see more implementations, but since we only have one active implementation, it's what we have to make do by 18:30
Nemokosch well, my concern has been, and I hopefully managed to express that in a certain email, that Rakudo takes priority over language design, ecosystem, community considerations - and that seems toxic 18:49
lizmat so you'd rather see another RFC process ? 18:58
tbrowder__ hi, can anyone please point me to where the class attribut trait "is entry" is described in the docs? thanks. 19:05
lizmat is entry? is that a standard attribute?
tbrowder__ *attribute
lizmat tbrowder_ I do not know of what you speak 19:07
tbrowder__ I do not know of what you speak
tbrowder__ i'm not sure. David Warring uses it in his PDF::* modules, in particular in PDF::Lite.
lizmat rakking the Rakudo source for §entry doesn't give anything meaningful 19:09
tbrowder__ iit looks like a clever way to easy adding attributes to a derived class from other classes. his code is too complex for my
level.
lizmat so it's not a core thing? 19:10
tbrowder__ i guess not. i've tried grepping for it in some of his code but nothing hits me yet. there is a bunch of stuff in docs about attaching stuff to packages i don't understand but may give a clue. i'll ask david, though. thnx 19:12
lizmat yw, sorry to not have been able to be of more help 19:13
Nemokosch lizmat: I don't know, frankly. Definitely not the kind of RFC process that lead to the apocalypses and synopses 19:24
and I don't think an RFC process is appropriate for management kind of stuff
lizmat wouldn't want to go that way again either
Nemokosch however, if I look at something like the RFC of PHP, the picture is completely different. Concrete proposals well-argued, several considerations about the impact of the change, and eventually changes can be made to a language that had all kinds of handicaps to Raku 19:27
lizmat afk& 19:28
tbrowder__ .tell lizmat look8ng 19:33
tellable6 tbrowder__, I'll pass your message to lizmat
tbrowder__ .tell lizmat it may be a role or class, surprising me, but given complexity of pdf it makes sense, we'll see, lots of code to download 19:35
tellable6 tbrowder__, I'll pass your message to lizmat
hythm m: my %h; %h<a> = 1; say %h{ 'A' }; say %h{ /:i 'A' / } ## is it possible to access a hash with a regex instead of a Str? (the hash keys are unique, meaning that there will always be %h<a> or %h<A> but not both) 21:10
camelia (Any)
Regex object coerced to string (please use .gist or .raku to do that)
(Any)
in block <unit> at <tmp> line 1
Regex object coerced to string (please use .gist or .raku to do that)
in block <unit> at <tmp> line 1
ugexe how would it know that it wasn't indexed on a regex object? 21:19
m: my %h{Regex}; my $rx = rx/foo/; %h{$rx} = 1; say %h{$rx};
camelia 1
hythm for the purpose I'm using, the hash will not be indexed with regex, I construc tthe hash with Str keys only 21:20
ugexe even then, looking up keys with a regex only makes sense for string keys
hythm construct* 21:21
ugexe im explaining why such functionality doesnt exist
its not very generic, and would have all sorts of corner cases
so you'd have to implement something yourself using AT-KEY 21:22
why it doesn't exist in the core rather^
hythm I see. "my %h{Regex}" might actually suit my use case here, I will try this and see how it goes. thanks
ugexe m: role LookupRegex { multi method AT-KEY(Regex $key) { return self.grep({ $_.key ~~ $key }).head } }; my $h = Hash.new but LookupRegex; $h<foo> = 1; say $h{rx/o/}; say $h{rx/a/} 21:28
camelia foo => 1
Nil
perryprog Just for fun, I'm curious if there's much I can do to golf a one-liner like this. I'm also curious to see if anyone has any clever versions that add in some shell stuff (or are only shell stuff) 21:52
raku -e "for \$*HOME.add('some/path').dir(test => /'.' ext\$/) { run <python scripts/some-script.py>, .Str, '/some/path' ~ .basename }"
I'm asking because 1) I didn't want to figure out the ritual setup to make xargs do something like that (and it was erroring because one of the files had an apostrophe in it, and 2) I'm not sure how to better supply more natural pathnames. 21:53
I can't do "~/foo/bar".IO since that doesn't expand ~ to $HOME, and I thought I couldn't do relative pathnames but I think that was just because I did it wrong 21:54
Yeah, relative paths are fine 21:55
lizmat hythm: perhaps raku.land/zef:lizmat/Map::Match is something for you ? 21:58
hythm thanks lizmat, that's exactly what I needed. 22:01
gfldex perryprog: I would .hyper(:1batch) that. Loops are lame, you know. :-> 22:08
perryprog I'm not sure I can parallelize this specific script (external IO stuff) but you know let's see what happens if I try 22:09
hm, no speed change... 22:13
gfldex The overhead of `run` is quite hefty. 22:28