This channel is intended for people just starting with the Raku Programming Language (raku.org). Logs are available at irclogs.raku.org/raku-beginner/live.html
Set by lizmat on 8 June 2022.
00:16 jgaz left 00:48 CodeTortoise joined 00:56 jaguart joined
jaguart why are private multi methods not allowed? 02:33
guifa I'm not sure if that's more of an NYI or not allowed 02:35
jaguart I just realised I can make them subs :) 02:36
guifa that's what I was about to suggest :-) 02:38
m: class A { my proto foo (|) { * }; multi foo (\self, Str) { 'string' }; multi foo (\self, Int) { 'int' }; method bar($x) { self.&foo($x) } }; say A.bar(1); say A.bar('a') 02:40
camelia int
string
jaguart :) thank you 02:49
Why do you write a proto? are there gotchas from not? 02:55
guifa Force of habit really 02:58
But in this case I guess it doesn't really cause any problem. 03:00
03:10 CodeTortoise left
jaguart does a return type constraint on the proto apply to all the same-name multis? 03:13
guifa huh, it doesn't 03:16
but you can fairly easily, although it's only checked at run time: 03:17
m: proto sub foo (--> Int) { * }; multi sub foo (-->Str) { 'bar' }; say foo; 03:18
camelia bar
guifa that has no problem
m: m: proto sub foo (--> Int) { {*} }; multi sub foo (-->Str) { 'bar' }; say foo;
camelia Type check failed for return value; expected Int but got Str ("bar")
in sub foo at <tmp> line 1
in block <unit> at <tmp> line 1
guifa basically, if your proto is { * }, then the body of the proto is ignored; BUT if you use {*} inside of the proto body, that gets the result of the dispatch out. Since that's a return value for the proto block, it's actually type checked on the return type 03:20
jaguart interesting - so I read that {*} is the proto-body - and guess that { * } is a Whatever in a block... 03:21
Raku feels too subtle sometimes 03:22
guifa Yeah 03:25
I think of {*} as a special term
jaguart so if you want type-check using your proto - which feels like a good thing - pull the dispatch into your proto a'la { {*} }
We need a good-habits page, though it should be longer than the 'traps' page [which will be hard] - :o 03:26
guifa I'd agree. I think right now there's not a lot of sanity checks happening at compile time for multis relative to the proto 03:27
jaguart grrr. I have this `method attributes {` ==> but this call is NOT barfing: `for $wisp.mop.methods( :all, :$local ) ->` and I can't golf it 03:44
rf Does that proto: (|) { * }; do anything? 04:06
05:03 rf left 05:40 Kaipii left
jaguart given ' Method+{<anon|1>}|3855621948592' what regex might I use to split on '|' outside curlies? 07:27
actually scratch that - I will use an end-anchor 07:29
10:19 Kaipii joined
yabobay ``` 16:27
constant $filename = "in";
given $filename.IO.open(:r, :bin) {
my $signature = .read(8).List; # the first 8 B of a png is its signature
my $normalPngSignature = (137,80,78,71,13,10,26,10);
.say for $signature, $normalPngSignature;
say $signature == $normalPngSignature;
}
```
i have this raku program, and a plaintext file called "in", and it produces this result:
```
(48 49 50 51 52 53 54 55)
(137 80 78 71 13 10 26 10)
True
```
the two lists are clearly different. what is going on?
guifa jaugart: btw, I found out why multi return values don't have to line up with protos: if you do `proto sub foo (-->Str) { …; my $a = {*}; … }` , you could potentially act on the value of $a, and behave differently before finally producing a str 16:33
17:06 Kaipii left 17:09 Kaipii joined
Nahita `==` is numeric equality checker and $signature and $normalPngSignature have the same number of elements, so it says True 18:13
18:13 Kaipii left
`eqv` might be used instead 18:13
a List in numeric context is its number of elements 18:14
18:44 discord-raku-bot left, discord-raku-bot joined 19:15 Kaiepi joined
p6steve m: "well".Numeric 19:25
m: "well".elems 19:26
m: "well".elems.say
in raku a Str is not an Array of Chars ... so it will not coerce to Numeric 19:27
m: say "well" eq 4 19:28
m: say 4.Str 19:29
however an Int will coerce to a Str
Nahita a String can be converted to Numeric though, if it looks like one 19:30
e.g., "1299" .Numeric
so "17" == 17 will be True 19:32
user requested comparison in the numeric context and that's what they get!
user requested comparison in the numeric context and that's what they get 19:33
yabobay so what is == in other languages would be eqv in raku?
Nahita yeah kind of i think
since language also has binding, there's also =:= for example 19:34
yabobay what's that
Nahita even the containers should be the same check
```perl 19:35
>>> my $a = 3
3
>>> my $b = 3
3
>>> $a == $b
True
>>> $a =:= $b
False
```
p6steve oooo (that's cool) 19:52
Nahita user requested comparison in the numeric context and that's what they get! 19:57
Nemokosch <@989550365533937664> well well, there is a number of "equivalence operators" with their own subtleties 20:06
`==` is "obtain Numeric and check for equality"
(its negative counterpart doesn't really exist but don't get me started on that just now) 20:08
`eq` is "obtain String and check for equality" (same way, its negative counterpart looks like `ne` but in fact it doesn't exist as a proper first-class operator) 20:09
`=:=` is "obtain low-level address and check for equality" 20:11
basically the equivalent of reference check 20:12
`===` is "obtain WHICH representation and check for equality"
20:12 rf joined
unlike the address, WHICH is something that can be defined for types. It is used as a higher-level identity of data - for value types (deeply immutable types), it should be the same for the same value 20:14
for "reference types", it's usually still some low-level address
WHICH is a string representation 20:15
now, `eqv` uses another string representation of the data: the `.raku method`
now, `eqv` uses another string representation of the data: the `.raku` method
the `.raku` method is supposed to return a string with the following semantics: the string should describe the data like code that could generate that data 20:17
yabobay aaaaaaaaaaaaaaaaaaaaaaaaaa
Nemokosch so while the WHICH value of two List instances would be different (that still relies on the address of the objects), the .raku value of them would be the same 20:18
lizmat Ideally, .raku is the opposite of .EVAL, and should roundtrip
m: say '42'.raku.EVAL
camelia 42
yabobay m: '42'.raku.EVAL.WHAT 20:19
uh
Nemokosch didn't generate output I guess
m: '42'.raku.EVAL.WHAT.say
yabobay oh right
lizmat m: '42'.raku.EVAL.WHAT.say 20:21
camelia (Str)
Nahita if you are implying eqv returns True iff .raku's are the same, that is wrong 20:23
documentation has an example for it you can check
Nemokosch github.com/rakudo/rakudo/blob/704a....pm6#L1321 20:24
well, if you mean that their type can be different while their representation is the same... perhaps? although that seems fairly odd 20:25
Nahita no i don't mean that
Nemokosch other than that, it's literally the check performed for `eqv`
Nahita class A {}; my \a = A.new.Set; my \b = A.new.Set; (a.raku eq b.raku, a eqv b) 20:26
m: class A {}; my \a = A.new.Set; my \b = A.new.Set; (a.raku eq b.raku, a eqv b).say
Nemokosch well, why does this happen, then? 20:27
Nahita documentation has an example for it you can check 20:28
Nemokosch where does documentation have an example? 20:29
and that doesn't seem to answer the question what happened there 20:30
Nahita it has "The reason is that" i don't know what you are not seeing 20:31
and i don't really care
Nemokosch it would be hard for you to provide less help with more words, wouldn't it 20:32
but okay, I can google "the reason is that" on the website lol
p6steve docs.raku.org/routine/eqv 20:36
quite a good read 20:37
Nemokosch yes, googling "the reason is that" actually did help xD 20:38
you know, these days, I tend to trust the logic of the code more than what the docs say
for example because the docs haven't been deployed for several months 20:39
so right now I'm trying to figure out what got called actually
say, you look up `eqv` on the docs site 20:40
the behavior is described for 3 types 20:41
if you `rak` the Rakudo sources, it's defined for about 10 types
github.com/rakudo/rakudo/blob/704a...y.pm6#L300 20:42
p6steve I am a great fan of the core documents ... and I have a lot of respect for the documentation team (which is a thankless task) ... yes there are some wrinkles but imo these are 3rd order and there is nowhere else that compares for an explanation of the rationale
Nemokosch and now I think the described behavior can be found ^right there
smartmatch semantics are used 20:43
and Set(A.new(a => 5)) doesn't accept another instance of itself
which is debatable at best for smartmatch semantics, I would say 20:44
so I'd say "eqv doesn't necessarily rely on the raku representation": point taken 20:45
"see <this example>": this example is arguably wrong behavior
> This could be called an equivalence operator, and it will return True if the two arguments are structurally the same, i.e. from the same type and (recursively) contain equivalent values. 21:01
It doesn't seem to be hard to make this True
A.new(a => 5) and A.new(a => 5) are "equivalent values" by the default implementation 21:02
23:09 NemokoschKiwi joined 23:29 kjp joined