🦋 Welcome to the MAIN() IRC channel of the Raku Programming Language (raku.org). This channel is logged for the purpose of keeping a history about its development | evalbot usage: 'm: say 3;' or /msg camelia m: ... | 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 8 June 2022.
00:07 reportable6 left 00:10 reportable6 joined 00:26 Sgeo joined 01:10 Kaipei joined 01:12 Kaiepi left 02:12 linkable6 left, sourceable6 left, evalable6 left, statisfiable6 left, greppable6 left, tellable6 left, quotable6 left, squashable6 left, coverable6 left, reportable6 left, unicodable6 left, notable6 left, committable6 left, bloatable6 left, releasable6 left, nativecallable6 left, bisectable6 left, shareable6 left, benchable6 left 02:13 bisectable6 joined, sourceable6 joined, committable6 joined, bloatable6 joined, notable6 joined 02:14 coverable6 joined, statisfiable6 joined, evalable6 joined, tellable6 joined, benchable6 joined, releasable6 joined, shareable6 joined, quotable6 joined 02:15 reportable6 joined, nativecallable6 joined, linkable6 joined, greppable6 joined, unicodable6 joined, squashable6 joined 03:15 evalable6 left, linkable6 left 03:17 evalable6 joined 03:18 linkable6 joined 03:43 Xliff left 04:43 quotable6 left, evalable6 left, tellable6 left, linkable6 left, bloatable6 left, statisfiable6 left, reportable6 left, releasable6 left, benchable6 left, bisectable6 left, unicodable6 left, notable6 left, greppable6 left, squashable6 left, committable6 left, sourceable6 left, nativecallable6 left, coverable6 left, shareable6 left, committable6 joined, nativecallable6 joined, reportable6 joined, quotable6 joined 04:44 statisfiable6 joined, shareable6 joined, benchable6 joined 04:45 coverable6 joined, notable6 joined, greppable6 joined, squashable6 joined, tellable6 joined, bloatable6 joined, sourceable6 joined, bisectable6 joined, evalable6 joined 04:46 unicodable6 joined, releasable6 joined, linkable6 joined 05:46 reportable6 left, benchable6 left, greppable6 left, sourceable6 left, coverable6 left, nativecallable6 left, linkable6 left, statisfiable6 left, quotable6 left, evalable6 left, tellable6 left, committable6 left, shareable6 left, notable6 left, releasable6 left, bloatable6 left, bisectable6 left, unicodable6 left, squashable6 left, quotable6 joined 05:47 nativecallable6 joined, coverable6 joined, squashable6 joined, releasable6 joined, notable6 joined, shareable6 joined, unicodable6 joined, bisectable6 joined 05:48 reportable6 joined, statisfiable6 joined, benchable6 joined, evalable6 joined, bloatable6 joined, linkable6 joined, greppable6 joined, sourceable6 joined 05:49 committable6 joined, tellable6 joined 06:07 reportable6 left 06:08 reportable6 joined 07:08 reportable6 left, unicodable6 left, evalable6 left, benchable6 left, shareable6 left, coverable6 left, nativecallable6 left, greppable6 left, notable6 left, committable6 left, statisfiable6 left, tellable6 left, bloatable6 left, bisectable6 left, quotable6 left, releasable6 left, sourceable6 left, linkable6 left, squashable6 left, bloatable6 joined, squashable6 joined 07:09 releasable6 joined, sourceable6 joined, shareable6 joined, quotable6 joined, reportable6 joined 07:10 notable6 joined, committable6 joined, benchable6 joined, nativecallable6 joined, unicodable6 joined, coverable6 joined 07:11 tellable6 joined, greppable6 joined, linkable6 joined, evalable6 joined, bisectable6 joined, statisfiable6 joined 07:59 Sgeo left 08:59 committable6 left, quotable6 left, greppable6 left, linkable6 left, unicodable6 left, evalable6 left, statisfiable6 left, notable6 left, bisectable6 left, coverable6 left, shareable6 left, reportable6 left, benchable6 left, tellable6 left, bloatable6 left, sourceable6 left, squashable6 left, nativecallable6 left, releasable6 left, committable6 joined 09:00 reportable6 joined, bloatable6 joined, tellable6 joined, shareable6 joined, bisectable6 joined, squashable6 joined 09:01 sourceable6 joined, statisfiable6 joined, evalable6 joined, unicodable6 joined, benchable6 joined 09:02 greppable6 joined, coverable6 joined, notable6 joined, nativecallable6 joined, linkable6 joined, quotable6 joined, releasable6 joined 09:04 Altai-man joined 10:04 coverable6 left, linkable6 left, bloatable6 left, shareable6 left, unicodable6 left, quotable6 left, greppable6 left, nativecallable6 left, bisectable6 left, committable6 left, reportable6 left, benchable6 left, sourceable6 left, evalable6 left, squashable6 left, notable6 left, releasable6 left, tellable6 left, statisfiable6 left, reportable6 joined 10:05 shareable6 joined, statisfiable6 joined, benchable6 joined, bloatable6 joined, tellable6 joined 10:06 committable6 joined, notable6 joined, coverable6 joined, linkable6 joined, quotable6 joined, bisectable6 joined, nativecallable6 joined, releasable6 joined, evalable6 joined 10:07 sourceable6 joined, unicodable6 joined, greppable6 joined, squashable6 joined 10:48 frost joined 11:17 euandreh left 11:23 simcop2387 left, simcop2387 joined 11:40 perlbot left, simcop2387 left 11:42 perlbot joined 11:43 simcop2387 joined 11:47 simcop2387 left 11:48 simcop2387 joined 12:04 Guest86 joined 12:06 reportable6 left 12:08 reportable6 joined 12:10 frost left 12:55 Guest86 left
p6steve m: my $t = 'dkjgsj2022skjh'; my regex yr { \d**4 }; $t ~~ /<yr>/; my $r = ~$<yr> if $<yr>; $r.say 13:27
13:27 _________ left, p6steve joined
guifa m: my $t = 'dkjgsj2022skjh'; my regex yr { \d**4 }; $t ~~ /<yr>/; my $r = ~$<yr> if $<yr>; $r.say 13:28
camelia 2022
guifa . o O ( camelia bot can't see through discord bot)
p6steve hmmm - need to be on irssi ;-), not discord
tellable6 2022-08-04T19:03:32Z #raku <Xliff> p6-steve: Looked into that. Decodes into a Buf which I can't do anything with. It doesn't seem to work with Raku's decode.
2022-08-04T21:24:04Z #raku <Xliff> p6steve: I did get that far, however it appears that the string I am tryig to parse fails the deserializer.,
p6steve anyway, question is is there a better idiom to say 'my $r = ~$<yr> if $<yr>' ? 13:29
this seems like I have to say '<yr>' twice... and I'm very lazy 13:30
guifa my $r = $<yr>.?Str
evalable6 Use of Nil in string context
in block <unit> at /tmp/iZTL1O9mrU line 1
guifa err
p6steve yeah - that's the err
guifa oh right. Nil returns Nil for everything except for a few methods 13:31
we need a true Nil that returns Nil always lol
p6steve i was wondering something like //= ?
guifa I mean, what is the value you want if there's nothing there? 13:32
if you do my $r = ~$<yr> if $<yr>, but $<yr> isn't there
$r will be (Any)
13:32 _________ joined
p6steve m: my $t = 'dkjgsjskjh'; my regex yr { \d**4 }; $t ~~ /<yr>/; my $r = ~$<yr> if $<yr>; $r.say 13:33
camelia (Any)
guifa my $r = .Str with $<yr>; is what I'd do
p6steve m: my $t = 'dkjgsj2022skjh'; my regex yr { \d**4 }; $t ~~ /<yr>/; my $r = .Str with $<yr>; $r.say 13:34
camelia 2022
p6steve m: my $t = 'dkjgsj2022skjh'; my regex yr { \d**4 }; $t ~~ /<yr>/; my $r .= Str with $<yr>; $r.say 13:35
camelia Use of uninitialized value $r of type Any in string context.
Methods .^name, .raku, .gist, or .say can be used to stringify it to something meaningful.

in block at <tmp> line 1
Voldenet Wait, there's so many operators in raku, but not the one for `?.`-like method call?
Nemokosch that's right
p6steve guifa: that's the ticket !! thanks
guifa Voldenet there is
BUT — and it's a big but 13:36
Nemokosch it's such a big but that the answer is essentially _no_
p6steve so with topicalizes into the expression - how cool is that
guifa .? returns Nil when the method isn't there
Nil in Raku is almost a true Nil, but frustratingly not quite when it comes to a handful of methods 13:37
Voldenet tilts head
guifa notably, in this case, .Str
Nemokosch the closest to a `?.` is `andthen`
`.?` is pretty much the opposite of `?.`
Voldenet m: my $x; my $y = $x?.Str;
camelia ===SORRY!=== Error while compiling <tmp>
Bogus postfix
at <tmp>:1
------> my $x; my $y = $x⏏?.Str;
expecting any of:
infix
infix stopper
postfix
statement end
statement modif…
Nemokosch not just visually - it checks if the method exists on the type
13:37 p6steve left
not if the data is available 13:37
Voldenet essentially .? isn't ?. tho, ?. is more useful when traversing data that could be missing 13:38
Would be nice if that op was added
Nemokosch `.?` is barely ever useful I think 13:39
make one - it's literally just $x andthen .method
"the tight `andthen`"
guifa You'd need to go to the slang level for it though. all the dot operators are psuedo operators — there's no way to catch the bare string on RHS with standard operators 13:40
Nemokosch tbh `andthen` itself is tricky the least to say 13:42
let's add one more to the RakuAST bucket list 😄 13:45
Voldenet :) 13:46
it's actually a tricky problem, btw 13:48
Nemokosch oh right, you might remember that andthen chain as well 13:49
where the second andthen absolutely failed to get a closure
Voldenet given `sub a(Any, –> Str)` and `sub b(Str, –> Int)` what should '$x?.&a?.&b` return, (Str) or (Int)? 13:50
guifa Speaking of slangs
I think tonight or tomorrow I'll finally release my regex one. Infinitely more advanced than my BASIC one
Nemokosch If there are 5 free minutes on the conference... 😉 13:51
guifa lol I already teased the idea of regex slangs at P&RC 13:52
I just don't have time to get a presentation together for that
Plus 90% of the cool stuff will be far more interesting once RakuAST is ready — I'm still having to do old fashioned string concats with a string-based EVAL because the regex nodes aren't quite finished 13:53
Nemokosch a shame really 13:54
Voldenet: my call (haha) would be (Int), by the way
If that call chain is allowed to succeed at all, I think that would only make sense
guifa I'd say Nil if the call fails. That works fine on typed variables: 13:55
m: my Str $a = Nil; say $a.WHAT
camelia (Str)
Nemokosch Yes, the regexes are kinda yucky at the moment... I mean it's nice that there is built-in syntax for them, but as long as there is no way to generate them, it's really just dummy weight 13:56
in the meantime, Python doesn't have actual regexes but strings and nothing can be missing
guifa You can handle some regex with RakuAST right now, just … not everything. And my slang is to convert a full regex flavor to Raku 13:57
Nemokosch I think Nil also leads to (Int) in that chain 13:58
guifa It'll lead to the type of the variable it's assigned to
so by default, (Any)
14:00 discord-raku-bot left 14:01 discord-raku-bot joined 14:03 discord-raku-bot left, discord-raku-bot joined
Nemokosch oh right, this won't run for any of us in this channel 14:03
14:04 Nemokosch joined
Nemokosch m: sub demo(-->Int) { Nil }; my Str $demo = demo; dd $demo; 14:04
camelia Str $demo = Str
tellable6 2022-08-04T22:01:12Z #raku <Xliff> Nemokosch: How do I parse that whole string as a string?
14:04 Nemokosch left 14:05 euandreh joined
Nemokosch It basically dodges all the type safety attempts 14:05
I would also have expected this function to return (Int), rather
since that's what my Int $result = Nil; would give 14:06
Voldenet Indeed, type safety is problematic here 14:07
Nemokosch again, this is not something I can foresee changing any time soon, if ever... but
doing "Nil is empty" and "Nil is a soft exception" at the same time is a hardly saveable approach
Voldenet m: sub why(–> Int()) { Nil }; why() 14:08
camelia ===SORRY!=== Error while compiling <tmp>
Missing block
at <tmp>:1
------> sub why(⏏–> Int()) { Nil }; why()
Voldenet m: sub foo(–> Int()) { Nil }; foo() 14:09
camelia ===SORRY!=== Error while compiling <tmp>
Missing block
at <tmp>:1
------> sub foo(⏏–> Int()) { Nil }; foo()
Voldenet ah, right
m: sub foo(--> Int()) { Nil }; foo()
camelia ( no output )
Voldenet m: sub foo(--> Int()) { Nil }; foo().WHAT.say
camelia Nil
Nemokosch all Failures derive from Nil, probably we wouldn't want to wrap them all into that certain Int...
Voldenet m: sub x() returns Int:D { Nil }; x().WHAT.say' 14:11
camelia ===SORRY!=== Error while compiling <tmp>
Two terms in a row
at <tmp>:1
------> x() returns Int:D { Nil }; x().WHAT.say⏏'
expecting any of:
infix
infix stopper
statement end
statement …
Voldenet m: sub x() returns Int:D { Nil }; x().WHAT.say
camelia Nil
Voldenet I'm not sure about getting Nil from a routine apparently returning `Int:D` 14:12
lizmat Nil is allowed to do that, as is Failure
m: sub a(--> Int:D) { fail "foo" }; say a 14:13
camelia foo
in sub a at <tmp> line 1
in block <unit> at <tmp> line 1
Nemokosch > Absence of a value or a benign failure
the problem itself is combining these two things
the "absence of a value" has all reasons to still obey type safety 14:14
Actually, it can be argued that a failure also has
Voldenet If I wanted type safety, I'd say that `Int` should either return `(Int)` or `Int:D`
failure is an exception, so I'd expect the call to never return anything 14:15
lizmat suppose types were checked for Failure and Nil, then any sub potentially return a Failure or Nil would not be able to have a return constraint
Nemokosch I frankly don't get why failures are even allowed to silently fall back to "the absence of a value"
But if they are allowed to do that, maybe even a failure should obey type annotations...
you wish but Failure is not an Exception 14:16
lizmat Failure wraps an Exception
it's an Exception with a built-in bomb disposal team :-) 14:17
Nemokosch I'm not sure I like the idea of "failures" in the first place but for all intents and purposes, they keep your code running, they don't break the flow
they act much more like values than exceptions
lizmat m: dd [].pop 14:18
camelia Failure.new(exception => X::Cannot::Empty.new(action => "pop", what => "Array"), backtrace => Backtrace.new)
lizmat m: if [].pop { } else { say "nothing to pop" } 14:19
camelia nothing to pop
14:19 _________ left
Nemokosch for example, this could be just "the absence of a value", without the bells and fanfars 14:20
a failure-agnostic Nil value
this example pretty much hints why I wasn't sure about failures regarding the type safety
you lose the assigned data I guess, or it has to "explode" some way 14:22
but assuming that Nil is JUST "the absence of a value", it could still be type safe
the same way nothing bad happens when you assign Nil to a typed variable, the function could do that by itself, hence not leaving a big hole on the type
what happens when you assign a Failure to a usual variable, though 🤔 14:24
Anton Antonov @lizmat Just submitted a new minor issue in the "App::Rak" GitHub repository. 🙂
Nemokosch I checked it now - it doesn't act like Nil...
lizmat Anton Antonov: thanks
14:24 Nemokosch joined
Nemokosch my $blah = [].pop; dd $blah ~~ Nil; $blah = Nil; dd $blah ~~ Nil; 14:25
evalable6 Bool::True
Bool::False
Nemokosch okay, I think this is the no.1 madness this week 14:26
Voldenet
Nemokosch what isn't Nil is Nil but what is Nil isn't Nil... this is roughly as bonkers as the legendary [] == ![] in Javascript
Voldenet `[] == ![]` isn't crazy, it makes perfect sense 14:27
Nemokosch okay... Raku/Problem-Solving... 14:28
Nemokosch Voldenet: it "makes sense" the same way this does
Voldenet :)
when you look at the code it's obvious
Nemokosch it is deterministic alright, but it is unintuitive to anyone who hasn't learned the conversion rules by heart 14:29
I feel strongly about [] converting to '' and 0 anyway
or '' to 0, for the matter, I praise Python for avoiding that conceptual clusterfuck
Voldenet no matter how you define it, automatic type conversions are going to be pain 14:30
Nemokosch well, if you define them in all directions, maybe
Voldenet -1 is true and also false
lizmat Nil returns a container to its original state 14:31
14:31 _________ joined
lizmat m: my $a is default(42) = 666; say $a; $a = Nil; say $a 14:31
camelia 666
42
Nemokosch You know, I tried this because I "expected" this result
"expected" in the bad sense
was afraid of it, we could say 14:32
I see this as the ultimate proof Failures should have nothing to do with Nil
they don't behave like Nil but falsely claim they are Nil
If they already don't behave like Nil, it would be very desirable that they don't claim to descend from Nil 14:33
lizmat m: dd Failure.^mro
camelia (Failure, Nil, Cool, Any, Mu)
Nemokosch Yes - take that Nil out of the chain, is my proposal 14:34
It violates the substitution principle in the craziest way
To be honest, I'm already afraid of the attempt to even write down the issue 14:36
14:38 Nemokosch left
Nemokosch But this is so insane that I wouldn't sleep well if I didn't even try to bring it up 14:38
14:41 discord-raku-bot left, discord-raku-bot joined
lizmat Insane? I'd say strangely consistent 14:41
Voldenet m: my Int:D $x = Nil; 14:42
camelia Type check failed in assignment to $x; expected Int:D but got Int (Int) (perhaps Nil was assigned to a :D which had no default?)
in block <unit> at <tmp> line 1
Voldenet m: sub x() returns Int:D { Nil }; x().say
camelia Nil
Voldenet so… is it allowed or not?
Nemokosch lizmat, please... 14:43
you have just seen a Failure being Nil while Nil itself NOT being Nil
what is so consistent about this...
lizmat returning Nil from a sub is *not* an assignment of Nil to a container 14:44
14:44 Altai-man left
Voldenet obviously 14:44
Nemokosch the behavior of Nil is the one of an absent value
the behavior of the descendants of Nil is one of a captured error
Voldenet but it's kind of surprising obviously
Nemokosch consistent?
but is it something the user should care about? 14:45
is this something _right_, even?
Voldenet if you return Int:D from method, it should be assignable to Int:D
lizmat perhaps... Nil predates having complete :D support 14:46
so perhaps it not failing was an oversight
for returning Nil
vrurg ^^ any ideas ?
Nemokosch the outlook of this is that the type system has a permanent leak on values that will come up every now and then
But even with a sole Int, shouldn't the missing value be (Int), as if there was indeed an assigment? 14:48
and this is were failures kick in again, as they descend from Nil but don't behave like Nil 14:49
Voldenet I'm not sure how jit is supposed to handle this 14:57
is there even a way to say that `this returns int always`? 14:58
I mean uh, I know 14:59
m: sub x() returns int { Nil }; x().say
camelia Cannot unbox a type object (Nil) to int.
in sub x at <tmp> line 1
in block <unit> at <tmp> line 1
Voldenet but perhaps it would be more useful if it type system was more constrained 15:00
lizmat perhaps, but it would have to be a 6.e feature, as otherwise I think too much code will start to fail in the wild 15:01
Possibly even a 6.f feature by now 15:02
Voldenet I suppose it is a big breaking change
lizmat afk for a few hours&
Nemokosch Issue created 15:18
Voldenet Nemokosch++ 15:19
Nemokosch One day, I will at least write a post about != and ne, that one is really a chest full of treasure, there could be so many acceptable and fully working solutions there
this one is tougher but also more important in a way 15:20
Voldenet im a lot of programming languages `x != y` is not equal to `!(x == y)` 15:21
also `x == y` is not equal to `y == x` 15:22
less surprisingly it's a result of convenient conversions 15:30
m: my $nil-assigned = Nil; say $nil-assigned ~~ Nil; 15:33
camelia False
Voldenet m: my $nil-assigned = Nil; say Nil ~~ $nil-assigned;
camelia True
Voldenet Ah yes.
but it's described in docs, so it's hrdly surprising 15:36
gfldex Smartmatching against Nil is a big code smell.
Voldenet having `Nil` anywhere near the code is a big code smell ;) 15:39
gfldex There can be very good reason to return Nil explicitely.
Voldenet with good enough reason you can also juggle null pointers casually, but it's still smelly code 15:42
15:44 linkable6 left, evalable6 left 15:45 linkable6 joined 15:46 evalable6 joined
Nemokosch Having Failure is Nil is language smell 15:55
Voldenet: I'm arguing that != should indeed not be a shorthand for !( x == y) 15:56
And I'm not the first one actually 15:57
Voldenet I do like my boolean algebra working though 15:59
15:59 discord-raku-bot left, discord-raku-bot joined
Voldenet messing with equality leads you to creation of `equals` method 16:03
(keep in mind missing `notEquals` method) 16:04
16:51 silug left
sjn heya; folks. I'm trying to build raku, and getting some linking issues with libmoar.so, during Configure.pl 17:01
anyone who has similar issues here?
here's the error: /usr/bin/ld: ./libmoar.so: undefined reference to `uv__cloexec_ioctl' 17:04
Hm. looks like my nqp dir was outdated, and Configure.pl didn't fix that 17:07
Voldenet apparently bad version of libuv was linked, btw 17:09
but nevermind 17:12
sjn deleting the nqp dir seems to do the trick, though I kinda expected that to have happened when I ran "make distclean" earlier.... :-| 17:15
(libuv was found somewhere deep below in that dir) 17:16
...so in other words, rebuilding raku from git when there are files lying around from a previous build, is a bit meh 17:17
"make distclean" ought to have fixed that, tbh
17:20 silug joined
lizmat sjn: could you please make an issue for that? It's been bugging me a few times as well 18:02
leont I've seen such issues before, it happens sometimes and it is annoying 18:05
18:06 reportable6 left 18:07 reportable6 joined
Nemokosch Voldenet: bad news, !(x == y) gets in the way here 18:09
Hint: Junctions
Voldenet no wonder I didn't think of it, I don't know how to use junctions :D 18:18
I mean uh, I know the syntax and all, I just don't know where to apply them 18:19
18:49 Altai-man joined
Nemokosch Fair enough, perhaps nobody really knows 18:50
anyway, (1, 4, 6).all >= 2 does mean "all these numbers are at least two", and will eventually collapse to False
but (1, 4, 6).all != 1 will collapse to True, because it expands to !((1, 4, 6).all == 1) 🤦‍♂️ 18:51
and like this is a design decision, mind you. There is nothing that keeps it from being consistent 18:52
!= and ne aren't operators that are allowed to act upon the individual values because Larry Wall said something about how English natives expect the negation to be lifted 18:53
maybe this is an oversimplification but I'm fairly certain if it wasn't for Larry's insisting that this makes sense, it would have never happened 18:55
Voldenet that's the problem of junctions though 18:56
Nemokosch Not really 18:57
Voldenet you can't simply apply logic operators to junctions
Nemokosch The junctions would be able to handle != and ne on individual values
no logic operators involved
Voldenet (1, 4, 6).all != 1 => (1, 4, 6).none == 1
Nemokosch the sole fact that NO, != and ne do NOT contain logic operators
they are _just operators_
Voldenet negation is logic operator 18:58
18:58 Sgeo joined
Nemokosch != is one operator, let alone ne 18:59
ne cannot even be argued to contain a logic operator
and inbefore yes, I do know that the design decision was to make them meta-involved
but like why unnecessarily break the expectation that they are operators?
that's why I brought >=, you know 19:00
this is the exact reason 19:01
>= is indeed not implemented as !<
>= is real but by deliberate design, != is not real, even though they could be, like in all other languages where this even comes up
!= could visually be <> by the same chance, like back in the Pascal days
Voldenet Sure, while it's very practical to implement just equality matching
it won't work in this case 19:02
Nemokosch I mean, for yourself, you can decide to implement not equal as not ( equal ) 19:03
but why should they be allowed to introduce inconsistencies with built-in stuff that led to the creation of the Mu type in the first place?
the fact that you _have to_ convert @values.all != $value into @values.none == $value is both against TIMTOWDY and I'd argue general linguistic inclusivity, as "none" is quite characteristically an anglo concept 19:05
I wouldn't bring these things up if I weren't repeatedly told how much Raku is about the community and the high ideals
and escaping anglocentrism in particular is an ideal I very much admire
Voldenet junctions are very anglocentric 19:07
Nemokosch that should mean it's an easy target 19:09
and since there are still usability issues with junctions, maybe it's not late to target them with this, in particular
that there is a non-technical issue around the design of junctions 19:10
Voldenet forall((1, 4, 6), * >= 2) would be more universal
or `!exists((1, 4, 6), * < 2)`
since it's `forall` handling operators, it can introduce special cases 19:11
Nemokosch the big idea of junctions (if it is really a "big" idea) is that it's a type
not a utility function but something built-in that works with quite literally anything that takes any
like subscripts
Voldenet which leads us to operator overloading 19:12
and more and more anglocentric design
it's not the problem with `(*!=*)` => `!(*==*)` transformation, it's that the junctions define their special case for this 19:15
Nemokosch why does it lead us to operator overloading? operator overloading, in the Pythonic, C++ish sense is virtually nonexistent in Rkau 19:16
19:16 deoac joined
Voldenet because essentially, operators can't be used on junctions, junctions use operators for the outcome 19:16
leont … I can't follow you now 19:17
Nemokosch If the operator is defined with Any
If I were to guess, this ! meta-magic happens on Mu level
so != takes up Mu values and already makes the "conversion" 19:18
transposal, rather
19:18 deoac left, deoac joined
leont Like, I get that negated operators can be confusing, but I don't see the problem with any operators 19:19
Nemokosch and then == is defined on Any
leont And part of the difficulty is that the current behavior is sensible for any but not for all, but any is much more common than all so I think it's the right call
Negating the junction instead of negating the operator is almost always the sensible solution though 19:21
Nemokosch the current behavior is not sensible for any, either 19:23
and like I'm not the first one to discover that - it came up in 2016 already, there is a rakudo issue as well, and Liz opened a pull request to change it but gave up because of the lack of consensus
(1, 2, 3).any != 2 -> "if any of the values are not 2"? "if any of the values are different from 2"? "if any of the values are greater or less than 2"? 19:26
doesn't match the semantics all these sentences set up
and the bigger problem is: if you picked ANY OPERATOR that isn't != or ne, it would match that semantics 19:28
including >= <= stuff
because it was insisted that != and ne not be real first-class operators
Voldenet m: say (1, 2, 6).all .is-prime 19:29
camelia all(False, True, False)
Voldenet m: sub my-prime { $^x.is-prime }; say (1, 2, 6).all my-prime; 19:30
camelia ===SORRY!=== Error while compiling <tmp>
Two terms in a row
at <tmp>:1
------> ime { $^x.is-prime }; say (1, 2, 6).all⏏ my-prime;
expecting any of:
infix
infix stopper
postfix
stateme…
Voldenet m: sub my-prime { $^x.is-prime }; say (1, 2, 6).all .&my-prime;
camelia ===SORRY!=== Error while compiling <tmp>
Malformed postfix call (only basic method calls that exclusively use a dot can be detached)
at <tmp>:1
------> e { $^x.is-prime }; say (1, 2, 6).all .⏏&my-prime;
Voldenet junctions have some rough edges 19:31
vrurg lizmat: Nil is bypassing any type checks. No exceptions. In part, this is what allows fails to be use used pretty much everywhere.
Nemokosch this is core Raku syntax though 19:32
19:32 Nemokosch joined
Nemokosch m: sub my-prime { $^x.is-prime }; say (1, 2, 6).all.&my-prime; 19:32
camelia all(False, True, False)
Voldenet ah, right, it's about .& op being hacky 19:33
Nemokosch vrurg: fails could do this on their own without Nil being involved, no? 19:34
It could be rephrased as "Failure is bypassing any type checks, no exceptions"
and then Nil could be safely used for one purpose: "the absence of a value"
19:34 Nemokosch left 19:42 deoac2 joined 19:44 deoac2 left, deoac17 joined 19:45 deoac17 left 19:50 [Coke] left 20:04 vrurg_ joined, vrurg left 20:13 Altai-man left
vrurg_ Nemokosch: Consider this way: Nil is a polite way of informing about a problem. Fail is "the last call". Throwing is the ultimate. 20:20
tellable6 vrurg_, I'll pass your message to Nemokosch
20:20 vrurg_ is now known as vrurg
vrurg Nemokosch: another thing, a container may have a default value to which it is gets reset when assigned with Nil. From this perspective returning Nil also makes full sense. 20:22
tellable6 vrurg, I'll pass your message to Nemokosch
Voldenet you can return thing of type Int:D that can't be assigned to Int:D later 20:27
m: sub get-thing() returns Int:D { Nil }; sub use-thing(Int:D $thing) { say $thing; }; my $x = get-thing() xx 3; use-thing($x[0]) 20:30
camelia Type check failed in binding to parameter '$thing'; expected Int but got Nil (Nil)
in sub use-thing at <tmp> line 1
in block <unit> at <tmp> line 1
Voldenet well, can't be assigned to Int either 20:33
Nemokosch vrurg: I get how Nil and Failure can both make sense; my point is that making a connection between them is troublesome 21:15
without that connection, it would really be "up to us" to deal with the code Voldenet sent. If Nil is absence, it could either be enforced to become Int when the function gives the return value - or it could be a compile error or something 21:16
However, if we want to allow Failures at all, essentially one needs to keep pretending they aren't some sort of Nil 21:17
vrurg Nemokosch: there will be no way to distinct a Nil return from Int when the latter is returned. See my comment in the problem-solving issue, actually. But the point is both Nil and Failure are actually "no value". But the latter is a _problematic_ no value. 21:18
tellable6 vrurg, I'll pass your message to Nemokosch
Nemokosch it would be better if one didn't have to "pretend" but they really wouldn't be a sort of Nil 21:19
after all, they don't really fulfill the expectations Nil sets
Anyway, it's okay if it is "no value" but perhaps it still shouldn't be mixed up with the absence of a value. Because it's not that and it doesn't behave like that. 21:20
21:20 linkable6 left, evalable6 left
vrurg An absence is singalled by undefinedness. I.e. by a type object. More over, the convenience is that absence can tell the type of the absent value. :) 21:21
21:22 evalable6 joined, linkable6 joined
Nemokosch And Nil is the typed undefinedness 21:25
and Failures are not undefinedness
vrurg They are too, but they're more than that. 21:28
And, BTW, failures actually only match to Mu/Any, but explode for any other typecheck. 21:31
... typecheck on assignement.
Nemokosch ... and to Nil :DDD 21:36
Something that holds a value that you need to store and retrieve is not a "missing value" 21:37
Simply by the fact that you need to store it 21:38
Also, this is not directed towards you in particular, I just notice that it's really hard to discuss these things because of a certain prejudice
Just because you (or even me, in certain cases) know why something works that way internally, won't make that behavior sane per se 21:39
it helps thinking about what lead to the anomaly but won't make the anomaly go away 21:42
21:45 avuserow left
Just think of Javascript. As I have read You Don't Know JS, I have to say, JS type coercion rules are mostly sane. There are only a few choices that I don't agree with, and even less that introduce inconsistencies (like [] converting to '' and 0, while being a truthy value). Yet, Javascript is remembered as the lunatic, 10-days language, and most of the cliché WTFs lead to coercion rules or hoisting. 21:48
Of course Javascript had such a headstart with the browser that this reputation couldn't kill it still, but Raku doesn't have any similar headstart. 21:49
Voldenet just remember that `[] - {}` is not a number
valid 21:50
Nemokosch 😂
fair
even - {} is not a number, is it 😄
Voldenet ofc 21:51
Nemokosch but {} - [] is 0 I think
Voldenet unlike `[] - []` which clearly is 0
Nemokosch oh sorry, `-0`
still fair xD 21:52
and I have to say, many of these WATs in Raku don't seem justified at all, there is either no feedback on why they have to be like that, or that feedback is very unconvincing... 21:53
Voldenet Though maybe Nil should be hiden behind some black magic namespace 21:56
it's clearly not something sane code should use
it's more like internal type system related thing
Nemokosch well, that's how vrurg made it sound for sure 21:57
and what really reassures me about these WATs is when I notice that "somebody was faster"
somebody has already noticed that very same thing and asked about it some way
Voldenet m: sub x() returns Int:D { Nil }; x 21:59
camelia ( no output )
Voldenet m: use nqp; sub x() returns Int:D { nqp::null() }; x
camelia Type check failed for return value; expected Int:D but got Mu (Mu)
in sub x at <tmp> line 1
in block <unit> at <tmp> line 1
Voldenet nqp::null() is safet ro use than Nil 22:00
s/safet ro/safer to/
Nemokosch the justified ancients of Mu Mu 22:01
vrurg Voldenet: Then just use Mu instead.
Voldenet problem is that any lib can use Nil instead 22:02
vrurg I have a string feeling that what you, ppl, need is just an undefined value. If you don't understand Nil then you likely not using it the way it is supposed to be used. 22:03
I myself normally avoid it because there are better ways.
lizmat in that case, I'd say Any is what you're looking for
Voldenet Yes, indeed
vrurg *strong feeling
Voldenet you're assuming that producer of the code is also consuming the code 22:05
Nemokosch ^^
Voldenet type safety of libs become the problem
Nemokosch And where is the compiler to tell you (or others, for that matter) that you are drilling a hole in the type system, for example?
Voldenet I'm expecting some objective-c to default to using Nil 22:06
s/objective-c/objective-c programmers/
vrurg m: sub foo(--> Int:D) { Nil }; my Int:D $v = foo;
camelia Type check failed in assignment to $v; expected Int:D but got Int (Int) (perhaps Nil was assigned to a :D which had no default?)
in block <unit> at <tmp> line 1
vrurg This is it. This is how things are to be done. 22:07
If strict typing is required.
lizmat calls it a day
Nemokosch Voldenet made a pretty good example that counteracts this
> sub get-thing() returns Int:D { Nil }; sub use-thing(Int:D $thing) { say $thing; }; my $x = get-thing() xx 3; use-thing($x[0]) 22:08
vrurg Which one? I don't have time to follow everything here.
m: sub get-thing() returns Int:D { Nil }; sub use-thing(Int:D $thing) { say $thing; }; my $x = get-thing() xx 3; use-thing($x[0])
camelia Type check failed in binding to parameter '$thing'; expected Int but got Nil (Nil)
in sub use-thing at <tmp> line 1
in block <unit> at <tmp> line 1
vrurg First of all, we do get a typecheck error here.
Second: 22:09
Voldenet error on use
vrurg m: sub get-thing() returns Int:D { Nil }; sub use-thing(Int:D $thing) { say $thing; }; my Int:D @x = get-thing() xx 3; use-thing($x[0])
camelia ===SORRY!=== Error while compiling <tmp>
Variable '$x' is not declared. Did you mean '@x'?
at <tmp>:1
------> Int:D @x = get-thing() xx 3; use-thing(⏏$x[0])
Nemokosch that sub lied like a boss 😄
vrurg m: sub get-thing() returns Int:D { Nil }; sub use-thing(Int:D $thing) { say $thing; }; my Int:D @x = get-thing() xx 3; use-thing(@x[0])
camelia Type check failed in assignment to @x; expected Int:D but got Int (Int) (perhaps Nil was assigned to a :D which had no default?)
in block <unit> at <tmp> line 1
Nemokosch yes - from a function that should actually produce Int:D
because that's its signature
Voldenet the more complex codebase, the harder will it be to find out what's the problem
Nemokosch it cannot be trusted
vrurg Voldenet: that's why you use typing in that codebase. Not `my $x` where you expect a typed array, but `my Int:D @x`. 22:10
Voldenet this is not helpful at all
vrurg Why?????
Voldenet you're filling the codebase with all the pointless types
the only functions that are interested in those types are `get-thing` and `use-thing`
vrurg C'mon, tell this to Rust people where everything typed! 22:11
Nemokosch even Rust strongly relies on type inference though
Voldenet Not really!
vrurg Either way, I would keep away from big codebase which blindly trusts third-party libraries. They're not proven to be bugless. Also, a module/lib dev must document the return values, Nil too. 22:12
Nemokosch I have an urge to call this "type sanity" instead of "type safety" 😅
vrurg Rust infers types, as far as I remember.
Any way, the principle of 'better safe than sorry' is working.
Nemokosch because it's "type safe" in the sense that the supposed types match - however it's not "type sane" because an unchecked type got in and broke all expectations 22:13
vrurg So, either one is toying with code and can allow themselve skip types. Or it's something serious and types are used anywhere there are doubts.
Voldenet > sub get-thing() returns Int:D { my Int:D $x = third-party-value; $x };
it's extremely weird code right there 22:14
vrurg Ok, I have a lot of work for today. Just have nothing else to add.
Nemokosch vrurg: you know 22:15
Many people (who aren't us)
would keep away from a language where something that is Nil is not Nil but something that is not Nil is Nil
so I think you're sitting backwards on that horse
vrurg Voldenet: it's simpler as `sub get-thing(--> Int:D) { my Int:D $ = foo }`
vrurg is afk& 22:16
Voldenet I'm not getting my pitchfork for this, it's not worth fighting for, let's just hope nobody uses Nil ;)
Nemokosch Frankly, those people who want to be safe all the time and get their money on time, won't choose Raku as it is now. I'm definitely not that type of person. 22:18
I'm okay with reporting issues, looking for a module that may be somewhat similar to what I want to do, polishing code just for the sake of it 22:19
But this "git gud" attitude is a sure way to keep those others away from this language
ugexe there are no perfect tradeoffs 22:28
unless i did them
Voldenet ;D 22:29
I think in objective-c you can assign nil to NSNumber, btw
ugexe m: my Int:D $x is default(42) = Nil # there is also this behavior 22:30
camelia ( no output )
Voldenet the thing I'm on about is the discrepancy between returned type and the one accepted for the container 22:31
Nemokosch zef install Ugexe::Tradeoffs 22:36
Voldenet :)
Nemokosch And like apparently the container isn't even needed for the check, right? A binding is enough. 22:38
Voldenet > Any method call on Nil of a method that does not exist, and consequently, any subscripting operation, will succeed and return Nil. 22:40
m: say Nil.CALL-ME()
camelia No such method 'CALL-ME' for invocant of type 'Nil'
in block <unit> at <tmp> line 1
Voldenet uh
m: say Nil() 22:42
camelia Nil
ugexe github.com/rakudo/rakudo/blob/9b13....nqp#L3866 22:43
looks like the code for CALL-ME() goes through a different code path than most others
eh thats !moar tho 22:44
22:45 linkable6 left, evalable6 left, evalable6 joined
Voldenet not like I'm expecting to use Nil any time soon, but it is sufficiently weird 22:45
22:46 linkable6 joined
Voldenet it's a tool that looks like it only invites subtle bugs into well-typed code 22:47
22:48 pamplemousse joined
Nemokosch (Any) is my favorite Nil 22:49
:PP
22:53 deoac left
Voldenet i'm looking through codebases and in most cases (Any) would be better 22:53
22:55 deoac joined
Voldenet there are some null object design pattern uses tho 22:55
but after seeing number of occurences, I understand why can't it be changed easily 22:56
Nemokosch Well that's still no reason to make Failures descend from Nil... 22:57
22:58 pamplemousse left
Voldenet they don't behave like Nil anyway, I'm pondering why 23:24
23:58 evalable6 left, linkable6 left 23:59 linkable6 joined