🦋 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.
guest912 Can I create a custom hash type overriding x{smth} operation? 00:02
So that smth could be not a string but converted to a string under the hood?
I’m trying to add “does Associative [K,V]”, adding AT-KEY & ASSIGN-KEY methods but when I try to do x{smth} I get an error 00:03
Like “Associative indexing implementation missing from type”
guifa Yes 00:07
you can override the AT-KEY method
what's the error? 00:08
guest912 I did that, but I get this “Associative indexing implementation missing from type”
My type name after this
guifa do you also have an EXISTS-KEY method? I'm pretty sure it's just AT-KEY and EXISTS-KEY that are the minimum 00:09
guest912 Yep 00:18
guifa can you post your code?
guest912 Let me try some make some clean example
00:21 Altai-man left
guest912 guifa, here: pastebin.com/SJb6sHka 00:33
An attempt to read (“a{(12,34)}.say”) gets me the same error 00:46
Wait, value type comes first, before the key? role Associative[::TValue = Mu, ::TKey = Str(Any)] { } 00:47
It does not change my error though
00:50 gdown joined
guest912 I removed “multi” and used regular methods 00:51
It fixed the issue but now I have another issue 00:52
nemokosch there are too many type annotations for me to feel comfortable 😄
guest912 pastebin.com/yBjghHc8 00:53
I tries to destructure the key into multiple different keys. Even though I add a scalar wrapper. 00:54
Dam, it was not a scalar wrapper but a list wrapper
My bad
It seems to work, let me check
avuserow m: sub f(--> Int, Int) {return 1, 2;}; say f(); # is there a way to specify multiple returned items in the signature? 00:55
camelia ===SORRY!=== Error while compiling <tmp>
Malformed return value (return constraints only allowed at the end of the signature)
at <tmp>:1
------> sub f(--> Int⏏, Int) {return 1, 2;}; say f(); # is the
avuserow m: sub f(--> (Int, Int)) {return 1, 2;}; say f(); # is there a way to specify multiple returned items in the signature? 00:56
camelia ===SORRY!=== Error while compiling <tmp>
Malformed return value
at <tmp>:1
------> sub f(-->⏏ (Int, Int)) {return 1, 2;}; say f(); #
guest912 Okay this works: pastebin.com/t7JD0FMZ 01:00
avuserow, I would define a type that describes this shape and return it 01:01
m: subset IntPair where * ~~ (Int:D, Int:D); sub foo(--> IntPair:D) { (12,34) }; foo.say 01:02
camelia (12 34)
guest912 Is there any point to add any parameters to Associative role? 01:07
If I change them to any random types (“Associative[Bool:D, UInt:D]”) everything works as before
Is it just purely some metadata, just like code comments?
guifa I don't think I've ever used it, would need to investigate it a bit more. I think the idea would be that you would say Associative[::K, ::V] and then have, e.g. method of { V } 01:12
but don't quote me on that
guest912 docs-dev.raku.org/type/Associative in the docs it seems like the value comes before the key 01:16
role Associative[::TValue = Mu, ::TKey = Str(Any)] { }
nemokosch I don't know, check is a bit frightening 01:18
pastebin.com/yBjghHc8 - this snippet was quite certainly about the way indexing is hooked into AT-POS
namely that it has loads of clever dispatches, and they quite certainly include list-y dispatches
that's why something like %foo{1, 2, 3} could work as %foo{1}, %foo{2}, %foo{3} 01:19
guest912 It seems the whole “does Associative” is not necessary
nemokosch it probably isn't, maybe the sigil checks it
01:24 jpn joined 01:28 jpn left 01:29 stanrifkin joined 01:31 jpn joined 01:36 jpn left
guifa the role is required for the sigil, but that's about it 02:05
assigning to @ requires Positional, to % Associative, and & Callable (callable or code I forget which lol)
nemokosch Callable 02:10
02:19 jpn joined 02:24 jpn left
[Coke] came back hours later, that scraper test still running 02:31
02:32 jpn joined
guest912 guifa, so those parameters for the role is purely documentation? 02:33
Or you can somehow actually access them?
02:35 kylese left 02:36 kylese joined 02:37 jpn left
nemokosch no, it's rather the role itself that is mostly for documentation 02:43
[Coke] scrape() calls out to from-xml($data), that hangs. 03:15
03:15 kylese left, kylese joined 03:30 kylese left 03:35 kylese joined
[Coke] this hangs in a checkout of web scraper: raku -I. -MXML -e "from-xml('t/data/s05.html'.IO.slurp)" 03:41
github.com/raku-community-modules/XML/issues/68 03:45
03:54 gdown left
guifa guest912: no, not necessarily. The parameters autofill for of and keyof 04:02
m: class A {;}; class B {;}; class Foo does Associative[A,B] {;}; say Foo.of; say Foo.keyof
camelia (A)
(B)
04:06 gdown joined
guest912 guifa, can I somehow access these in the type signature of a method? 04:07
Like class A does Associative[Int:D, Str:D] { method AS-KEY(self.keyof \x --> self.of) {} }
guifa I mean, sure, ... where self.of and where self.keyof. But you could just hard code them since they're known at compile time 04:08
guest912 I just want this for the sake of having a shorthand 04:10
04:10 jpn joined
guest912 The types can be long, nested into multiple package levels 04:10
guifa class Foo does Associative { my \K = Foo.keyof; my \V = Foo.of; method ASSIGN-KEY($k where K, $v where V) { say $k,$v } }; 04:12
04:15 jpn left
guest912 guifa, what about return value? 04:44
Return type I mean
m: class Foo does Associative[Str:D, Int:D] { method ASSIGN-KEY(\k where Foo.keyof, \v where Foo.of) { say k, v } }; my \x = Foo.new; x{123} = 'hi'; 04:45
camelia 123hi
guest912 m: class Foo does Associative[Str:D, Int:D] { method ASSIGN-KEY(\k where Foo.keyof, \v where Foo.of) { say k.raku, ' ', v.raku } }; my \x = Foo.new; x{123} = 'hi'; 04:46
camelia 123 "hi"
guest912 m: class Foo does Associative[Str:D, Int:D] { method ASSIGN-KEY(\k where Foo.keyof, \v where Foo.of) { say k.raku, ' ', v.raku } }; my \x = Foo.new; x{123} = 321;
camelia Constraint type check failed in binding to parameter 'v'; expected anonymous constraint to be met but got Int (321)
in method ASSIGN-KEY at <tmp> line 1
in block <unit> at <tmp> line 1
04:46 stanrifkin_ joined 04:49 stanrifkin left
guest912 m: class Foo does Associative[Str:D, Int:D] { subset V where Foo.of; method AT-KEY(\k where Foo.keyof --> V) {'test'}; method ASSIGN-KEY(\k,\v) {say k,v} }; my \x = Foo.new; x{123} = 'foo'; x{123}.raku.say 04:51
camelia 123foo
"test"
guest912 m: class Foo does Associative[Str:D, Int:D] { subset V where Foo.of; method AT-KEY(\k where Foo.keyof --> V) {321}; method ASSIGN-KEY(\k,\v) {say k,v} }; my \x = Foo.new; x{123} = 'foo'; x{123}.raku.say
camelia 123foo
Type check failed for return value; expected Foo::V but got Int (321)
in method AT-KEY at <tmp> line 1
in block <unit> at <tmp> line 1
guest912 guifa, it seems to me using subsets like “subset K where Foo.keyof” instead of “my \K = Foo.keyof” is better since you don’t have to type “Foo.*” all the time 04:52
In case you rename the class only a couple lines with those subsets will change.
Would you agree? 04:53
An the arguments become extremely short: K \k, V \v 04:54
Here is an example: pastebin.com/0iYev8EY 04:58
05:07 jpn joined 05:12 jpn left 05:40 CIAvash joined 05:44 CIAvash left 06:02 CIAvash joined 06:04 jpn joined 06:09 jpn left
guest912 Is there an opposite of “:D” for the types? Like if a type is “:D” but you want to make it optional? 06:21
nemokosch Hm, what would that mean? 06:48
Sounds like an oxymoron to me
m: my Str:D %demo; %demo.of.&dd 06:52
Raku eval Str:D
nemokosch m: my Str:D %demo; %demo.of.WHAT.&dd 06:53
Raku eval Str:D
nemokosch Okay but what type is this xD
m: dd Str:D 06:54
Raku eval Str:D
nemokosch m: Str:D.^name.say
Raku eval Str:D
nemokosch Why...
m: my Str:D $nonsense = Str:D; dd $nonsense 06:55
Raku eval Exit code: 1 Type check failed in assignment to $nonsense; expected type Str:D cannot be itself (perhaps Nil was assigned to a :D which had no default?) in block <unit> at main.raku line 1
06:55 epony left
nemokosch Okay, this is ugly but at least comprehensible 06:56
guest912 Everything is nullable by default. 06:59
m: my Str $x = Nil; $x.say
camelia (Str)
guest912 Which is a mystery to me, why would anyone think it’s a good decision? 07:00
Like NullPointerException in Java was not enough as a proof that it is not
But in Java at least primitives are not nullable 07:02
nemokosch If you think it's a bad decision, what do you think about Str:D somehow being a value?
I've been using this language for more than two years and this is the first time I bumped into this
07:02 jpn joined
m: Str:D ~~ Str andthen say 07:03
Raku eval Exit code: 1 ===SORRY!=== Argument to "say" seems to be malformed at /home/glot/main.raku:1 ------> Str:D ~~ Str andthen say⏏<EOL> Other potential difficulties: Unsupported use of bare "say". In Raku please use: .say if you meant to call it as a method on $_, or use an explicit invocant or argument, or use &say to refer to the function as a noun. at /home/glot/main.raku:1 ------> Str:D ~~ Str
andthen say⏏<EOL>
nemokosch m: Str:D ~~ Str andthen .say
Raku eval True
guest912 I don’t think it’s a value, I just don’t want a variable to be able have Nil as value unless I asked for it explicitly
nemokosch You can see it is though 07:04
guest912 m: say Str:D ~~ Str
camelia True
guest912 nemokosch what do you mean I can see it?
nemokosch You can see that it is a value 07:05
It was a value in all these snippets
guest912 Are maybe referring to some Raku-related term “value”?
nemokosch No, common sense
You couldn't just print int or something in Java 07:06
guest912 From the common sense for me Str:D is a type that is saying explicitly that it is a non-nullable string
nemokosch Have you see the snippets though
guest912 What snippets?
nemokosch Here in the chat 07:07
guest912 I don’t think I see what you are talking about.
07:07 jpn left, gdown left
nemokosch And I'm not suited to run these circles at this hour 07:08
guest912 Anyway, all I want is to be explicit when I need an optional/nullable value or a defined one. 07:09
And I also want the type system to make sure the code is obeying the type constraints.
Voldenet in java Integer can be null though
guest912 Because Integer is not primitive? 07:10
Voldenet Right, raku's Int is java's Integer 07:11
java's int is raku's int32
m: my int32 $i; say $i;
camelia 0
guest912 m: my int32 $i = Nil; $i.say 07:12
camelia Cannot unbox a type object (Nil) to int.
in block <unit> at <tmp> line 1
guest912 m: my int32 $i; $i.say
camelia 0
guest912 m: my int32 $i; $i.defined.say
camelia True
guest912 Very similar to Java indeed
nemokosch Well, both int in Java and int32 in Raku are unnice low-level hacks 07:13
int32 is quite literally runtime-native 32-bit integer
Voldenet in C# Int32 is int, because C# has value type semantics via struct 07:14
which shows that you can solve that without those low-level hacks
nemokosch Yeah C# is a well-designed language for something as complex 07:15
Voldenet C# was designed to be able to describe C++/C headers
so it has __arglist, structs, stackalloc and all weird things 07:16
but still, I do believe that value semantics are really useful 07:17
in fact, raku has this problem, that native calling something with a struct is impossible
btw, I do wonder if using Int:D is going to be faster than Int 07:19
since Int:D is probably doing explicit typecheck and Int uses rare branch only when trying to unbox null 07:20
nemokosch look, the thing is, up until now I thought Int was two things: a value (the default value of type Int) and a type 07:21
I thought this was a specialty for type names that they fill both roles
But apparently Int:D is also a value, it is a value of Int, moreover a value of Int:D which is simply explicitly ruled out from assignment 07:22
Voldenet it's… sufficiently weird
nemokosch I thought it was only a type on an almost syntax level, therefore I thought asking "what type is it" would either be nonsense like in Java, or yield some meta type called Type or whatever 07:23
Voldenet m: my Int $u = Int:U; say $u; my Int $d = Int:D; say $d; my Int $i = Int; say $i; my Int:D $nd = Int:D;
camelia (Int:U)
Type check failed in assignment to $nd; expected type Int:D cannot be itself (perhaps Nil was assigned to a :D which had no default?)
in block <unit> at <tmp> line 1

(Int:D)
(Int)
Voldenet weird, the output is kind of reshuffled 07:24
either way, those Int… variants are simply pointers to some constants with no value 07:26
m: say Int =:= Int:U
camelia False
nemokosch why is it False anyway
why is it not the same at least 07:27
m: say Int =:= Int:T
Raku eval Exit code: 1 ===SORRY!=== Error while compiling /home/glot/main.raku Invalid type smiley ':T' used, only ':D', ':U' and ':_' are allowed at /home/glot/main.raku:1 ------> say Int =:= Int:T⏏<EOL> expecting any of: pair value
nemokosch m: say Int =:= Int:_
Raku eval True
nemokosch blah
Voldenet =:= basically checks pointer address
so it's obvious if those three are not equivalent 07:28
nemokosch it is obvious but why are they not, really 07:29
why are these fantom values backing all of them
and why do these fantom values fall into the same type
and look, here is the crazy thing 07:30
not long after saying that Int:D is an Int, it turns out Int:D doesn't even have a compatible meta-object!
m: (Int:D).^methods.say
Raku eval Exit code: 1 No such method 'methods' for invocant of type 'Perl6::Metamodel::DefiniteHOW' in block <unit> at main.raku line 1
nemokosch but somehow it's still hacked as if it indeed knew these methods 07:31
m: (Int:D).cos.say
Raku eval Exit code: 1 Use of uninitialized value of type Int:D in numeric context in block <unit> at main.raku line 1
nemokosch suddenly this call succeeded 07:32
or well, did it
at least some effort has been made to understand it as a number
Voldenet that behavior of ^methods makes sense, being able to assign Int:D to Int… 07:33
I'm betting nowhere it's described that it'd make sense
it only happens to work now
guest912 m: my Int:D $x = 123; my Int $y = $x; $y.say
camelia 123
Voldenet what I mean is\ 07:34
m: my Int $x = Int:D;
camelia ( no output )
nemokosch uh
Voldenet Int:D is not Int:D
Obviously :)
nemokosch but it is Int
XD
Voldenet no, it is not, Int =:= Int:D says False! :D
guest912 m: my Int $x = Int:D; say $x ~~ Int:D
camelia False
Voldenet m: my Int $x = Int:D; say $x ~~ Int:D; say $x 07:35
camelia False
(Int:D)
nemokosch but here's the thing
guest912 m: say Int ~~ Int 07:36
camelia True
nemokosch assignment succeeded to an Int type constraint
guest912 m: say Int:D ~~ Int:D
camelia False
nemokosch m: my Int $x = Int:D; my Int:D $y = $x;
Raku eval Exit code: 1 Type check failed in assignment to $y; expected type Int:D cannot be itself (perhaps Nil was assigned to a :D which had no default?) in block <unit> at main.raku line 1
nemokosch this is a big fat godforsaken nonsense
Int:D is Int but not Int:D
Voldenet m: my Int $x := Int:D; say $x ~~ Int:D; say $x =:= Int:D; say $x
camelia False
True
(Int:D)
07:37 jpn joined
Voldenet makes you scratch your head a bit 07:37
nemokosch a bit you say
Voldenet if you see pointers here and there, know that := copies the value 07:38
and ~~ compares the value
guest912 This seems very wrong: “my Int $x := Int:D; say $x ~~ Int:D;”
To be True
Voldenet this isn't, the =:= is
nemokosch btw I found how to make Int:D into Int 07:39
guest912 Ah, it’s actually False, it’s fine. I got confused by multiple says
07:40 lucerne left
guest912 m: my Int $x = Int:D; say $x =:= Int:D 07:40
camelia False
guest912 How was that True above? 07:41
Ah, it’s bind operator
:= vs. =
nemokosch m: (Int:D).^nominalize.say 07:42
Raku eval (Int)
nemokosch m: (Str:D).^nominalize.say
Raku eval (Str)
07:42 jpn left
Voldenet it makes sense, though I'd rather have Int:D present itself as nominalized version after being assigned (not bound) to int 07:47
08:38 jpn joined 08:43 jpn left
lizmat m: dd Int:D 09:33
camelia Int:D
lizmat m: my $x = Int:D; dd $x 09:34
camelia Mu $x = Int:D
lizmat m: say Int:D
camelia (Int:D)
lizmat m: my Int $x = Int:D; say $x<> =:= Int:D 09:35
camelia True
lizmat the problem was containerization of $x
=:= doesn't decontainerize 09:36
09:39 jpn joined 09:44 jpn left 09:49 sena_kun joined 09:50 jpn joined 10:24 lucerne joined 10:45 jpn left 11:21 jpn joined 11:24 CIAvash left 12:01 Sgeo left 12:02 jpn left
nemokosch The way this works isn't remotely alright 12:09
But at least found a way to "remove the type smiley"
tbrowder__ tonyo: i sent the pm 12:28
12:30 jpn joined
tbrowder__ is there an IRC channel for noob mac users who want to use the terminal? 12:30
12:54 jpn left 13:12 jpn joined 13:30 epony joined 13:38 epony left 14:05 jpn left 14:06 jpn joined
tbrowder__ ah, i found a good link to lots of help 15:50
17:06 stanrifkin_ left
librasteve guest912: this is a bit late in the proceedings, you may want to look at raku.land/zef:lizmat/Hash::Agnostic 17:48
17:53 jpn left 18:00 jpn joined
guest912: there are a couple of ways to adapt raku to use Monads such as github.com/masukomi/Definitely and github.com/rawleyfowler/Monad-Result/tree/main 18:05
Voldenet imo generic monads are not good fit for dynamic languages 18:15
Sure, you can code like this and it'll work, just the language itself prefers `given $x { when Int:D { }; default { }}` sort of syntax 18:18
antononcube @Voldenet I forgot to further troll @rf about his monads...
Basiscally, for me the forward feed operator provides good enough monadic pipelining. I do have complains about it, but they are relatively minor. 18:19
Voldenet feed operator is good overall 18:22
my biggest complaint is that for some reason topic variable is the last parameter 18:23
nemokosch is it really the topic variable, or just the passed value?
18:24 jpn left
Voldenet well, it's passed value in this case 18:24
it's not gamebreaking, it only feels weird and creates hard to debug problems
ugexe feed operator was prohibitively slow last i remember
Voldenet especially if you change positional signatures without changing call sites
nemokosch I think it makes sense since for .& it's the first argument
aaand that's a big reason why I like it much more 18:25
the feed operator is almost never convenient to use, it takes way too special circumstances, not really worth keeping in your vocab
antononcube @Voldenet Yes! It is different from other languages I used monads with... I learned to live with it, though.
Voldenet .& has a few problems compared to feed op 18:26
antononcube @nemokosch I think you are thinking like a JavaScript programmer.
Voldenet m: sub inc($by, $n) { $n + $by }; 1 ==> inc(2) ==> inc(3) ==> say();
camelia 6
Voldenet now, the same thing done with .& is… ugh… not elegant 18:27
antononcube I like forwared feed, ==> , because code with it looks "pretty and instructive". 🙂
nemokosch why is it not elegant?
how is it not way better, even?
antononcube @Voldenet Good example. My main complaint is that we have to say() , not just say. 18:28
Voldenet m: sub inc($n, $by) { $n + $by }; 1.&inc(2).&inc(3).say;
camelia 6 18:29
Voldenet m: sub inc($n, $by) { $n + $by }; 1 . &inc(2) . &inc(3) .say;
camelia ===SORRY!=== Error while compiling <tmp>
Unsupported use of . to concatenate strings. In Raku please use: ~.
at <tmp>:1
------> sub inc($n, $by) { $n + $by }; 1 .⏏ &inc(2) . &inc(3) .say;
Voldenet uh oh
.& pretty much never allows spaces
if you did a lot of feed forward calls, it gets unreadable fast
nemokosch I mean who cares about spaces 18:30
I agree that it would be better if Raku wasn't this whitespace sensitive in general
Voldenet …astronomers?
nemokosch but I still think it's better in all regards 18:31
Voldenet I like whitespace rules compared to perl
nemokosch if somebody REALLY wants extra spaces, they should use the "unspace"
or andthen
I think the andthen chaining is still very much superior to feeds
Voldenet but you can say .map({ }) and .say on separate lines! 18:32
nemokosch I'm with Mr Krňávek on this one
yeah but it's kind of an inconsistent feature
Voldenet andthen is verbose
nemokosch ==> plus parens is also verbose, let's be fair 18:33
Voldenet True
nemokosch except it scales much worse lol
Voldenet and the uncanny thing about `==> thing(2)` is that uncanny last argument creeping in
I'd understand `==> thing(2, _)` and likes 18:34
nemokosch well I still think that since there is already .&, there would have been no point to feed it as first argument
Voldenet though I use feed forward more than .& only because of spaces and newlines 18:35
not that it's better
librasteve on the Option/Some/None Monads, I have spent a bit of time in Rust and, while I do not like shouty compilers htat prevent me from doing practically anything, I accept that Rust has it's adherents and that there is some sense in applying Monad restrictions where you want to surface possible (null-related) bugs early 18:47
so, I like that Raku will just get on and compile my stuff and let's me have undefined things here and there and fails quietly (as you say Voldenet) - but I also get that others may prefer a more shouty / safety-first alternative 18:49
18:53 maylay left
Voldenet different languages, approaches and purposes 18:57
19:05 maylay joined 19:06 jpn joined 19:11 jpn left
librasteve sure - imo (i) raku lets you code in the style you want and (ii) raku has the tools (in this case, a module or two) to let you do that if you want (for any that) 19:15
nemokosch the problem is that even after 2 years, there are these things in Raku that I've never seen and that make no sense 19:19
like this Int:D madness
it really feels like there was no design review/finalization, somebody at some point just said "okay, it's time to release something to the public"
19:22 jpn joined
librasteve well I don't suppose that anyone tried something as dumb as my Int $i = Int:D before ... so please fix it or shut up 19:23
19:28 jpn left 19:33 jpn joined 19:38 jpn left 19:49 jpn joined
nemokosch Fix it? This is ironic from somebody who actively opposes fixing design mistakes 19:54
No, let's just pretend problems don't exist
Or even better: blame the user for conceptual anomalies. Because why would anyone write complex or abstract code in Raku, right? Not possible. 19:55
20:06 maylay left
Voldenet no need to get upset over it as long as we all agree it's silly 20:21
unless there's sound reason for all of this 20:22
20:32 jpn left 20:42 ACfromTX joined 20:49 Sgeo joined
nemokosch heh, as long as we agree 20:54
I find it so grotesque - somewhat offensive even, not gonna lie - that some people notoriously protect a programming language and its faults over actual people 20:55
inb4 no, I'm far from the only one, a lot more damage is done to actual beginners who legitimately got confused when something seriously strange is explained to them as a "you thing" 20:57
21:09 maylay joined
[Coke] heads out 21:22
21:22 [Coke] left 21:34 maylay left
guest912 librasteve thanks for the links. But the way how I use Raku and what I use it for implies that I have zero dependencies, and no depenencies management apart from the Rakudo itself. 21:42
So I either rely on builtin language features. Or something small I can add into the code itself. 21:43
Voldenet, “monads are not good fit for dynamic languages” yet we have them all over the place, like elvis operator for instance
22:12 epony joined 22:36 maylay joined 22:45 jpn joined 22:51 jpn left 23:12 sena_kun left 23:55 jpn joined