🦋 Welcome to the MAIN() IRC channel of the Raku Programming Language (raku.org). This channel is logged for the purpose of keeping a history about its development | evalbot usage: 'm: say 3;' or /msg camelia m: ... | Log inspection is getting closer to beta. If you're a beginner, you can also check out the #raku-beginner channel! Set by lizmat on 25 August 2021. |
|||
leont | Yeah, there are only $_, $/ and $!, and the last one is barely magical. | 00:00 | |
Xliff | MasterDuke++ | 00:01 | |
MasterDuke: Getting a 404 from that URL | 00:02 | ||
leont: Don't the dynamics count? | |||
leont | I wouldn't consider them magical, TBH | ||
Xliff | OK | 00:03 | |
00:06
reportable6 left
|
|||
leont | They're just differently namespaced | 00:11 | |
00:32
timm left
00:33
timm joined
00:37
timm left
00:43
timm joined
|
|||
guifa | Nemokosch: the topic actually is a bit different between Perl and Raku. The idea of the topic in perl is from pro-drop languages (Larry is a linguist by trade). In, e.g., Spanish, I can say "El perro es grande. Es negro. Ladra." (literally: The dog is big. Is black. Barks"). There's no need to repeat the subject | 00:48 | |
Each followed the natural language convention that a topic is established and continued, but Perl did it at a line-by-line level, and Raku does it a block level | 00:49 | ||
Generally, you shouldn't need to reference the topics, just like in such pro-drop languages, you'd rarely use the subject explicitly except for emphasis | 00:51 | ||
to me, given $foo { .bar; .baz; .abc; .say } is a bit clearer than $foo.bar; $foo.baz, $foo.abc, $foo.say | 00:52 | ||
I guess with is probably the better control word there but both work | |||
The nice thing though is, just like my students learning Spanish, you're not *required* to use it. AFAIK, every structure in Raku that might use a topic variable has a way to use an explicit named variable instead, at the cost of a bit more line noise (although, no more than most other programming languages) | 00:54 | ||
Nemokosch | the dynamics don't count in my opinion, even though they also seem to be a "writers first" feature | 01:05 | |
for the topic variable, I don't know how it is in Perl and I suspected it got simplified in Raku | |||
still, I think it's useful to think "inside the box", and outside of the Perl macroverse | 01:07 | ||
I'm no ambassador of outsiders but I have the impression many people would raise their eyebrows if you told them that Raku was designed with the outsider reader in mind | |||
01:09
reportable6 joined
|
|||
> to me, given $foo { .bar; .baz; .abc; .say } is a bit clearer than $foo.bar; $foo.baz, $foo.abc, $foo.say | 01:09 | ||
I kind of agree, also, this kind of code is a pleasure to refactor even with notepad | |||
01:12
xinming left
01:14
xinming joined
01:20
f00 joined,
timm left
01:24
f00 left,
f00 joined
01:29
f00 left
02:29
shareable6 left,
greppable6 left,
linkable6 left,
squashable6 left,
releasable6 left,
evalable6 left,
tellable6 left,
quotable6 left,
benchable6 left,
coverable6 left,
notable6 left,
bloatable6 left,
committable6 left,
reportable6 left,
sourceable6 left,
bisectable6 left,
unicodable6 left,
nativecallable6 left,
statisfiable6 left,
committable6 joined,
evalable6 joined
02:30
benchable6 joined,
coverable6 joined,
reportable6 joined,
sourceable6 joined,
quotable6 joined,
squashable6 joined,
linkable6 joined
02:31
unicodable6 joined
02:32
tellable6 joined
02:37
xinming left,
xinming joined
|
|||
guifa | Nemokosch: using the topic variable definitely takes a little bit to get used to, but once you do, it's very easy on the eye as a user. At the very least, though, starting a line with a .foo should signal to a non-Raku user that *something* is going on, and hopefully it doesn't take long to find out it's acting on the topic | 02:40 | |
leont | And unlike in Perl (where it's essentially a dynamic variable) it's lexical, so it doesn't have weird action at a distance issues. | 02:43 | |
03:29
releasable6 joined
03:31
statisfiable6 joined,
bisectable6 joined
04:23
xinming left
04:24
xinming joined
04:30
greppable6 joined
04:32
notable6 joined
05:08
toastloop joined
05:30
bloatable6 joined
05:49
mexen joined
06:07
reportable6 left
06:18
Kaiepi left
06:21
Altai-man_ joined
06:22
Altai-man_ left
06:30
nativecallable6 joined
06:37
Kaiepi joined
06:45
Altai-man left
06:48
sena_kun joined,
sena_kun left
07:09
reportable6 joined
07:19
phogg left
07:24
abraxxa joined
07:29
abraxxa left,
abraxxa joined
07:31
phogg joined
07:52
jjido joined
08:06
Sgeo left
08:07
Sgeo joined,
jjido left
08:30
shareable6 joined
08:34
jjido joined
08:45
jjido left
08:48
toastloop left
08:49
toastloop joined
08:51
dakkar joined
09:00
f00 joined
09:18
patrickb left
09:19
patrickb joined
09:35
jjido joined
09:41
Darkcoal joined,
Sgeo left
09:50
toastloop left
|
|||
Voldenet | I consider dynamic variables mostly an antipattern | 10:02 | |
the biggest issue with them is when you need to use some process using changing dynamic variable | 10:03 | ||
10:05
jjido left
|
|||
Voldenet | `my $*unclear = "a"; code(); { my $*unclear="b"; code(); }; code()` vs `code("a"); code("b"); code("a");` | 10:06 | |
Nemokosch | they are essentially hidden globals | ||
again, okay for prototyping | |||
Voldenet | I'd say okay for rarely used code that never needs to switch context, like loggers | 10:07 | |
10:08
f00 left
|
|||
Nemokosch | what would that look like? | 10:10 | |
Voldenet | for instance: `my $*sql-executing = -> $_ { .query.say }; some-complicated-process-using-sql($conn.start-transaction)` | 10:11 | |
however, `$conn.sql-executing = …` would be as fine | 10:12 | ||
but then it would pollute connection's state, so it would start logging things outside of the current routine | 10:13 | ||
Nemokosch | tbh it's hard to come up with a good use | 10:14 | |
one thing is sure: it's never unavoidable | 10:16 | ||
lizmat | please note that dynamic variables are used extensively internally, without it e.g. react / whenever would not work | 10:33 | |
(or at least be a lot harder to implement) | |||
Voldenet | While there are good examples where it makes sense, "avoid it until you decide that you can't" is a good rule | 10:38 | |
Nemokosch | I'm sure there are good examples, I've just never come across them so far 😛 | 10:39 | |
lizmat | dynamic variables make excellent default values for parameters | 10:45 | |
take e.g. the $*SCHEDULER variable. If you want to use another scheduler for your code, you don't need to pass it along everywhere, you just need to specify it in the outer dynamic scope of your code | 10:46 | ||
El_Che | (who schedules the scheduler?) | 10:49 | |
lizmat | the core does :-) | ||
El_Che | and who cores the core? :) | 10:50 | |
(weirdly enough, it's a verb) | |||
lizmat | I don't think I can verb my way out of this :-) | 10:51 | |
El_Che | :) | ||
Nemokosch | 😂 | 10:52 | |
El_Che | Star Trek famously ejects the core more often than not | ||
Efforts to speed up the raku core should be under the Scotty umbrella | 10:53 | ||
Voldenet | scheduler can schedule the scheduler just fine | 10:56 | |
El_Che | and decides it's fine? | 10:59 | |
Voldenet | "fine" is a decision made based on sanity of the original author | 11:01 | |
m: my $*SCHEDULER = class :: { method cue($code) { my $*SCHEDULER = CurrentThreadScheduler.new; start $code(); } }.new; await start { "why though".say }; | |||
camelia | why though | ||
Nemokosch | :DD | 11:02 | |
El_Che | Voldenet: so we end up with the "Lary is always right" axioma :) | 11:06 | |
Voldenet | I've seen threading apis using schedulers as method arguments and… uh, end result was difficult to understand | 11:08 | |
El_Che | I imagine | 11:11 | |
"Imagine there is no scheduleeeeeer" | 11:12 | ||
Voldenet | Scheduler is an implementation detail | ||
lizmat | the default scheduler is an implementation detail, yes | ||
but you can write your own, if you want to | |||
Voldenet | so it's useful to keep it hidden from people | ||
lizmat | well, most people don't know of its existence, so I think that part worked out :-) | 11:13 | |
El_Che | lizmat: I see you play the long game :) | 11:16 | |
lizmat | well, if you can't tell that by now... :-) | ||
El_Che | sue me, write me a open letter :P | 11:17 | |
an | |||
(I need to drink less coffee monday morning :) ) | |||
c.tenor.com/E-pWfHWt2xUAAAAd/tweak...-tweak.gif | 11:21 | ||
11:24
evalable6 left,
linkable6 left,
evalable6 joined
11:25
linkable6 joined
11:26
jjido joined
|
|||
Voldenet | If you think you've had too much coffee, you need more of it | 11:26 | |
El_Che | Voldenet: it sounds like a hangover fix | 11:32 | |
11:55
jjido left
11:57
frost left
12:00
jjido joined
12:07
reportable6 left
|
|||
qorg11 | Any way to convert bytes to base32? | 12:11 | |
12:23
jjido left
12:25
frost joined
|
|||
lizmat | m: dd 42.base(32) | 12:27 | |
camelia | "1A" | ||
lizmat | qorg11 ^^ | ||
qorg11 | Is that the encoding? | 12:34 | |
Like base64 but base32? | |||
lizmat | m: dd 65.base(32) | 12:35 | |
camelia | "21" | ||
lizmat | m: dd 63.base(32) | ||
camelia | "1V" | ||
Voldenet | it's not rfc4648 base32 | 12:36 | |
CIAvash | qorg11: didn't find anything in the ecosystem for base32, but maybe this will help: github.com/ugexe/Perl6-Base64/blob...Base64.pm6 | ||
Voldenet | it's base32 hex | ||
lizmat | there's also raku.land/zef:raku-community-modul...ME::Base64 | 12:37 | |
12:57
jjido joined
13:08
hankache joined
13:17
hankache left
13:37
euandreh left
14:00
frost left
|
|||
lizmat | And yet another Rakudo Weekly News hits the Net: rakudoweekly.blog/2022/02/21/2022-...rly-co-op/ | 14:02 | |
14:06
jjido left
14:08
reportable6 joined
14:12
euandreh joined
14:39
euandreh left
14:41
euandreh joined
14:45
qorg11 left,
qorg11 joined
14:46
qorg11 left,
gotem joined
14:55
euandreh left
15:02
dakkar left
15:03
dakkar joined
15:09
curiosa joined
15:10
curiosa joined
15:14
silug left,
silug joined
|
|||
Nemokosch | um, the second example of the second task is faulty again... where would you report? | 15:25 | |
talking about the weekly challenge | |||
Geth | ecosystem: c11ebef951 | (Elizabeth Mattijsen)++ | META.list Remove Color, Web::App and Web::App::MVC |
15:44 | |
15:49
euandreh joined
|
|||
[Coke] reads the weekly #153, and is not surprised that factorions seem a little scarce. | 15:58 | ||
Geth | ecosystem: e62f923cf6 | (Elizabeth Mattijsen)++ | META.list Move Andrew Egeler's modules to raku-community-modules Well, for those that now live in the Raku Community Modules Adoption Center. |
16:08 | |
guifa | Nemokosch: I definitely agree that dynamics are something to be used sparingly. But they are really useful when you hit those cases. One semi-useful place has been where I have a large number of small subs that need to be passed mostly the same variables, but I'm too lazy to write it out | 16:09 | |
my %formatters = a => { $*day }, b => { $*month }, c => { $*date-delimiter } | 16:10 | ||
lizmat | guifa: you could also let those subs share a lexical scope :-) | 16:11 | |
guifa | I mean, yes, assuming that works in the code structure | ||
16:11
patrickb left
|
|||
guifa | then you can just set those, and do something like $fmt-string.comb.map({ %formatters{$_}() }).join et violà | 16:12 | |
Geth | ecosystem: 9d0c359b7d | (Elizabeth Mattijsen)++ | META.list Freeze Net::SMTP While we're moving it to the zef ecosystem |
||
16:12
patrickb joined
|
|||
guifa | lizmat hence I said "semi-useful". Given that the code for formatters for the international datetime formatting is severla hundred lines long, it makes sense to pull it to a different scope (module, even, I think is how I last left it, but that module is ripe for a massive rewrite with RAST) | 16:13 | |
lizmat | :-) | ||
ok | |||
guifa ended up using $^vars though | |||
turns out those are the fastest way to pass args into a block | |||
at least as of last year when I benchmarked it | 16:14 | ||
lizmat | ah? faster than an explicit signature ? | ||
guifa | indeed! It was quite surprising to me | ||
lizmat | I thought they codegenned to the same thing? | ||
guifa | in RAST at least, they have separate nodes, but maybe at the QAST level they are handled the same | 16:15 | |
lizmat | well, I'm not seeing any difference between: | 16:16 | |
my $a = { $^a + $^b }; $a(42,666) for ^10000000 | |||
and | |||
my $a = -> $a, $b { $a + $b }; $a(42,666) for ^10000000 | |||
now | |||
guifa | Almost certainly newdisp touched on some of that stuff, yeah? | ||
lizmat | wouldn't think so | 16:17 | |
what it touched is how the infix:<+> is dispatched | |||
guifa | hmm, I dunno then | 16:18 | |
oh | |||
jeez | |||
my benchmark is even older than last year | |||
github.com/alabamenhu/IntlFormatDa...atters.pm6 | |||
lizmat | m: my $a = -> $a, $b { $a + $b }; dd $a.signature | ||
camelia | :($a, $b) | ||
guifa | "As of Dec 2020 in Rakudo, implicit positionals are the fastest" | ||
lizmat | m: my $a = { $^a + $^b }; dd $a.signature | ||
camelia | :($a, $b) | ||
lizmat | ok, not sure what changed since then | 16:19 | |
guifa | I'd almost do a new benchmark now with my code except … that's a lot of refactoring to do to test with when I'm just gonna gut it all ;-) | 16:20 | |
lizmat | yeah, sure. no pb :-) | ||
I think there *is* a difference between handling of \a and $a in a signature nowadays | |||
if it can be proven that $a is *not* an Iterable at compile time | 16:21 | ||
16:21
silug left
|
|||
guifa | oh yeah, this also reminds me I need to start working on DateTime::Calendars | 16:23 | |
guifa stares forbodingly at the book on his shelf titled Calendrical Calculations and the insane amounts of math and astronomical calculations and stuff | |||
lizmat | :-) | 16:24 | |
guifa | I guess an initial test could be one of the ones that's identical to gregorian, but for the epoch. I'm just curious if there's a way I can somehow get ::Calendars and ::Timezones to play nicely, such that they can be called in either order, and/or independently, deep in module scope or at top level scope | 16:26 | |
16:26
silug joined
|
|||
guifa | I *think* it would be easier if CORE::DateTime had a .calendar, .era, .cycle, .quarter attributes (easily supplied with initial attributes of 'gregorian', {.year > 0}, 0, { (.month + 2) % 3 }, but I think that'll be a summer project for me to figure out all that | 16:32 | |
lizmat | I think to have that in core, would be troublesome performance wise for the cases that don't need it :-( | ||
Anton Antonov | I have a regex that parses code lines, for example, ``` | 16:33 | |
my regex CodeLine { | |||
^^ | |||
$<indent>=(\h ** 2) | |||
$<code>=(<-[\h]> [<alpha> | '(' | ')' | '_' | '.' | \s | '::' | '$']+ ) | |||
$$ | |||
} | |||
``` | |||
I want to be able to use a variable to specify the number of indentation spaces (it is hard coded as 2 above.) Can specify that as an argument for the regex above, or should I make a function that creates regexes using a quantifier as an argument? | |||
guifa | my regex CodeLine($indent) { … \h ** $indent … } | 16:35 | |
err | 16:36 | ||
that $indent needs to go into a code block | 16:39 | ||
\h ** {$indent} | |||
Although it looks like passing that variable to the regex is annoying outside of grammars… so maybe use ..... | |||
guifa pauses while scrolling up and looking at Nemokosch quietly ;-) | 16:40 | ||
dynamic variable :D | |||
Anton Antonov | @guifa Thanks! | 16:41 | |
guifa | m: my regex foo { \h ** {$*indent} }; my $*indent = 2; say ' ' ~~ &foo; say ' ' ~~ &foo; | 16:42 | |
camelia | Nil 「 」 |
||
Anton Antonov | @guifa Yes, I tried that you suggest in the last line first without the curly brackets around `$indent` , so, yes, that works. | 16:43 | |
16:58
patrickb left
17:00
vrurg left
17:01
vrurg joined
17:04
patrickb joined
17:07
ccntrq joined
|
|||
Geth | ecosystem: 22ec24e8b2 | (Elizabeth Mattijsen)++ | META.list Freeze Email::Simple While we're moving it to the zef ecosystem |
17:08 | |
17:13
abraxxa left
17:21
mexen left
17:26
Sgeo joined
17:29
silug left,
djerius left
17:31
djerius joined
17:32
silug joined
17:34
dakkar left
17:41
silug left
17:48
silug joined
17:51
vrurg left
18:07
reportable6 left,
curiosa left
18:19
MasterDuke left
|
|||
Geth | ecosystem: 9d0d47bc59 | (Elizabeth Mattijsen)++ | META.list Freeze Net::IMAP While we move it to the zef ecosystem |
18:23 | |
19:21
vrurg joined
19:36
ccntrq left
19:59
MasterDuke joined
20:10
reportable6 joined
20:20
Darkcoal left
21:03
curiosa joined
|
|||
curiosa | Hi, I have a question. Let's say that you you have an object with many ro attributes. You want a method that return a new object with everything identical to the caller a part a few attributes. What would be the best way to write such a method in Raku? | 21:05 | |
one option is clearly to invoke new with all the arguments taken from the caller a part the few that are changed; this is quite bloated | 21:06 | ||
another option is to make all attributes rw and then call copy and modify only what need to modify, this doesn't fell the Raku's way | |||
what would you do? | |||
21:15
discord-raku-bot left,
discord-raku-bot joined
|
|||
Xliff | curiosa: Why would you want to do things that way? | 21:19 | |
If you want to selectively allow attributes to be rw, create methods for each attribute that allow you to customize the logic. | 21:20 | ||
tonyo | m: class AA { has $!o; has $!p; submethod BUILD(:$!o = 1, :$!p = 2) { }; method COPY(:$o = $!o, :$p = $!p) { return AA.new(:$o, :$p); }; method o {$!o}; method p{$!p}; }; my $a1 = AA.new(:o(2), :p(3)); my $a2 = $a1.COPY(:p(6)); dd [$a1.o, $a1.p]; dd [$a2.o, $a2.p]; | 21:24 | |
camelia | [2, 3] [2, 6] |
||
Xliff | m: class A { has $!may-not-be-writeable; has %!attribute-writeable; method may-not-be-writeable is rw { Proxy.new( FETCH => $!may-not-be-writeable, STORE => -> $, \v { unless %!attribute-writeable{ &*ROUTINE.name } { say "Attribute is not currently writeable!' return }; $!may-not-be-writeable = v }; }; method set-rw { %!attribute-writeable{ '$!may-not-be-writeable' } = True; }; method set-ro { %!attribute-writeable{ | 21:26 | |
'$!may-not-be-writeable' } = False }; }; | |||
camelia | ===SORRY!=== Error while compiling <tmp> Unable to parse expression in subscript; couldn't find final '}' (corresponding starter was at line 1) at <tmp>:1 ------> ; method set-ro { %!attribute-writeable{⏏<EOL> expecting any … |
||
Xliff | Hmm... I will have to repl this. One sec. | ||
tonyo | curiosa: ^ that pattern will let you control what can be modified on copy | 21:27 | |
curiosa | I prefer to do things in the most simple way | 21:41 | |
the thing is that I have | 21:42 | ||
a language that i am parsing that specify types | 21:43 | ||
and for each type there is an attribute that is number-of-bytes, let's say | |||
then I have arrays | 21:44 | ||
and arrays should multiply that attribute by the number-of-elements | |||
and return also a type | 21:45 | ||
all this is happening in the actions of a grammar, such that array-of gets the type of the element as a made argument | 21:46 | ||
tonyo | you can use some introspection to get that done in actions if you don't know what the attributes are at compile time, | 21:47 | |
Xliff | replit.com/@Xliff/YellowgreenAdole...#main.raku | 21:52 | |
^^ curiosa | |||
curiosa | that's nice | 21:57 | |
tonyo | m: class A {has $!o = 6; method o { $!o }; }; my $a1= A.new; sub copy($of, %vals) { my $cp = $of.WHAT.new; for $cp.^attributes.grep(*.readonly) -> $attr { $attr.set_value($cp, (%vals{$attr.name} // $attr.get_value) );}; $cp }; dd [$a1.o, copy($a1, '$!o' => 12).o] | 22:00 | |
camelia | [6, 12] | ||
tonyo | generic way to do it if you don't know what the object is at compilation ^ | 22:01 | |
22:04
slowtype- joined
22:05
slowtyper left
22:11
vrurg left
22:12
vrurg joined
22:19
vrurg left,
vrurg joined
22:27
Altai-man joined
22:35
Altai-man left
|
|||
japhb | Why not .clone? | 22:42 | |
docs.raku.org/routine/clone | |||
curiosa | omg, clone is perfect! | 22:43 | |
does clone calls TWEAK ? | 22:46 | ||
22:49
lgtaube left
|
|||
curiosa | damn, it doesn't | 22:51 | |
m: class a { has $.beer = 1; submethod TWEAK(:$beer) { $!beer = 2 * $!beer; } }; my $b = a.new(:beer(3)); say $b; say $b.clone: :beer(4) | |||
camelia | a.new(beer => 6) a.new(beer => 4) |
||
curiosa | isn't this a bug? | ||
japhb | Kinda feels like it, yeah. File a Rakudo issue? | 22:56 | |
23:03
lgtaube joined
|
|||
tonyo | .clone doesn't let you control what gets copied | 23:30 | |
23:33
curiosa left
23:40
ocomport joined
|
|||
gfldex | PWC#153 spoiler warning: gfldex.wordpress.com/2022/02/22/lo...ly-simply/ | 23:41 | |
ugexe | if TWEAK was rerun on .clone the it could modify various internal state which isn't what .clone should do | 23:59 |