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