This channel is intended for people just starting with the Raku Programming Language (raku.org). Logs are available at irclogs.raku.org/raku-beginner/live.html Set by lizmat on 8 June 2022. |
|||
00:01
hudo__ joined
00:04
hudo_ left
01:54
guifa_ left
|
|||
aruniecrisps | Is there a way to use with that allows you to check for two variables at once, kind of like: with $maybe-fail-1 -> $x, $maybe-fail-2 -> { } else { } | 02:43 | |
antononcube | You can use the method defined instead. | 03:41 | |
03:46
discord-raku-bot left,
discord-raku-bot joined
|
|||
aruniecrisps | yea, i figured the other option was something like if all($maybe-fail-1, $maybe-fail-2).defined { } else { } | 03:47 | |
05:22
discord-raku-bot left,
discord-raku-bot joined
|
|||
@SmokeMachine I'm gonna fork the RedJobber repo and play around with it | 05:58 | ||
09:43
CIAvash joined
10:32
CIAvash left
|
|||
gfldex | m: my $a; my $b; with $a { with $b {;} } | 10:47 | |
Raku eval | |||
ab5tract | m: my $a = 1; my $b = 0; with so $a & $b { dd $_ } | 11:26 | |
camelia | Bool::False | ||
ab5tract | mostly defeats the utility of `with`, though | 11:30 | |
gfldex | Indeed, Rakudo can't optimise that. | 11:52 | |
librasteve | err - I think that this wil work: | 15:07 | |
with ($maybe-fail-1 & $maybe-fai-2) { } else { } | 15:08 | ||
so you use & to make an all junction and then use that as the argument of with ... | 15:09 | ||
can even go ... | 15:12 | ||
with $maybe-fail-1 & $maybe-fail-2 { } else { } | |||
16:07
teatime joined
|
|||
gfldex | m: sub prefix:<///>(\RHS) { RHS.defined ?? True !! Any } my @perms = [X] (42, Any).permutations; for @perms -> [$a, $b] { say [$a, $b, do with /// ($a & $b) { 'Amen!'; }]; } | 18:30 | |
Raku eval | [42 (Any)] [42 42 Amen!] [(Any) (Any)] [(Any) 42] | ||
gfldex | Solved, but way to tricky. | 18:31 | |
The problem here is that definedness is not an object. Quite in contrast to True-ness. | |||
.oO( This may deserve a blogpost. ) | 18:32 | ||
librasteve | gfldex: I see that you have a solution and I guess that it is better than mine | 19:05 | |
BUT ... I get the same output without the fancy '///' operator | 19:06 | ||
my @perms = [X] (42, Any).permutations; for @perms -> [$a, $b] { say [$a, $b, do with ($a & $b) { 'Amen!'; }]; } | |||
[42 (Any)] [42 42 Amen!] [(Any) (Any)] [(Any) 42] | |||
Please can you elaborate why my proposal fails? | 19:07 | ||
My proposition is that with ($a & $b) is similar to ($a & $b).defined where ($a & $b) is an all Junction so maybe there's a flaw in that logic?? | 19:23 | ||
gfldex | with cares about definedness, the &-Junction cares and returns about True-ness. There are objects that are defined but False and one can cunstruct an object that is undefined but True (there may be good reason to do so). | 19:44 | |
Sadly, it so not trivial to implent custom Junctions or it would be possible to have one that cares about and returns defined-ness (by cheating, because there is no value for definedness). | 19:46 | ||
In Raku (and AFAIK no other language) we make a clear distinction between true-ness, defined-ness and DEFINITE-ness. The docs are not good at pointing that out. | 19:49 | ||
Nahita | can you given an example? i think with $a & $b works as librasteve mentions. Junction doesn't return a True immediately unless in a boolean context right? And with doesn't immediately impose that but first subjects definedness, which the junction then seems to evaluate as $a.defined && $b.defined: | 19:59 | |
m: my $a = 3 but False; my $b = -2; with $a & $b { say "both defined, ok" } else { say "at least one undefined" } | |||
Raku eval | both defined, ok | ||
Nahita | m: my $a = 3 but False; my $b = Raku; with $a & $b { say "both defined, ok" } else { say "at least one undefined" } | 20:00 | |
Raku eval | at least one undefined | ||
gfldex | m: my $a = True but role :: { method defined { False } }; my $b = Raku; with $a & $b { say "both defined, ok" } else { say "at least one undefined" } | 20:01 | |
Raku eval | at least one undefined | ||
Nahita | not sure I follow. You mean it should look at .DEFINITE or something? In this example, $a.defined is explicitly made False, so it is the expectation that with $a & $b won't pass through? | 20:04 | |
gfldex | .DEFINITE is not the same as .defined. The latter is a method under the control of the object in question, .DEFINITE is a grammar-level macro (same as .WHAT) and lastly a call into the VM. (In the VM it's just looking at pointer field in a C-struct). | 20:08 | |
Nahita | yeah I'm familiar they are not the same. I didn't understand your example, so I was mentioning maybe you were alluding to that or something | ||
I still don't see what your example shows and how it disproves with $a & $b is failing | 20:09 | ||
gfldex | I would not trust a Junction and definedness, because a Junctions always returns Bool. | 20:10 | |
m: my $a; my $b; my @perms = [X] (42, Any).permutations; sub infix:</&>(\LHS, \RHS) { constant Defined = Mu.new; LHS.defined && RHS.defined ?? Defined !! Any } for @perms -> [$a, $b] { say [$a, $b, do with $a /& $b { 'Amen!'; }]; } | |||
Raku eval | [42 (Any)] [42 42 Amen!] [(Any) (Any)] [(Any) 42] | ||
gfldex | I think this is a clear solution. By defining a defined-and infix, we don't need the Junction anymore. | 20:11 | |
Maybe //& would be a better name for defined-and. | 20:12 | ||
Nahita | No this is not clear why extra work is a clear solution. If you changed /& to &, you get the same exact output | 20:13 | |
gfldex | There is no Roast test for combining Junction and with (or I can't find it). So if that works it is a happy coincidence. | ||
Nahita | > because a Junctions always returns Bool. only asked in a boolean context, no? | ||
isn't the superposition of many states their thing | 20:14 | ||
gfldex | No, a Junction always returns a Bool. | ||
Read the Rakudo-code, if you don't trust me. | |||
Nahita | m: say (12 & 3) + 1 | ||
Raku eval | all(13, 4) | ||
gfldex | Please not that say is (almost) a debugging utility. | 20:15 | |
It will go out of it's way to display something gist-ish. | |||
librasteve | m: (-1 & 1).sign | 20:17 | |
Raku eval | |||
librasteve | m: say (-1 & 1).sign | ||
Raku eval | all(-1, 1) | ||
librasteve | m: say (-1 & 1).defined | ||
Raku eval | True | ||
librasteve | so I get from this that .defined caused the Junction to collapse and thus rturn a Bool | 20:18 | |
so I guess that gfldex is right about the behaviour (even if it's surprising) | 20:19 | ||
back to the question, how about | |||
[&&] (-1,1)>>.defined | |||
gfldex | For methods-calls. you can find the Rakudo code for what happens. Indeed, it calles .defined an each member of the source-Junction and creates a new Junction object with the returned elements as members (and the same Junction-(sub)-type. | 20:21 | |
Please note, that Junctions are internal-ish objects and where meant to be highly optimisable. That Rakudo exposes the values may be a mistakes that will bite us in the future. | 20:22 | ||
Where by "future" is a value within the next 100 years. :) | |||
librasteve | so why dont we get ... | 20:23 | |
say (-1 & 1).defined; # all(True, True) | 20:24 | ||
Nahita | so I read the source and concluded it doesn't always return a Bool; only if asked to, directly or indirectly. What do I do next... | ||
no! in this case it returns a Bool method !defined-all() { my \eigenstates := $!eigenstates; my int $i = -1; nqp::while( nqp::islt_i(++$i,nqp::elems(eigenstates)) && nqp::atpos(eigenstates,$i).defined, nqp::null ); nqp::hllbool(nqp::iseq_i($i,nqp::elems(eigenstates))) } | |||
no junction is generated in here | 20:25 | ||
gfldex | Please point me at that code. | ||
Nahita | so asks truthfulness and collapses a Junction. defined asks for a parallel concept and collapses a junction, so they specifically implemented .defined method, is my theory | 20:27 | |
like they implemented .Bool as well | |||
gfldex | !defined-all is called by .defined _on_the_new_Junction_object. | ||
Nahita | because if they didn't implement a custom .defined, since Junctions don't evaluate to a Boolean but, well, to a Junction type object, it will do all(True, True) | 20:28 | |
sorry, what is the "new" Junction object; don't they evaluate to Bool always as you say? | |||
come on... | |||
gfldex | lizmat the be precise, see here: github.com/rakudo/rakudo/commit/7a...dfc353a92e | ||
That is an optimisation and may vanish at some point in the future. | 20:29 | ||
Nahita | with all due respect, "a Junction always returns a Bool." is I think wrong and contrasts the whole existence of Junctions, many states bundled together like a cat, only when you ask, they collapse to a Bool. Otherwise, they are a Junction object... | 20:31 | |
m: say (3 & -7) ~~ Bool | |||
Raku eval | False | ||
gfldex | 1 & 2 forms a Junction object. Any operation on that object creates a new Junction object. Unless the compiler cheats. Such cheats are colled "optimisation". Don't rely on them. They are very internal and can change with every new commit. | 20:32 | |
Nahita | so can you rephrase for me to better understand what you meant by "a Junction always returns a Bool." please? | 20:33 | |
gfldex | Please consider Roast the definition of the language, not what Rakudo does. And Roast does not know about the optimisation of the .defined-call case. | 20:35 | |
librasteve | m: say (Any & Any).defined | ||
Raku eval | False | ||
Nahita | not talking about .defined, though... If anything, it would support your claim of them being Bools | 20:37 | |
librasteve | ^^^ this is a quandary - it is a Junction object (which is defined), but it collapses to an undefined state ... so you are going to need a special exception to apply .defined to a Junction | ||
Nahita | .defined and .Bool are authors way of providing collapsers to user code | ||
librasteve | so we all agree that Junction.defined must be a special cased path, right? | ||
Nahita | yes they implemented specifically | 20:38 | |
otherwise it would defer to casual method call and return a Junction back, all(False, False) for that last example of yours | |||
librasteve | so my guess is that eh implementor of this case made it DWIM (ie made the original with ($a & $b) do what I showed initially) | ||
gfldex | This is exactly the special case that lizmat cared about. But if you want to use eigenstates; (a module written by lizmat) you get a surprising result, _in_this_special_case. Because after the operation we should get Junction.new(True, True, :type<all>). | 20:39 | |
The commit message states otherwise. It is clearly an optimisation. | 20:40 | ||
Nahita | you see that prior to that commit, .defined was returning a Bool still, right? | 20:41 | |
and even if it didn't, and returned a Junction (of definedness-es), that Junction will be then tested against truthfulness to collapse a Bool, and it would still work the same | 20:42 | ||
gfldex | I consider the with-block working in conjunction with this optimisation a happy-coincidence. It does DWIM. so this might be an ENOROAST. | ||
Nahita | Interesting you don't see it as strangely consistent, though... | 20:43 | |
specifically overloading .defined is not an optimization though, it's consistent with .Bool collapsing, so .defined also collapses | 20:44 | ||
the !defined-all et al. are not of interest to us; implementation detail that someone thankfully did to make it faster | |||
and to repeat, even if they didn't overload .defined, it would return a Junction as yet another casual method call | 20:45 | ||
librasteve | if you are happy with the behaviour of Junction.defined (with and without the optimization), then there is no happy conincidence other than with effectively applies .defined to it's argument | ||
Nahita | that Junction would be then collapsed to produce a Bool because that's what with eventually wants being a synonym to if ...defined | 20:46 | |
then the observable behaviour here and then would be the same! | |||
librasteve | so why not say this is suprisingly consistent and add this test to ROAST | ||
gfldex | We may have to do so or use v6.e; may cause more surprises that we would like to. | 20:48 | |
However, I'm not sure if a with-block or with-statement makes sense with a Junction. The current behaviour may give the right answer to the wrong question. It feels like a design smell and those tend to hurt in the long run. | 20:50 | ||
Also, can somebody please add "SprachgefĆ¼hl" to the English language. You did steal "schadenfreude" and "zeitgeist" after all. | 20:51 | ||
librasteve | it's certainly fairly "out there" in terms of when you would want it | ||
The first known use of sprachgefĆ¼hl was in 1894 | 20:54 | ||
www.merriam-webster.com/dictionary/sprachgefĆ¼hl | |||
just use it! | |||
gfldex | Thank you very much indeed! | ||
librasteve | (but no capitals and expect everyone to wtf) | 20:55 | |
what is the inverse of Sprachgefuehl? | 20:56 | ||
(in the sense of code smell == poor sprachgefuhl) | 20:57 | ||
gfldex | m: my \a = (42 & 42).defined; dd a; my \b = (42 & 42).Str; dd b; | 21:01 | |
Raku eval | Bool::True all("42", "42") | ||
gfldex | @Nahita Does this ^^^ look consistent to you? | 21:02 | |
Nahita | yes, as I mentioned, they specifically overloaded .Bool and .defined for us users to collapse the Junctions to Booleans | ||
to work with if and with smoothly | |||
gfldex | lizmat: Do you got an opinion on that last example? | 21:03 | |
Nahita | which it turns out they do very smoothly, as the best answer so far to arun's question was by librasteve and it was with $a & $b | ||
highly readable too | |||
still you didn't answer this, but of course you don't have to... | 21:05 | ||
gfldex | Do you know about the module called eigenstates? | 21:06 | |
Nahita | exposes the bundled private states of a junction? yes if so | 21:07 | |
gfldex | Good, you can go a step deeper and do funky stuff with the module. It allows to avoid loops (because that loop is hidden in Junction.rakumod). But that requires the result-Junction to acutally be a Junction. If there is a .defined call in the loop (that can be fairly well hidden, Raku is a functionally-ish language) that will fail. | 21:10 | |
This may be the reason why my sprachgefĆ¼hl is complaining. | |||
This discussion is getting dangerous! I almost crashed my spaceship into a spacestation. :) | 21:12 | ||
librasteve | even the author of eigenstates says we should never use it and that Junctions are a black box | 21:13 | |
gfldex | here is an example how to (ab)use eigenstates: gfldex.wordpress.com/2022/07/30/sw...g-sundays/ | ||
librasteve | surely the bahaviour of Junctions under a method call is do the call on each member and return a Junction of results (unless it special cased) | 21:15 | |
and we all agree that Junction.defined is a special case | |||
gfldex | I would support a no-use-nqp-policy of Raku modules. Sadly, that trains has been gone for quite a while now. | 21:16 | |
librasteve | I do not support a language design policy based on the idea that someone may use eigenstates (there are many health warnings on this module and reliance on such implementation details is a known risk) | 21:17 | |
gfldex | I do agree that it is a special case. I don't agree it is so for DWIMing. It looks like an optimisation-by-hand. | 21:18 | |
librasteve | anyway I am keen to hear what lizmat thinks ... since she wrote the code ;-) | 21:19 | |
gfldex | m: with True && False { say āoiā½ā } | 21:26 | |
Raku eval | oiā½ | ||
gfldex | Actually, this may be the reason why my sprachgefĆ¼hl complains so hard. | ||
librasteve | & not && | 21:27 | |
m: with False {say 'yo'} | 21:28 | ||
Raku eval | yo | ||
lizmat | could someone gist me what I should have an opinion about? | ||
gfldex | lizmat: gist.github.com/gfldex/57f83bae44e...0c971d7eed | 21:29 | |
librasteve | m: say "yo" with 1 & Any; | 21:30 | |
Raku eval | |||
librasteve | m: with 1 & Any {say 'yo'} | ||
Raku eval | |||
librasteve | m: with Any & Any {say 'yo'} | 21:31 | |
Raku eval | |||
librasteve | m: with 1 & 1 {say 'yo'} | ||
Raku eval | yo | ||
librasteve | ^^ is it supported to use with with a Junction to check that all arguments are .defined? | ||
lizmat | so the question is: should Junction.defined return a Junction or a Bool ? | 21:32 | |
librasteve | no, more like "can with take a Junction a argument" | 21:33 | |
aruniecrisps | it ultimately spawned from my question on how you would go about assigning multiple variables in a with statement | 21:34 | |
lizmat | also: I did do github.com/rakudo/rakudo/commit/7a...dfc353a92e but didn't change any semantics | ||
so don't ask me why Junction.defined doesn't return a Junction ;-) | 21:35 | ||
librasteve | here's a longer example (from above)... | 21:36 | |
lakmatiol | the docs tell me this | ||
cdn.discordapp.com/attachments/768...a4cb5& | |||
gfldex | .oO(We need to blame deeper!) |
||
librasteve | my @perms = [X] (42, Any).permutations; for @perms -> [$a, $b] { say [$a, $b, do with ($a & $b) { 'Amen!'; }]; } | 21:37 | |
gives... | |||
[42 (Any)] [42 42 Amen!] [(Any) (Any)] [(Any) 42] | |||
gfldex | I think I found it. github.com/Raku/old-issue-tracker/issues/5801 | 21:38 | |
librasteve | the question is - can a Junction be used reliably as the argument of a with ? (ie can this behaviour be relied on) | ||
lakmatiol | if with is specified to call .defined, then it should work fine if .defined works as it says so in the docs for Junction.defined | 21:39 | |
librasteve | yes, that's the question | 21:40 | |
gfldex | :D So we conclude: Zoffix just changed he behaviour without any further discussion. | ||
aruniecrisps | the question i'm assuming is whether Junction.defined as it is now, is gonna remain that way reliably | 21:41 | |
gfldex | I don't miss that guy. :) | ||
lizmat | A Raku "with" codegens to an nqp::with, and that is documented as: github.com/Raku/nqp/blob/master/do...kdown#with | 21:42 | |
gfldex | "evaluates to a defined value" is not exactly an explanation what happens. Because Raku does not have a value for defined-ness. | 21:43 | |
My guess would be: If it is a native-type, cheat. Otherwise call `.defined`. | 21:44 | ||
lizmat | % nqp -e 'nqp::with(42,nqp::say("foo"))' | 21:45 | |
Cannot find method 'defined' on object of type BOOTInt | |||
looks like it tries to execute a .defined | |||
so the doc could be clearer on that | 21:46 | ||
s/evaluates to a defined value/calls the .defined method/ | 21:47 | ||
m: class A { method defined(--> False) { } }; with A.new { say "foo" } | |||
camelia | ( no output ) | ||
gfldex | lizmat: does that mean that MoarVM could cheat for BOOTInt (lest there is a mixin)? | ||
21:48
MasterDuke joined
|
|||
lizmat | from Raku, you shouldn't be able to reach the BootInt normally, it would always be boxed | 21:48 | |
m: say 42.^find_method("defined").file | 21:49 | ||
camelia | SETTING::src/core.c/Mu.rakumod | ||
lizmat | so no cheating is needed | 21:50 | |
librasteve | ok, so I take it that we can have confidence in: | 21:53 | |
with $a & $b {say 'yo'} | |||
lizmat | m: with 42 & 666 { say "foo" } | 21:54 | |
camelia | foo | ||
lizmat | m: say "foo" with 42 & 666 | ||
camelia | foo | ||
librasteve | thanks all | 21:55 | |
aruniecrisps | Is there a way to automatically restart a Cro server when I make changes to the code or no? | 22:02 | |
lizmat | not sure, maybe ask on #cro ? | 22:04 | |
librasteve | The cro run command is used to run services. It automatically sets up file watching and restarts services when there are source changes to the services | 22:05 | |
cro.services/docs/cro-tool | |||
aruniecrisps | gotcha thanks! | 22:06 | |
gfldex | Issue issued as: github.com/Raku/roast/issues/852 | 22:11 | |
aruniecrisps | Okay there is one thing I'm not the biggest fan of right now, and it's the install times for Cro | 22:22 | |
lizmat | you can try installing with --/test | 22:23 | |
aruniecrisps | Good catch, that's what I was doing wrong, thanks! | ||
lizmat | the Cro test suite is pretty elaborate | 22:24 | |
aruniecrisps | Yea I noticed, looks pretty battle tested as well | 22:26 | |
22:53
sivoais left
|
|||
I'm running into this error when setting up HTTP 2.0 with Cro: | 22:56 | ||
cdn.discordapp.com/attachments/768...e4112& | |||
23:06
sivoais joined
23:11
teatime left,
teatime joined
|