🦋 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.
00:00 Manifest0 left
grondilu it cannot use the comparison I defined in A? 00:01
nemokosch hmm 00:02
grondilu If it can't, it means I can't reuse any sub defined in Real?? 00:03
nemokosch m: class A does Real { }; multi sub infix:«<»(A, 0) { Bool.pick }; multi sub prefix:<->(A) { rand }; say A.new.abs
Raku eval
nemokosch that's not much...
oh right, your candidate was probably wrong 00:04
I don't like this whole mishmash with types as sometimes types, sometimes values
grondilu m: class A does Real { }; multi sub infix:«<»(A, 0) { Bool.pick }; multi sub prefix:<->(A) { rand }; say A.new.abs 00:05
camelia MoarVM panic: Memory allocation failed; could not allocate 131072 bytes
nemokosch m: class A does Real { }; multi sub infix:«<»(A, 0) { say 'Actually executed'; Bool.pick }; say A < 0;
Raku eval Actually executed True
00:05 merp left
nemokosch m: class A does Real { }; multi sub infix:«<»(A, 0) { say 'Actually executed'; Bool.pick }; say A.new < 0; 00:05
Raku eval Actually executed True
nemokosch but it does run for an instance as well 🥹
m: class A does Real { method Bridge {...} }; multi sub infix:«<»(A, 0) { say 'Actually executed'; Bool.pick }; say A.new < 0; 00:06
Raku eval Actually executed True
grondilu m: wth 00:07
camelia ===SORRY!=== Error while compiling <tmp>
Undeclared routine:
wth used at line 1
00:07 merp joined
tonyo haha 00:07
grondilu wait the difference is just the multi?
nemokosch m: class A does Real { method Bridge {...} }; multi sub infix:«<»(A, 0) { say 'Actually executed'; Bool.pick }; multi sub prefix:<->(A) { say 'Unary minus also executed...'; rand }; say -A.new 00:08
Raku eval Unary minus also executed... 0.10870624375577653
grondilu no it's not
nemokosch m: class A does Real { method Bridge {...} }; multi sub infix:«<»(A, 0) { say 'Actually executed'; Bool.pick }; multi sub prefix:<->(A) { say 'Unary minus also executed...'; rand }; say A < 0 ?? -A !! A;
Raku eval Actually executed Unary minus also executed... 0.3647369977724271
grondilu I don't see the difference with what I wrote earlier
nemokosch right... 00:09
grondilu m: class A does Real { method Bridge {...} }; multi sub infix:«<»(A, 0) { Bool.pick }; multi sub prefix:<->(A) { rand }; say A.new.abs
camelia Stub code executed
in method Bridge at <tmp> line 1
in block <unit> at <tmp> line 1
nemokosch m: class A does Real { method Bridge {...} }; multi sub infix:«<»(A, 0) { say 'Actually executed'; Bool.pick }; multi sub prefix:<->(A) { say 'Unary minus also executed...'; rand }; my $v = A.new; say $v < 0 ?? -$v !! $v;
Raku eval Actually executed Unary minus also executed... 0.5301130943966046
nemokosch so if you hardcode everything, it works
if you want to reuse code
which supposedly roles are for
m: class A does Real { method Bridge {...} }; multi sub infix:«<»(A, 0) { say 'Actually executed'; Bool.pick }; multi sub prefix:<->(A) { say 'Unary minus also executed...'; rand }; my $v = A.new; say $v.abs 00:10
Raku eval Exit code: 1 Stub code executed in method Bridge at main.raku line 1 in block <unit> at main.raku line 1
nemokosch then it doesn't work
I see two possible explanations. Either it can't see the dynamic type of self, which would make it completely useless 00:11
grondilu ok I see now. so in the end, no, I can't reuse the abs code, because it refers to sub calls
nemokosch or it cannot see the global multi definitions 00:12
indeed, the latter is much more probable, and it kinda rings a bell
grondilu my guess is it does not see the global multi
nemokosch the same way sort won't take your own cmp operator into account
it could be made work but it's overhead and there was some controversy 00:13
grondilu is it correct semantics, though? It should be basic but I actually don't know enough about OOP to know.
m: role A { sub foo {...}; method bar { foo() } }; say class B does A { sub foo { "B::foo!" }; }.bar 00:15
camelia Stub code executed
in sub foo at <tmp> line 1
in method bar at <tmp> line 1
in block <unit> at <tmp> line 1
grondilu ^here for instance is A::bar suppose to call B::foo?
*supposed 00:16
nemokosch I think this is completely different from the operators, and here I think you are right
grondilu well operators are just subroutines with special syntax
nemokosch m: role A { sub foo {...}; method bar { foo() } }; say class B does A { sub foo { "B::foo!" }; }.foo
Raku eval Exit code: 1 No such method 'foo' for invocant of type 'B' in block <unit> at main.raku line 1
nemokosch wait, why was it a sub? 00:17
of course the method wouldn't dispatch to a sub in a random different scope
grondilu is it obvious? not to me.
nemokosch what does it even mean for a class or a role to contain a sub? 00:18
grondilu it's in its lexical scope?
nemokosch most probably 00:19
and I wouldn't expect scopes to have anything to do with method resolution rules
grondilu I mean lately I've been learning how to use dynamic variables, so I may be starting to hope to do something similar with subs. 00:20
nemokosch why would a simple local sub resolution turn into some method resolution mechanism
grondilu the point is anyway that using subs in a role, and inside its methods, kind of ruins the purpose of roles since we can't reuse these sub calls. 00:21
or rather redispatch them if that makes sense
like this abs method: it relies on infix:<-> and prefix:<->, but I have no way to modify how these work and apply it to abs. I have to rewrite it all. 00:23
nemokosch I think it's kinda different because in the operator case you didn't even scope the operator, it was in the mainline. Now, if not even the mainline is visible to the called core code, what is?
grondilu *infix:«<» 00:24
I don't know what is what you call the mainline
If abs had been written with only method calls : method abs { self.less-than(0) ?? self.negate !! self }, I could re-use it. 00:26
nemokosch that's right
honestly, I also don't know why it would be so difficult to add actual syntax to retrieve a method of a class, rather than doing metamodel hackery 00:27
it feels like a lot of effort is duplicated with functions and methods and the differences are too big 00:28
I'm almost certain an operator-driven approach would work in C++ and it would definitely work in Python where operators are really methods 00:30
vendethiel Some are, but then… 00:32
These have a predefined set of operators
nemokosch the question is, is this really a good tradeoff? 00:35
do you want to rather use new arbitrary operators in your own code and be unable to reuse existing operators when interacting with other code, or give up on the arbitrary operators while retaining the composability for the existing ones? 00:36
sounds like the usual weak typing vs strong/duck typing dichotomy 00:37
grondilu Is this really weak typing? We're still in the same branch of the inheritance tree.
nemokosch the inheritance tree did nothing here, as we can see... 00:38
grondilu because subs are not part of it 00:39
nemokosch the subs we care about are global anyway
grondilu why couldn't I overload them, then? 00:40
vendethiel Scala mangles the name of your operators
nemokosch because the core has a limited global scope compared to your own code
vendethiel No it’s the usual expression problem
nemokosch basically it's a scope registered into your global scope 00:41
it's mainly an interface problem
the principle that you should reserve existing operators with their existing behavior and provide clever coercions for your data types if you want to use them, and if you don't like the behavior, just ditch them and define new operators 00:42
vendethiel no
00:42 ProperNoun joined, deoac left
nemokosch this is basically the weak typing Raku worked out based on Perl 00:42
00:42 deoac joined 00:43 rf left
and it works well as long as the vast majority of your operations are carried out on common types only 00:43
probably that's why it worked so well for Perl
however, for more general purpose programming, you will define your own types much more often than new operations for the existing common types 00:44
and that's where reusing the same structural interfaces is not a curse but a necessity and a blessing 00:45
grondilu when it works 00:46
00:46 vrurg left
nemokosch the irony is that the coercions that power the weak typing system also couldn't work without such common interfaces, like the .Typename methods for Raku 00:46
00:47 vrurg joined
grondilu goes to sleep 00:47
nemokosch good night 00:48
01:02 ProperNoun left 01:03 ProperNoun joined 01:19 rf joined 02:00 deoac left 02:22 edr left 02:44 Sgeo left, Sgeo_ joined 02:46 Xliff joined
Xliff What's the best way to re-export a symbol when you are already exporting a bunch using "is export"? 02:47
05:43 sena_kun joined
grondilu Xliff: I was told some time ago to define EXPORT before declaring the module: discord.com/channels/5384078799804...4647170049 07:35
07:51 jpn left 08:02 lichtkind joined
Xliff grondilu: What's at that link? I generally don't do discord because it litters accounts! 08:09
And I am now getting the dreaded "Message failed to load" error.
grondilu: Can you please port the important bits of that somewhere I can view it? Thank.s 08:10
08:13 Sgeo_ left 08:15 dakkar joined, Manifest0 joined
lizmat the EXPORT sub needs to be outside of any package in the compunit 08:19
example of exporting "ok" from Test:
use Test; 08:20
sub EXPORT() { Map.new: ('&ok' => &ok) }
Xliff Does that also work for a compunit that is already exporting things? In that example, would anything else marked "is export" also be exported or only &ok? 08:21
lizmat only ok in that case: the EXPORT sub overrides 08:23
Xliff OK. How can I write one to preserve the existing exports
lizmat by walking EXPORT::DEFAULT::.keys 08:26
m: sub foo() is export { }; dd EXPORT::DEFAULT::.keys
camelia ("\&foo",).Seq
Xliff Or would this work? 08:27
sub EXPORT() { Map.new: ( '&ok', |Module::EXPORT::DEFAULT::.pairs ) } 08:28
Err... that would be... 08:29
sub EXPORT() { Map.new: ( '&ok' => &ok, |Module::EXPORT::DEFAULT::.pairs ) }
lizmat without the Module:: I think 08:30
that's the whole point: the export is done by the compunit, *not* any other package
Xliff lizmat: OK, so I would have to do that inside the module and publish it via some data structure. 08:36
m: package A { sub a is export { 42; }; A::EXPORT::DEFAULT::.keys
camelia ===SORRY!=== Error while compiling <tmp>
Missing block
at <tmp>:1
------> xport { 42; }; A::EXPORT::DEFAULT::.keys⏏<EOL>
expecting any of:
statement end
statement modifier
statement modifier loo…
lizmat the publishing is done by the EXPORT sub by what it returns in the Map
Xliff m: package A { sub a is export { 42; }; }; A::EXPORT::DEFAULT::.keys.gist.say 08:37
camelia (&a)
Xliff Actually...that works well enough.
lizmat m: package A { sub a is export { 42; }; }; EXPORT::DEFAULT::.keys.gist.say
camelia (&a)
lizmat not sure why it is in both
Xliff Well... not a real compunit, yeah? 08:38
lizmat whatever you put in m: is a compunit
anything inside an EVAL is a compunit
Xliff m: sub ok { "ok!" }; package A { sub a is export { 42; }; }; sub EXPORT { Map.new( '&ok' => &ok, |EXPORT::DEFAULT::.pairs ) }; 08:39
camelia ( no output )
Xliff m: sub ok { "ok!" }; package A { sub a is export { 42; }; }; sub EXPORT { Map.new( '&ok' => &ok, |EXPORT::DEFAULT::.pairs ) }; EXPORT::dEFAULT::.keys.gist.say
camelia Could not find symbol '&dEFAULT' in 'EXPORT'
in block <unit> at <tmp> line 1
Xliff m: sub ok { "ok!" }; package A { sub a is export { 42; }; }; sub EXPORT { Map.new( '&ok' => &ok, |EXPORT::DEFAULT::.pairs ) }; EXPORT::DEFAULT::.keys.gist.say
camelia (&a)
Xliff Hmmm... 08:40
m: sub ok { "ok!" }; package A { sub a is export { 42; }; }; sub EXPORT { Map.new( '&ok' => &ok, |A::EXPORT::DEFAULT::.pairs ) }; EXPORT::DEFAULT::.keys.gist.say
camelia (&a)
lizmat m: sub ok { "ok!" }; package A { sub a is export { 42; }; }; sub EXPORT { Map.new( '&ok' => &ok, |A::EXPORT::DEFAULT::.pairs ) }; dd EXPORT()
camelia ===SORRY!=== Error while compiling <tmp>
Target type too complex to form a coercion type
at <tmp>:1
------> XPORT::DEFAULT::.pairs ) }; dd EXPORT()⏏<EOL>
08:41
Xliff m: sub ok { "ok!" }; package A { sub a is export { 42; }; }; sub EXPORT { Map.new( '&ok' => &ok, |A::EXPORT::DEFAULT::.pairs ) }; EXPORT().gist.say
camelia ===SORRY!=== Error while compiling <tmp>
Target type too complex to form a coercion type
at <tmp>:1
------> ::EXPORT::DEFAULT::.pairs ) }; EXPORT()⏏.gist.say
lizmat m: sub ok { "ok!" }; package A { sub a is export { 42; }; }; sub EXPORT { Map.new( '&ok' => &ok, |A::EXPORT::DEFAULT::.pairs ) }; dd EXPORT
camelia EXPORT
Xliff m: sub ok { "ok!" }; package A { sub a is export { 42; }; }; sub EXPORT { Map.new( '&ok' => &ok, |A::EXPORT::DEFAULT::.pairs ) }; EXPORT.gist.say
camelia (EXPORT)
lizmat hmmm
m: sub ok { "ok!" }; package A { sub a is export { 42; }; }; sub EXPORT { Map.new( '&ok' => &ok, |A::EXPORT::DEFAULT::.pairs ) }; dd &EXPORT()
camelia Map.new(("\&a" => sub a { #`(Sub|6111105622400) ... },"\&ok" => sub ok { #`(Sub|6111105622784) ... }))
Xliff m: sub ok { "ok!" }; package A { sub a is export { 42; }; }; sub EXPORT { Map.new( '&ok' => &ok, |A::EXPORT::DEFAULT::.pairs ) }; &EXPORT().gist.say
camelia Map.new((&a => &a, &ok => &ok))
Xliff Aha!
m: sub ok { "ok!" }; package A { sub a is export { 42; }; }; sub EXPORT { Map.new: '&ok' => &ok, |A::EXPORT::DEFAULT::.pairs ) }; &EXPORT().gist.say 08:42
camelia ===SORRY!=== Error while compiling <tmp>
Missing block
at <tmp>:1
------> ok' => &ok, |A::EXPORT::DEFAULT::.pairs ⏏) }; &EXPORT().gist.say
expecting any of:
statement end
statement modifier
sta…
Xliff m: sub ok { "ok!" }; package A { sub a is export { 42; }; }; sub EXPORT { Map.new: '&ok' => &ok, |A::EXPORT::DEFAULT::.pairs }; &EXPORT().gist.say
camelia Map.new((&a => &a, &ok => &ok))
Xliff Hmm.... that extra set of parents is looking at me suspiciously! 08:43
lizmat no, it's needed to disambiguate from named arguments to a list of pairs 08:49
otherwise the Map.new will silently eat any named args and create an empty Map (in most cases) 08:50
Xliff Ah, OK. Well, it's a starting place. Thanks, lizmat! 09:00
09:20 jpn joined 09:21 cm left 09:23 cm left, RakuIRCLogger joined
lizmat clickbaits rakudoweekly.blog/2023/09/25/2023-...eleaseses/ 10:19
Xliff \o/ -- My name in text! 10:46
sjn lizmat++ # keeping up the weeklies 11:09
sjn enjoys reading them at least :-D
lizmat sjn: always good to hear :-) 11:11
sjn btw, who cares about github.com/Raku/vim-raku ? 11:53
I've had a pull request there for looong while now
zostay: ^ 11:54
lizmat sjn: maybe you want a commit bit ?
sjn The PR is mostly for my QoL, and a nuisance which is trivial to fix 11:55
Not sure if I'm competent at vimrc to do anything useful
Geth vim-raku: 84a65c415f | (Salve J. Nilsen)++ (committed using GitHub Web editor) | .gitignore
doc/tags is generated, so let's ignore it (#30)

When loading this vim package, a tags file may be generated in the doc directory. Let's not track it in git! This is so we the checked-out repository (or submodule) stays "clean"
sjn oh, thanks :-D 11:56
lizmat yw
Xliff Oh! Nice name, sjn! 12:07
sjn Xliff: huh? which name? 12:11
12:11 jgaz joined
Xliff Yours. :) 12:11
sjn ah. it's an old Norwegian name. pretty rare (70-ish in .no who has it as a first name) 12:12
not really related to italian or latin words :-)
El_Che it sounds latin
sjn there's the latin word "Salve" which basically means "Greetings" or "Hello" 12:13
kinda-formal meaning, I think
El_Che as long as you don't accompany it with the arm greeting
:)
sjn but that's not a name :)
Xliff :)
sjn El_Che: when introducing myself, I actually say my name, so <confusion ensues among latin-speakers and italians> :-D 12:15
El_Che hehe
salve, morituri te salutant!
sjn El_Che: dramatically different translation with and without "salve" on google :-D 12:17
"Hello, they are dying to greet you"
nemokosch Servus salvus 12:23
sjoshuan @nemokosch o/ 😁 12:25
nemokosch 👀
sjn sjn = sjn 🇳🇴 on discord 12:26
nemokosch Flagged user? ^^ 12:29
12:33 derpydoo joined
El_Che sjn: google would fail a Latin exam :) 12:35
12:50 grondilu left
El_Che sjn: I help may daughter with the translations for her exams and I was surprised how bad google translate was for latin. You would think that they have enough conclusive data of a dead language to feed their AI monster :) 12:51
nemokosch Latin exams? What is the context?
El_Che high school 12:52
or middle school in the usa
nemokosch We were quite the weirdos to learn Latin at high school around here, in return, we almost always had good national results. I think even I made it to the top 10 once but one of my classmates made it to Italy, he was first or maybe second 12:53
El_Che it's a pretty popular study choice around here, resulting in one of the highest succes rates for university later all over the board, including the sciences
Latin is pretty mainstream here 12:54
nemokosch It was great because you never really had to learn vocabulary xD
El_Che hehe 12:55
nemokosch Lots of math and science folks performed well on these translation competitions, it was a good coupling, you mostly just needed essential grammar and logic
El_Che yeah, that's why latin high school pupils score well on science as well 12:56
but there is also the matter of cause and correlation 12:57
here, only good students choose Latin as their core study. In the beginning there are many, at the end a lot less. So there is a selection there 12:58
people that study ancient greek or mathematics do also well on university
(in general of course)
*in
nemokosch Yes, I wonder what this correlation means under the hood, what does it tell us 13:01
El_Che That challenging good students pays off, but we don't have to be 13:03
fetishist about the subject themselves (hallo elitists thinking ancient languages is the only way to go or that STEM is the only thing that matters) 13:04
and that we can't build an education system around elitism, so we need to make it wide enough so people can learn and have fun 13:05
2c :)
In my neck of the wood there is a history of elitism in education (of course not on the US levels, that's another level of crazy) 13:06
sadly the very active STEM proponents aren't any better and just do a quick s/.+/STEM/g 13:07
:)
nemokosch Education itself is kind of intertwined with elitism, which is not to say "back to monke" but it's not surprising it will peek in here and there 13:08
It's also kind of acquired knowledge, so to speak
It's also kind of acquired knowledge, so to speak 13:09
El_Che I think the Scandinavian countries are better structured on that subject, at least finland
13:21 rf left
jdv any idea why its seemingly impossible to search for "stat"? 13:45
13:53 tjr left
jdv also, why is .modified's value wrong? 14:02
14:04 TieUpYourCamel left
jdv gist.github.com/jdv/9e7190e2f84ae4...0f533fe3f3 14:05
dakkar jdv: wow, it looks like something messed up the timezone conversion 14:17
is that WSL? 14:18
(also, I don't think we have any `stat` function/method) 14:19
ooh, it happens on linux as well! 14:20
jdv: looks like you found a bug!
jdv i am on linux
looks like older version were worse
i only have current and 2023.04 atm
dakkar I'm on 2023.02, maybe I should check on latest…
jdv at least its closer
dakkar "closer"?
it's adding the timezone offset to the values returned by `stat`, which are guaranteed to be gmtime 14:21
jdv the fractional portion is "closer" on 2023.09 vs 2023.04
dakkar uh, I hadn't even noticed that it's wrong on my 2023.02 14:22
jdv i was just looking for full resolution mtime and noticed
i know there was some stat work that made it into the last release 14:23
Xliff I need application server project names. Can anyone help? 14:24
dakkar looks like rakudo calls nqp, nqp calls moarvm, moarvm calls libuv… and I can't see any data manipulation anywhere 14:28
so maybe the bug is inside libuv? weird, but possible
hmmm 14:29
14:31 jpn_ joined
dakkar ok, the Instant returned by `IO::Path.modified` contains the right value 14:32
jdv: can you double check? `raku -e '"foo.txt".IO.modified.to-posix.say'` should print the same integer part as `stat --format='%Y' foo.txt` 14:33
14:33 jpn left
jdv proabably libuv:( node looks the same. 14:34
dakkar dammit, now I can't reproduce the problem anymore (still 2023.02) 14:35
jdv the integer portion is the same for me - just fractional
dakkar hmmm 14:36
curiosity: what timezone is UTC-4? 14:37
America/New_York?
jdv yeah 14:38
dakkar uh… I fear the problem is that we both can't read 14:40
`TZ=America/New_York date -d @1695318519` prints `Thu Sep 21 01:48:39 PM EDT 2023`
13:48
which is… correct?
jdv huh?
yeah, the non-frac portion seems fine
dakkar (I know I got confused by my machine printing 12h instead of 24th, I should fix that)
no, I mean, the integer part looks fine too 14:41
jdv yeah
dakkar ok, so I was looking at a completely different "error" than you were, and got triply-confused
sorry, let's start again
(I really can't read, today ☹)
then I suspect it's "just" a matter of floating point representation 14:43
if you `.to-nanos.say`, it should show up the right digits
(instead of `.raku.say` or `.to-posix.say`)
jdv gist.github.com/jdv/62f6107b5ff8f3...14063c5719 14:45
dakkar yes, now try `.to-nanos`
jdv still wrong 14:47
dakkar oh?
oh yes, I see it here too
ah, ok, found it 14:48
it's still a floating point representation issue
jdv stat 131224342, nanos 131224320 14:49
sweet
dakkar that whole logic is a bit complicated ☹
jdv how does that require logic? 14:50
dakkar github.com/MoarVM/MoarVM/blob/main...eops.c#L40 this is the bottom call 14:51
jdv sub-second it should just be verbatim from the system, no?
dakkar github.com/MoarVM/MoarVM/blob/main...eops.c#L96 next one up, notice how it completely drops the `.tv_nsec` of the `st_mtim` structure 14:52
correction… I was looking at the wrong "stat" bit 14:56
github.com/MoarVM/MoarVM/blob/main...ll.c#L1377 14:57
that's the important bit
see? floating point
that should very probably be a rat, not a num, but I'm not sure if rats exist at this level
jdv is it not just github.com/MoarVM/MoarVM/blob/main...ops.c#L140 ? 15:00
rando guess
dakkar possibly! there's a few different places and I already got confused once
but again, float/num is not the best representation for somethin that arrives as a pair of longs 15:01
jdv meh:()
oop
:(
i guess i'll file a bug somewhere
dakkar it will need changes in rakudo, nqp, and moarvm, I'm really not sure where would be the best place to report the bug… 15:05
maybe report it against rakudo, linking to the moarvm bits of code?
15:11 jpn joined 15:13 jpn_ left 16:03 jpn left 16:32 tjr joined 16:35 dakkar left
jdv there's a bunch of number stuff going wrong 16:54
i don't even know what to report now
16:56 grondilu joined
grondilu m: class A does Real { method Bridge { pi } }; multi infix:<+>(A, $) { 0 }; say A.new + 1 16:58
camelia 4.141592653589793
grondilu why doesn't my multi take precedence?
m: class A does Real { method Bridge { pi } }; multi infix:<+>(A, Int $) { 0 }; say A.new + 1
camelia 0
jdv for instance 17:01
m: say 1695747489000167947/10e8
camelia 1695747489.0001678
jdv m: say 1695747489000167947/10e8.Int
camelia 1695747489.000167947
jdv wut
well, wat 17:02
grondilu m: class A does Real { method Bridge { pi } }; multi infix:<+>(A, Real $) { 0 }; say A.new + 1 17:03
camelia 0
grondilu nevermind 17:09
17:15 MoC joined
nemokosch multi resolution should be better documented 17:17
I just haven't come across anybody who knew it and was willing to explain
grondilu In the doc they say "The selection process is primarily based on types and number of arguments (arity), where the narrowest, most specific candidate wins, " 17:18
nemokosch it's not precise enough though, in this case, is it?
m: 1695747489000167947/10e8.Int andthen .WHAT.say
Raku eval (Rat)
grondilu I suppose having the second argument not typed at all made it very unspecific.
nemokosch still, the first one was as specific as gets so there should be some precision... 17:19
m: 1695747489000167947/10e8 andthen .WHAT.say
Raku eval (Num)
grondilu my initial issue was when I had typed it as Rat(Cool). I'll see if I can reproduce it here.
m: class A does Real { method Bridge { pi } }; multi infix:<+>(A, Rat(Cool) $) { 0 }; say A.new + 1
camelia 4.141592653589793
nemokosch jdv: I'm not sure if this is enough of an explanation but I'd think it was just another floating-point weirdness
grondilu so here the bridge is used, which is not what I wanted. 17:20
s/wanted/expected/
nemokosch m: say 10e8.Int == 100000000
Raku eval False
nemokosch dang
that's immediately quite some precision lost
jdv yeah. its too much for me to delve into atm.
nemokosch say 10e8.Int
oops
m: say 10e8.Int 17:21
Raku eval 1000000000
nemokosch but then how can they be not equal, lol
m: say 10e8.Int == 1000000000
Raku eval True
nemokosch maybe I miscounted
oh right, 10e8 is 10**9 actually 17:22
but anyway, the type is not the same, that much is for sure.
grondilu: if this is causing problems for you, I honestly encourage you to make an issue for it. I do think that it's a very significant problem that the multi dispatch resolution order is basically un(der)defined behavior and I'm sure there are other people who think the same 17:24
it's like, we are stronger together, bluntly put 17:26
if there are problems, it's the worst to let passivity and comfort to take over
tonyo you wouldn't be alone in that ^. currently following 386 or i'd take a look at it 17:28
nemokosch github.com/rakudo/rakudo/pull/5377 here's this PR from recently. A relatively easy fix for a corner case 17:31
Originally, I just wanted to create a separate multi candidate for the happy path... I think? I should have noted what happened exactly. 17:32
But in vague terms, I created candidate C which made something that originally dispatched to candidate A, dispatch to candidate B. I haven't touch either of those candidates 17:33
touched*
actually, I did document what happened reasonably well in the issue (#5340) itself 17:38
grondilu posting an issue is not always the best imho. In this case, I think I failed to realize that Rat(Cool) is less specific than Real. Because of the (Cool), I suppose. 17:50
anyway I think I finally manage to write that class for Quadratic Irrationals I wanted: gist.github.com/grondilu/b70fb0d8a...3f3a7317c6 18:23
It does Real, but man I had to define so many of the operators.
Using Bridge was so not possible that I ended up stubbing it so that the code halts whenever it tries to use it. 18:25
nemokosch maybe it is less specific, maybe it isn't. I mean, it's useful that you are able to convince yourself but really, I think it's telling that there is no proper material about multiple dispatch 18:29
grondilu If you look at lines 78 to 98, really all these lines should be inherited from Real IMHO. I shouldn't have to write them down myself.
nemokosch and smartmatch to a coercive type is broken for a long time, perhaps since the COERCE protocol landed
so there definitely are issues, it's not all just our poor understanding 18:30
grondilu maybe
nemokosch 'almafa' ~~ Real() was False until late 2020 iirc
grondilu still I'm not keen on posting issues unless it's really bothering me. 18:31
nemokosch it's True since, go figure, I think False was right