|
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
|
|||