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