🦋 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:01 jpn joined 00:07 deoac left, jpn left 00:13 jpn joined 00:27 donpdonp- joined 00:28 donpdonp|z_ left 00:38 donpdonp|z_ joined, donpdonp- left, jpn left 00:39 jpn joined 00:42 donpdonp joined, donpdonp|z_ left 00:57 jpn left 00:59 jpn joined 01:06 jpn left 01:13 jpn joined 01:30 sena_kun left 01:47 derpydoo left 02:13 jpn left 02:33 hythm joined 02:37 jpn joined 02:42 ProperNoun joined 02:43 jpn left 02:52 jpn joined 02:58 jpn left 03:22 jpn joined 03:27 jpn left 03:59 jpn joined 04:06 jpn left 04:09 jpn joined 04:17 jpn left 04:29 jpn joined
nemokosch AlexDaniel returns for one occasion and immediately spots a Rakudo regression 04:36
04:36 jpn left
Not gonna lie, I'm slightly relieved that it's not a Pastebin-Gist regression for my personal involvement but it's not looking good 04:43
05:16 Maylay joined 05:23 hythm left 05:45 sena_kun joined 06:17 Woodi left 07:33 jpn joined, derpydoo joined 07:53 lichtkind joined 07:54 dakkar joined 08:41 derpydoo left
Geth ecosystem/main: 85add8be8f | (Elizabeth Mattijsen)++ | META.list
Remove Text::CSV, moving to zef ecosystem
09:10
nemokosch > The FileSystem repo is meant to be used during module development and actually works just like Perl when looking for a module. It doesn't support versions or auths and simply maps the short-name to a filesystem path. 09:12
in this case, I really don't get why it can't work as efficiently as in Perl
most notably, why does it build a repository eagerly? 09:13
also, there should be at least a way to allow for precomp, if the performance depends on that 09:14
even if it's the user's responsibility to keep it in sync
at least some opt-in feature, like "I understand the risks, I want the performance gain even at a cost" 09:16
Geth ecosystem/main: ee61ce592c | (Elizabeth Mattijsen)++ | META.list
Remove Logger, it now lives in zef
09:28
09:31 Sgeo left 09:33 sena_kun left 10:16 abraxxa joined 11:23 clarkema_ joined, atweedie_ joined, bingos_ joined, patrickb_ joined 11:24 hexology- joined, rjbs_ joined 11:30 rjbs left, BinGOs left, hexology left, lucerne left, patrickb left, clarkema left, atweedie left 11:31 rjbs_ is now known as rjbs, patrickb_ is now known as patrickb, clarkema_ is now known as clarkema, atweedie_ is now known as atweedie, clarkema left, atweedie left, patrickb left, atweedie joined, atweedie left, atweedie joined, patrickb joined 11:33 clarkema joined 11:35 lucerne joined, lucerne left, lucerne joined 11:44 jpn left 11:45 jpn joined
ugexe it does work with versions 11:52
if you point it at a directory containing a META6.json file (./) instead of e.g. ./lib
and it does so because it has to know when files in the repository are changed to re-precompile
you can't check the file times because windows timestamp granularity isn't good enough 11:53
and CURFS does precompile 11:55
nemokosch I don't know how that applies here but I can definitely recall that you have to set "no precompilation" for a great variety of "use lib" cases 11:57
ugexe i honestly have no idea what you're referring to 11:58
precompilation works with CURFS
nemokosch then I guess we are stuck here 11:59
ugexe i mean i can only refute your incorrect statements. i cant read your mind to tell you what you aren't saying 12:00
nemokosch and I can't magically gather more data on it 12:01
lizmat and yet another Rakudo Weekly News hits the Net: rakudoweekly.blog/2023/09/25/2023-...eleaseses/
ugexe i wouldn't expect you to use magic
nemokosch that's nice
ugexe well when you learn to ask what you want instead of throwing a fit, I (and others) will be here to try and answer it 12:02
nemokosch sure. I thought remembering that I literally got compilation errors for it was enough. 12:04
lizmat nemokosch please supply a stack trace or a gist or whatever other tangible than "remembering", please 12:05
nemokosch um, about the asking part irclogs.raku.org/raku-beginner/202...html#14:58 12:09
lizmat well, maybe ugexe will correct me on that one
ugexe i mean that can be tested in like 5 seconds 12:11
gist.github.com/ugexe/6b80d704c293...c1c0a2bfae
it is usually worth attempting to validate any advice that is given just to be sure 12:12
lizmat ugexe: I think this was about using "use lib" *inside* a module ?
aka precompiling a "use lib" 12:13
nemokosch so does that actually make a difference?
ugexe use lib only potentially re-trigger precompilation
which makes sense
putting a `use lib "..."` in a module that will be installed doesn't make sense and is arguably wrong 12:14
but it would still work fine
you'd just have some invalid repository in your repo chain any time that module is loaded
nemokosch okay, then next question 12:15
is there any way to decompose Raku code into compunits without making all of the compunits a part of the API?
by the way, just a quick heads-up that between encouraging me to ask questions, you just kept repeating "CURFS does precompile" which had little meaning to me, while the point I was going to raise was actually legitimate 12:17
lizmat ugexe: wouldn't that be an action at a distance and a potential attack vector?
precomping "use lib" ?
nemokosch to only expose an executable that is backed up by several non-API modules? sounds everyday to me 12:18
ugexe lizmat: yeah
12:18 bingos_ is now known as BinGOs
nemokosch this is just the most trivial example 12:18
12:18 BinGOs left, BinGOs joined
ugexe i dont know what decompose raku code into compunits without. making all of the compunits a part of the API means 12:20
maybe something in github.com/LLFourn/p6-CompUnit-Util 12:22
nemokosch So my understanding is that if you want precompilation for something that depends on other modules (living in other compunits) of yours, you'll end up adding the dependency to the "provides" section of the META file 12:24
that's the encouraged way at least, and the only way I have ever heard of 12:25
ugexe that isn't entirely accurate because `provides` isn't directly used to generate precomp stuff. rather, `provides` lets rakudo know which source code files are available
nemokosch but it is required for resolving the dependency in the other module, unless you do use lib 12:27
or is there a non-use-lib, non-provides way?
12:28 jpn left
ugexe well with something like -Ilib (which points at a directory that does not contain a META6.json) your META6.json isn't getting used at all. however, rakudo generates an in memory representation of what it thinks the META6.json should be (because it doesn't know one exists) 12:28
12:28 derpydoo joined
nemokosch that's only for running an executable, isn't it 12:29
12:30 jpn joined
ugexe i'm not sure i understand, but i'm inclined to say no it is for everything 12:30
it is true that whatever your raku entry point is to run some code won't be precompiled. i.e. running `raku my-prog.raku` won't precompile that code, but running like `raku -e 'require "my-prog.raku";` should (I think) because in the second scenario my-prog.raku isn't the entry point (the one liner itself is) 12:32
unning `raku my-prog.raku` won't precompile that code -> i mean running that won't precompile my-prog.raku, it will still precompile all the modules it uses
nemokosch are we still talking about the case where the modules also depend on some modules in the folder? 12:34
ugexe yes 12:35
12:36 jpn left
nemokosch okay, nice. Let me try to put this together, now 12:36
So there are some rakumod files in the lib folder, they voluntaristically require each other by path when they need to, and there is an executable that is going to use some of these modules. If I start this executable setting -Ilib (maybe could just contain use lib as well at this point?), it can retrieve the modules without triggering a new precompilation for any of them? 12:39
ugexe can you clarify what you mean by require each other by path?
do you mean `require "/path/to/module.rakumod"` or `use lib "/my/distribution/root"`? 12:40
nemokosch we were talking about require most recently but I'm all "the ends justify the means" with this 12:41
all I want to achieve is precompilation kept for those rakumod files as well that don't appear in the provides section 12:42
12:43 jpn joined
ugexe the files that you aren't listing in provides... do they exist when you start your program? 12:45
or are they created at runtime
if they are created at runtime i'm not sure how/if that can work. if they exist when you start the program (which is generally going to be the case for most people) then yes it should precompile and do what you want with -Ilib 12:47
raku -e 'my $cur = CompUnit::Repository::FileSystem.new(prefix => $*CWD.add("lib")); say $cur.distribution.meta<provides>.keys'
if you run that snippet i suspect you'll see the files you don't list in the actual `provides` in the provides 12:48
nemokosch the files do exist. The whole reason I want to not add them to the provides section is that the provides section is sort of a public interface towards all users; it's not sure if "users" even makes sense in the context, and not all modules are meant to be public API anyway 12:50
a provides-only-for-the-dist-itself would solve this problem, for example 12:51
ugexe that does complicate things, but it is still possible via the `require $some-absolute-file-path.rakumod`. if this is going to be code you distribute then you'd want to create something that can absolutify the paths at runtime so to speak 12:53
nemokosch it's good to know that this is possible - but I think it's also good to know that this is a complicated thing that one has a good reason not to try 12:56
this is nothing extraordinary for Node, though - I'm saying Node because that's what I'm most familiar with but I suspect that a lot of similar languages have a similar approach 12:58
ugexe node can do what you are saying without exposing additional public api similar to what you mentioned earlier? 13:02
nemokosch yes
I think the underlying idea is so common that people tend to even take it for granted: you want to have finegrained control over what you expose to users, while you want to keep modularity for your underlying "private" code
13:05 edr joined 13:07 jpn left
ugexe i'm not entirely sure how that could work in raku with -Ilib specifically 13:10
there wouldn't be a way for raku to know which files are private
with -I. sure, it could be listed in some theoretical meta6.json key, but -Ilib needs to guess what that should be 13:11
13:16 jpn joined
nemokosch that's still better than nothing 13:19
I will check around with different languages as well, there is some PHP coming up anyway and I'm curious about Python as well... 13:21
13:21 jpn left
ugexe having it listed in provides is kinda better than nothing as well 13:23
nemokosch I think this is an overlooked aspect of filesystem-based resolution: it simply doesn't get more decentralized than this. You can just start a local project and decompose it later, as it grows, you don't even need a META file... and when an ecosystem is based around that, you will "cherrypick" what you want to expose to the user either way, which is what you'd normally want
ugexe like one could be a bit more explicit by doing `module Foo is implementation-detail { }'` 13:24
technically its still exposed, but at least its explicit in that it isn't supported publically
to generalize your problem further I would say yes META6.json needs a type of manifest listing for stuff like test files, but these type of private files could also probably leverage such a mechanism 13:26
nemokosch regarding the provides section: since they are involved in the dependency-resolution on the ecosystem level, is implementation-detail really feels like monkeypatching 13:28
I still don't get why that was a good idea in the first place, making the modules the dependencies, that is 13:29
13:29 jpn joined
ugexe i imagine because it is the only way to build a dependency graph without actually running or parsing raku code 13:29
so things like determining what order to precompile in most efficiently 13:30
13:33 jpn left 13:35 jpn joined
nemokosch hm, not sure I get it. The metadata belongs to the dist so the conceptual jump has to happen somewhere, linking the module to the dist, but then we lose the possibility to link the module directly to another module... 13:35
ugexe well that was all before precompilation 13:41
i think
so maybe my theory isn't correct
hmm, or maybe precompilation existed but at the time it was up to panda/zef or whatever to do the precompilation 13:42
because panda and zef used to both have regexes for parsing use/require statements to try and figure out the correct order to precompile (which was bad and didn't work a lot of times) 13:43
lizmat fwiw, I dread the time when every Rakudo core compilation meant I needed to reinstall *all* modules
I am *soooo* glad I don't have to do that anymore 13:44
nemokosch I don't know what would be better to know: that modules-as-dependencies has a good technical reason (meaning it was actually well thought through) or that modules-as-dependencies is just a Perlish habit (meaning that it's just a sociocultural thing to roll out an alternative where dists are the dependencies) 13:53
14:30 kjp left 14:37 Manifest0 joined 14:47 abraxxa left 15:51 Vyrus left 15:52 Vyrus joined, perlbot left 15:53 simcop2387 left, simcop2387_ joined 15:54 simcop2387_ is now known as simcop2387 15:55 perlbot joined 15:56 jpn left 15:58 jpn joined 16:05 Woodi joined 16:06 Maylay left 16:15 derpydoo left 16:17 jpn left 16:25 Woodi left 16:26 Woodi joined 16:33 derpydoo joined 16:36 MoC joined, dakkar left 16:44 jpn joined
ugexe i assume it would also help with things like the theoretical supercedes, superceded_by, and emulates meta6 fields 16:48
although off the top of my head i'm not sure how 16:49
16:49 spacekookie left
ugexe but those all worked at the module level 16:50
16:50 jpn left, spacekookie joined
ugexe see: github.com/Raku/old-design-docs/bl...d#emulates 16:51
those kind of make sense at a module level instead of distribution level, since I think it would be more common to emulate modules than entire distributions (which I'm not sure what emulating a distribution would even mean) 16:53
tonyo m: my Buf[uint8] $b .= new; $b.append(1 +< 8); dd $b; 16:58
camelia Buf[uint8] $b = Buf[uint8].new(0)
16:59 jpn joined 17:03 jpn left 17:13 jpn joined 17:18 jpn left 17:36 ProperNoun left 17:43 grondilu joined
grondilu stumbled upon this: 17:44
m: my Rational(Cool) $ = -my Rational(Cool) $ = 1
camelia Impossible coercion from 'Num' into 'Rational': no acceptable coercion method found
in block <unit> at <tmp> line 1
grondilu Not sure why a Num is involved anywhere here.
Especially since it works with Rat
m: my Rat(Cool) $ = -my Rat(Cool) $ = 1 17:45
camelia ( no output )
lizmat vrurg might know
nemokosch let's do a little QAST and parsing first, after all, the structure itself is kinda weird 17:46
grondilu m: print (-my Rational(Cool) $ = 1).WHAT 17:47
Raku eval Use of uninitialized value of type Num in string context. Methods .^name, .raku, .gist, or .say can be used to stringify it to something meaningful. in block <unit> at main.raku line 1
grondilu m: dd -my Rat(Cool) $ = 1 17:48
camelia -1.0
grondilu m: dd -my Rational(Cool) $ = 1
camelia -1e0
grondilu o_O
nemokosch you win 17:49
m: dd -my Rat(Cool) $ = 1 17:50
Raku eval -1.0
nemokosch m: dd -my Rational(Cool) $ = 1
Raku eval -1e0
nemokosch okay, so same in 2022.02
m: dd -my Rational(Cool) $foobar = 1
Raku eval -1e0
nemokosch m: dd my Rational(Cool) $foobar = 1
Raku eval Rational $foobar = Rational.new(numerator => 1, denominator => 1)
nemokosch m: dd -Rational.new(numerator => 1, denominator => 1) 17:51
Raku eval -0e0
nemokosch uh oh xD
grondilu it's very wrong, isn't it?
nemokosch sourcery time
m: dd Rational.new(numerator => 1, denominator => 1).bridge 17:53
Raku eval Exit code: 1 No such method 'bridge' for invocant of type 'Rational'. Did you mean 'Bridge'? in block <unit> at main.raku line 1
nemokosch I did mean that
m: dd Rational.new(numerator => 1, denominator => 1).Bridge
Raku eval 0e0
nemokosch so...
why? xD
lizmat Rational.new takes 2 positionals
grondilu I suppose there is no prefix:<-> candidate for Rational?
lizmat m: say Rational.new(1,1)
camelia 1 17:54
lizmat m: say Rational.new(1,2)
camelia 0.5
nemokosch lizmat: then dd is a bit funny - but the conversion is still wrong
it should not become a floating point number
grondilu: that's right, it's all just Real
which Bridges straight into Num 17:55
lizmat yeah, the .raku of Rational is wrong
grondilu and that seems wrong. Rat doesn't do that.
17:55 AlexDaniel left 17:56 sena_kun joined
nemokosch yeah Rat constructs its own negation 17:56
it is a class, after all, unlike Real or Rational 17:57
17:57 derpydoo left
grondilu maybe it should inherit it from Rational instead, after we put it in Rational 17:57
FYI I was using Rational as the type of an attribute as I wanted to make it possible to be a FatRat too, not just a Rat. 17:58
someone tells me if there was a better way. 17:59
lizmat grondilu: no, your thinking is correct
grondilu nemokosch github.com/rakudo/rakudo/commit/54c5682f9d 18:03
grondilu lizmat++ that's some quick fixing, thanks 18:04
oh wait that's just the raku method?
lizmat well, yeah, the problems stemmed from using the wrong interface to .new , did it not ? 18:05
grondilu I don't think so
lizmat ah, then I misunderstood
grondilu my original issue was with prefix:<-> 18:06
m: my Rational(Cool) $ = -my Rational(Cool) $ = 1
camelia Impossible coercion from 'Num' into 'Rational': no acceptable coercion method found
in block <unit> at <tmp> line 1
grondilu m: my Rational(Cool) $ = +my Rational(Cool) $ = 1
camelia ( no output )
lizmat I think the problem is really is coercion to a role 18:07
should that be possible at all I wonder
vrurg ^^
18:08 jpn joined
lizmat you'd be coercing to a pun of the role 18:08
gfldex Not all roles can autopun.
lizmat m: dd Rational.^pun
camelia Rational
lizmat looks like Rational thinks it can 18:09
18:12 mfiano left
vrurg lizmat: I'm not sure it makes much sense coercing into a role. If source object implements Rational method then it knows what the destination class is preferable. 18:28
lizmat yeah, that'd be my point as well 18:29
and maybe we shouldn't allow coercing into a role ?
vrurg Otherwise if a role can't be punned (often times it's when there is a yada-yada method) the resulting error would create more confusion and complicate debugging. 18:30
Disabling it would effectively disable it even if the source object implements a role-named method.
Perhaps a more informative error message is needed for when no method is found and the coercion falls back to .CORECE/.new on the target. At this point we can intercept roles and abort proceedings. 18:32
vrurg is afk for ~1hr
18:57 jpn left 19:01 Sgeo joined 19:06 jpn joined 19:11 jpn left 19:20 jpn joined 19:22 kjp joined 19:28 AlexDaniel joined, jpn left 19:36 jpn joined 19:43 jpn left 19:45 jpn joined 19:56 donpdonp left 20:00 MoC left 20:05 jpn left 20:06 jpn joined 20:14 sena_kun left
grondilu In the docs they say Real is the "Common role for non-Complex numbers.", but they're not really reals, are they? 20:50
Like, this afternoon I was trying to define a type for so-called quadratic irrationals, and I struggled to make it work as a "Real". 20:51
nemokosch why? 20:52
grondilu I'm struggling with the comparison operators, but now that I think about it again, I may be at fault. 20:53
I was hoping I could define infix:[<=>] and that then the other ones, like infix:[<], infix:[>] and so on would be deduced. It does not seem so. 20:55
m: class Foo does Real {}; multi infix:<<<=>>>(Foo, $) { Same } 20:56
camelia ===SORRY!=== Error while compiling <tmp>
Missing block
at <tmp>:1
------> ass Foo does Real {}; multi infix:<<<=>>⏏>(Foo, $) { Same }
expecting any of:
new name to be defined
grondilu m: class Foo does Real {}; multi infix:[<=>](Foo, $) { Same }
camelia ===SORRY!=== Error while compiling <tmp>
Cannot override infix operator '=', as it is a special form handled directly by the compiler
at <tmp>:1
------> lass Foo does Real {}; multi infix:[<=>]⏏(Foo, $) { Same }
grondilu m: class Foo does Real {}; multi infix:«<=>»(Foo, $) { Same } 20:57
camelia ( no output )
grondilu hang n
*on
m: class Foo does Real {}; multi infix:«<=>»(Foo, $) { Same }; say Foo.new <=> pi
camelia MoarVM panic: Memory allocation failed; could not allocate 131072 bytes
grondilu not too dissimilar from the issues I was facing. Often the program was hanging on a loop until it consumed all memory and broke my terminal. 20:58
I wasn't asking much in this tiny example, though. 20:59
Overall I find defining custom Real classes hard.
Even though that would be useful, as there are plenty of real types in math that can be useful. 21:00
Is there a module that provides a nice example of a custom Real class? 21:01
For what it's worth here is a snapshot of what I was trying to do: gist.github.com/grondilu/b70fb0d8a...3f3a7317c6 21:02
every time I try to mix in the Real role, I get errors. 21:03
nemokosch you definitely cannot expect the others to be "deduced" 21:07
overloading is pretty much "all or nothing" business 21:08
grondilu really? Should there be an abstract class mechanism or something? 21:09
*shoudn't
nemokosch I think that would be weak typing hell on steroids, and Raku already has kind of a bad rap 21:10
when there are default implementations to fall back to, it's at least predictable that whatever you don't overload will fall back to the default
grondilu shouldn't `$a < $b` always mean `$a <=> $b ~~ Less` ? 21:11
nemokosch what would "always" even mean?
what if somebody overloads it specifically, for whatever reason?
grondilu well, by default at least. 21:12
nemokosch by default, all of these operands have a certain behavior, you started the overloading business
actually, I was about to suggest checking whether it's possible to manage with the default
grondilu I mean that semantic could be in the Real role, it's high enough in the inheritance tree to be easily overloadable. 21:13
antononcube Clickbait -- "Jupyter Chatbook multi cell LLM chats teaser (Raku)" : youtu.be/wNpIGUAwZB8
nemokosch in general it's better to first think of a non-overloading solution whenever there is a default behavior 21:14
the core itself is guilty of not following this principle close enough - even though I didn't make it up, Larry Wall collected it in the "seeing right wrong" article 21:15
grondilu Honestly it's like infix:<**>. I don't understand why I always have to rewrite it every time I implement a Numeric-like class.
same for prefix:<->, prefix:<+> and so on. Either I'm doing something wrong, or the Numeric role is incomplete. 21:17
nemokosch I think you should overload none here 21:18
docs.raku.org/routine/Bridge
I suspected this was the intention with Bridge but actually, it's stated in the docs 21:19
so you should just derive from Real and implement the Bridge method
grondilu I'm pretty sure I had tried using the bridge before, but it's no good.
as they say in the doc, `Bridge` returns one of the *core* type. 21:20
nemokosch if you can show code, maybe we can dig something out. The principle seems fairly straightforward
that's only up to you I think what you make it return
grondilu hum... 21:21
I guess I should try with a toy model.
nemokosch oh, I see the point 21:22
if the implementation of > is "call Bridge and then do >"
then we're at zero squared
grondilu well yeah 21:23
nemokosch well, this is not terribly useful tbh
grondilu instead what I really want is an abstract class
that is one that would be in the core and that I could use as a basic algebraic type template. 21:24
so that I don't have to reinvent the wheel all the time.
I thought Real or Numeric functioned like that. I guess I was wrong. 21:25
21:26 rf joined
nemokosch core or not, there could be a trait for defining mundane stuff like the one you said, "define a walrus operator and deduce all numeric comparisons from that" 21:28
grondilu pretty much 21:30
nemokosch I guess even a role would do
grondilu oh you mean a user-space role? 21:31
grondilu hadn't thought about that
nemokosch well, that's easier to set off than something new in the core 21:32
grondilu you're right
nemokosch well, let me try, I have basically never created a role but hey, no pain no gain 21:33
grondilu naming is going to bug me though, as it's competing with what the core Real and Numeric should do. 21:34
nemokosch for now I was only thinking of a role that supplies comparisons from a walrus operator 21:35
grondilu you could call it "Ordered" 21:36
21:36 deoac joined
grondilu or "Order" 21:36
lizmat m: dd Order
camelia Order
grondilu oh yeah 21:37
nemokosch it's a total order even, isn't it?
grondilu I don't think so. 21:38
I seem to recall that < is total order. ≤ is partial order.
Nope, it's the opposite. My bad.
nemokosch seems like total ordering is partial ordering, plus either a <=b or b <= a is true 21:39
grondilu yeah, I confused terms. 21:40
nemokosch hm, the only thing that can get in the way with a role is that these operators are global functions... 21:42
grondilu m: role Comparison { method compare($ --> Order) {...} }; multi method infix:«<=>»(Comparison $a, Comparison $b) { $a <=> $b } }
camelia ===SORRY!===
Unexpected closing bracket
at <tmp>:1
------> arison $a, Comparison $b) { $a <=> $b } ⏏}
Other potential difficulties:
Useless declaration of a has-scoped multi-method in mainline (did you mean 'my method infi…
grondilu m: role Comparison { method compare($ --> Order) {...} }; multi method infix:«<=>»(Comparison $a, Comparison $b) is export { $a <=> $b } }
camelia ===SORRY!===
Unexpected closing bracket
at <tmp>:1
------> Comparison $b) is export { $a <=> $b } ⏏}
Other potential difficulties:
Useless declaration of a has-scoped multi-method in mainline (did you mean 'my method infi…
grondilu m: role Comparison { method compare($ --> Order) {...} }; my multi method infix:«<=>»(Comparison $a, Comparison $b) { $a <=> $b } } 21:43
camelia ===SORRY!=== Error while compiling <tmp>
Unexpected closing bracket
at <tmp>:1
------> arison $a, Comparison $b) { $a <=> $b } ⏏}
grondilu m: role Comparison { method compare($ --> Order) {...} }; my multi method infix:«<=>»(Comparison $a, Comparison $b) { $a <=> $b }
camelia ( no output )
grondilu nah that's wrong
m: role Comparison { method compare($ --> Order) {...} }; my multi method infix:«<=>»(Comparison $a, Comparison $b) { $a.compare: $b } 21:44
camelia ( no output )
grondilu maybe "Comparable" instead 21:45
nemokosch oh so you are planning to define the operators for the role? 21:46
grondilu m: role Comparable { method compare($ --> Order) {...} }; my multi method infix:«<=>»(Comparable $a, Comparable $b) { $a.compare: $b }; my multi method infix:«<»(Comparable $a, Comparable $b) { $a.compare($b) ~~ Less }
camelia ( no output )
grondilu nemokosch: yeah, that is the point.
m: role Comparable { method compare($ --> Order) {...} }; my multi method infix:«<=>»(Comparable $a, Comparable $b) { $a.compare: $b }; my multi method infix:«<»(Comparable $a, Comparable $b) { $a.compare($b) ~~ Less }; class Foo does Comparable { method compare($x) { Order.pick } }; 21:48
camelia ( no output )
grondilu m: role Comparable { method compare($ --> Order) {...} }; my multi method infix:«<=>»(Comparable $a, Comparable $b) { $a.compare: $b }; my multi method infix:«<»(Comparable $a, Comparable $b) { $a.compare($b) ~~ Less }; class Foo does Comparable { method compare($x) { Order.pick } }; say Foo.new <=> Foo.new 21:49
camelia Too few positionals passed; expected 3 arguments but got 2
in method infix:«<=>» at <tmp> line 1
in block <unit> at <tmp> line 1
grondilu oh I defined a method instead of a sub, silly me 21:50
nemokosch gotcha
grondilu m: role Comparable { method compare($ --> Order) {...} }; multi infix:«<=>»(Comparable $a, Comparable $b) { $a.compare: $b }; multi infix:«<»(Comparable $a, Comparable $b) { $a.compare($b) ~~ Less }; class Foo does Comparable { method compare($x) { Order.pick } }; say Foo.new <=> Foo.new
camelia More
grondilu m: role Comparable { method compare($ --> Order) {...} }; multi infix:«<=>»(Comparable $a, Comparable $b) { $a.compare: $b }; multi infix:«<»(Comparable $a, Comparable $b) { $a.compare($b) ~~ Less }; class Foo does Comparable { method compare($x) { Order.pick } }; say Foo.new < Foo.new 21:51
camelia False
grondilu something like that
To me, the Numeric role should have 'add', 'subtract', 'multiply', 'divide' and maybe 'compare' virtual methods. Then to the risk of oversimplifying it, I would say that someone wanting to create his own numeric type would only have to define these methods and be done with it. 21:56
21:56 AlexDaniel left
nemokosch originally, the div and mod methods were meant to be such generic operators 22:03
by the way, I was hoping to dynamically generate the operators so that the signature contains the exact type... that's beyond my level 22:05
grondilu m: role R { method what { ::?CLASS } }; say class Foo does R {}.new.what 22:08
camelia (Foo)
grondilu you can use ::?CLASS
m: role R { method what returns ::?CLASS {...} }; say class Foo does R { method what { Foo } }.new.what 22:09
camelia (Foo)
grondilu m: role R { method what returns ::?CLASS {...} }; use Test; dies-ok { say class Foo does R { method what { Mu } }.new.what } 22:10
camelia (Mu)
not ok 1 -
# Failed test at <tmp> line 1
grondilu hum
m: role R { method what returns ::?CLASS {...} }; say class Foo does R { method what { Mu } }.new.what 22:11
camelia (Mu)
grondilu not sure if that is correct 22:12
22:24 deoac left 22:45 deoac joined
ugexe Why? 22:52
doesnt Mu match damn near anything?
(Is on the phone so cant probe into it) 22:53
tonyo looks like the .what in Foo just overrides the role method, which is what i'd expect 22:59
grondilu well ok I suppose overloading a method is not just about the body, but also the return type. Fair enough, I guess. 23:05
I'll check if it's the same with class inhertance, though. 23:06
m: class A { method foo returns Str {...} }; class B is A { method foo returns Blob {...} };
camelia ( no output )
grondilu m: class A { method foo returns Str {...} }; class B is A { method foo returns Blob {...} }; say B.new
camelia B.new
grondilu yeah that's not too suprising. 23:07
m: class A { method foo returns Str {...} }; class B is A { method foo returns Blob { Blob.new } }; say B.new.foo # just one more check
camelia Blob:0x<>
grondilu m: role A { method foo returns Str {...} }; class B does A { method foo returns Blob { Blob.new } }; say B.new.foo # just one more check 23:08
camelia Blob:0x<>
ugexe I think if you make it a multi the signature will matter more 23:17
The interface method
m: role A { multi method foo returns Str {...} }; class B does A { multi method foo returns Blob { Blob.new } }; 23:18
camelia ===SORRY!=== Error while compiling <tmp>
Multi method 'foo' with signature :(B: *%_ --> Str) must be implemented by B because it is required by a role
at <tmp>:1
grondilu here is an other issue : I can't overload prefix:<-> from a compunit. 23:19
m: class A does Real { method Bridge {...}; multi prefix:<->(::?CLASS $) is export { rand } }; import A; say -A.new 23:20
camelia 0.8016484849660362
grondilu ^this works fine, but not if I put A in a file as a compunit.
ugexe What if you put no precompilation in it?
grondilu wdym
rm -rf .precomp? 23:21
ugexe I thought there was some issue regarding precompilation overriding the candidate or some such
no, the pragma
‘no precompilation;’
grondilu tries
lol nevermind I was running the wrong command. sorry 23:22
23:29 lichtkind left 23:35 rf left 23:36 rf joined, rf left, rf joined
grondilu hum, in Real there is `method abs() { self < 0 ?? -self !! self }`, yet I can't use it: 23:43
m: class A does Real { method Bridge {...} }; multi sub infix:«<»(A, 0) { Bool.pick }; multi sub prefix:<->(A) { rand }; say A.new.abs 23:44
camelia Stub code executed
in method Bridge at <tmp> line 1
in block <unit> at <tmp> line 1
grondilu why is it trying to call Bridge here?? 23:45
oh wait
the new sub candidates are not visible inside Real or something? 23:46
I suppose I was trying to apply the concept of abstract class for subs, not methods. 23:52
And only methods can be abstract, not subs, perhaps.
m: role A { sub foo { "A::foo!" }; method bar { foo } }; say class B does A { sub foo { "B::foo!" }; }.bar 23:58
camelia A::foo!
grondilu m: role A { sub foo {...}; method bar { foo } }; say class B does A { sub foo { "B::foo!" }; }.bar
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 m: role A { sub foo {...}; method bar { ::?CLASS::foo() } }; say class B does A { sub foo { "B::foo!" }; }.bar 23:59
camelia ===SORRY!=== Error while compiling <tmp>
Confused
at <tmp>:1
------> { sub foo {...}; method bar { ::?CLASS:⏏:foo() } }; say class B does A { sub foo
expecting any of:
colon pair
nemokosch because the comparison itself relies on the bridge
the self < 0 bit