|
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:44
archenoth left
01:17
frost joined
01:46
chikega joined
|
|||
| chikega | Hi everyone, are there any video tutorials about learning the Raku language? | 01:47 | |
|
01:51
chikega left
02:46
jetchisel left
02:49
jetchisel joined
03:06
MasterDuke left
03:09
razetime joined
03:27
razetime left
04:06
razetime joined
08:03
razetime left
08:20
razetime joined
08:34
frost left
|
|||
| lizmat | there are: www.youtube.com/results?search_que...23rakulang is a good starting point ? | 08:44 | |
|
09:00
crystalfrost[m] left
|
|||
| Nemokosch | Do you think a tematic Raku series would help? I used to love making tutorial series | 09:00 | |
|
09:00
crystalfrost[m] joined,
crystalfrost[m] left
|
|||
| lizmat | I think it would, if you feel up to it :) | 09:04 | |
| Nemokosch | The main question is if I should try to aim for a "first language" approach or an "nth language" assumption will do | 09:06 | |
| lizmat | fwiw, personally I would love to see a "first language" approach, because there are quite a few tutorials already coming from other languages | 09:07 | |
|
09:31
razetime left,
razetime_ joined
|
|||
| zacque | Why is my `@pascal` has different values from calling the `pascal-sequence` directly? paste.debian.net/1255512/ | 09:41 | |
| What's going on with the assignment? | |||
| gfldex | <@511826957558611968> you don't reset @k and the result-array @pascal contains referenced to @k. So the last change to @k will end up x times in @pascal. | 09:46 | |
| m:``` | 09:50 | ||
| sub pascal-sequence(Int:D $number) { | |||
| my @k; | |||
| gather { | |||
| for 1..$number { | |||
| @k = 1, | @k >>+>> (| @k[1..*], 0); | |||
| take @k.clone; | |||
| } | |||
| } | |||
| } | |||
| sub MAIN(Int:D $rows where $rows >= 3) { | |||
| my @pascal = (pascal-sequence $rows); | |||
| say @pascal; # OUTPUT: [[1 4 6 4 1] [1 4 6 4 1] [1 4 6 4 1] [1 4 6 4 1] [1 4 6 4 1]] | |||
| say (pascal-sequence $rows); # OUTPUT: ([1] [1 1] [1 2 1] [1 3 3 1] [1 4 6 4 1]) | |||
| } | |||
| MAIN(5); | |||
| ``` | |||
| m:``` | |||
| sub pascal-sequence(Int:D $number) { | |||
| my @k; | |||
| gather { | |||
| for 1..$number { | |||
| @k = 1, | @k >>+>> (| @k[1..*], 0); | |||
| take @k.clone; | |||
| } | 09:51 | ||
| } | |||
| } | |||
| sub AIN(Int:D $rows where $rows >= 3) { | |||
| my @pascal = (pascal-sequence $rows); | |||
| say @pascal; # OUTPUT: [[1 4 6 4 1] [1 4 6 4 1] [1 4 6 4 1] [1 4 6 4 1] [1 4 6 4 1]] | |||
| say (pascal-sequence $rows); # OUTPUT: ([1] [1 1] [1 2 1] [1 3 3 1] [1 4 6 4 1]) | |||
| } | |||
| AIN(5); | |||
| ``` | |||
| I got the feeling that there is a sequence operator waiting to be used for this problem. :) | 09:52 | ||
| zacque | Hmm, I don't get it, but `say (pascal-sequence $rows);` does give the correct result? | 09:53 | |
| I hope it does! 😄 | 09:54 | ||
| Nemokosch | it is seriously weird that one works and the other doesn't | ||
| but what you are doing was clearly a bad idea | 09:55 | ||
| ie modifying it in-place and taking it multiple times | 09:56 | ||
| actually, I have an idea why it's so weird | |||
| @vars are eager by default | |||
| so it fetched your whole sequence, and the inner list reached the last element | |||
| so you got the last element multiple times | |||
| on the other hand, the sequence was lazy so the mutation happened on the fly, giving the correct results | |||
| if my hypothesis is correct, it would work correctly with ` my @pascal = lazy (pascal-sequence $rows);` | 09:57 | ||
| zacque | Ok, so `take` always return a reference to the variable? | 10:16 | |
| I don't see how lazy and eager play a role here, because it doesn't say that `gather/take` is always lazy | 10:17 | ||
| Putting `lazy` in front of `pascal-sequence` doesn't help either | 10:18 | ||
| Nemokosch | pretty much everything is always lazy | ||
| it would be easier to collect the counterexamples | |||
| zacque | Oh, that's new to me. But I don't see it stated in the docs =X | 10:19 | |
| Hmmm, I mean why do you say that everything is always lazy? | 10:21 | ||
| Nemokosch | ~~because it's quite accurate~~ | ||
| it's a general design principle that everything that can return Seq over List, will return Seq over List | |||
| X, Z, map, grep, in fact gather and take is rather obvious in this list | |||
| because it's like the Raku version of generators and generators are lazy by concept | 10:23 | ||
| zacque | Huh? But Seq is only potentially lazy, from the doc "class Seq: An iterable, potentially lazy sequence of values" | ||
| I guess it meant that some functions taking Seq should be able to handle lazy list? | |||
| Nemokosch | I'd say there is no big difference between "lazy" and "potentially lazy" | 10:24 | |
| the implications come with the potential | 10:25 | ||
| it's rather a semantic argument, if we mean "lazy" as implementation or "lazy" as interface | |||
| "potentially lazy" is about the interface | |||
| zacque | I don't think it matters if that's an implementation detail | ||
| Nemokosch | you shall not assume that it's not lazy | ||
| zacque | From the user perspective, I guess I can safely assume all are not lazy unless declared otherwise? | ||
| Nemokosch | it's rather the opposite | 10:27 | |
| zacque | I meant if I work with the built-in lists and operators | ||
| Nemokosch | yeah no | ||
| almost everything is "potentially lazy", unless you ask otherwise | |||
| zacque | Hmmm, okay, I'll keep it in mind while learning more about Raku | ||
| Thanks | |||
| Nemokosch | this is really good when working with loads (potentially infinite) of data | ||
| zacque | But in the case, I think the laziness doesn't matter? Cause I've put `lazy` keyword and it gives the same result | 10:28 | |
| Yup, agree | 10:29 | ||
| Nemokosch | for me it didn't | ||
| zacque | Huh? Can you elaborate further? You've got a different result with `lazy`? | ||
| gfldex | m:``` | ||
| my \pascal = (1,), (1,1), -> @a { 1, |(@a «+» (|@a[1..*], 0)) } … *; | |||
| say pascal[^10]; | |||
| ``` | |||
| Nemokosch | yep | 10:30 | |
| I did this | 10:31 | ||
| zacque | Ah, I see. Thanks for showing your code | ||
| Mine still not working even with `lazy`. paste.debian.net/1255516/ | |||
| Guess I should use your approach | 10:32 | ||
| Nemokosch | [^4] seems to be too eager | 10:33 | |
| zacque | I think it works with `@pascal` as well, is there a specific reason that you use `\pascal`? | ||
| What do you mean? | |||
| Nemokosch | tbh I don't know how to properly use this lazy mess but if you iterate it, you can see the results popping out one after the other | 10:34 | |
| I replaced your @pascal[^4] line to | 10:35 | ||
| ```perl | |||
| .say for @pascal; | |||
| ``` | |||
| and then the right results were indeed popping out | |||
| zacque | Yes indeed, together with the `lazy` keyword | 10:37 | |
| Nemokosch | yep | ||
| docs.raku.org/language/list#index-...le_objects I'm reading this rn | |||
| zacque | Hmmm, that's so confusing right now | 10:38 | |
| I don't think it helps? | 10:39 | ||
| Nemokosch | not detailed enough... | ||
| right | |||
| There is one thing I feel we need to know | |||
| zacque | What's it? | ||
| Nemokosch | are the elements of the lazy list still the very same element multiple times, or not | ||
| because if they are, it's inevitable that once we fetch more at once, it will always have the same value | 10:40 | ||
| zacque | I guess it is the same variable? If not, it won't be lazy 😂 | 10:41 | |
| gfldex | `lazy` sneaks another `Seq` in that decontainerises the values in `@k`. When assigned to the Array, fresh containers are being filled with values. | ||
| Nemokosch | <@511826957558611968> | ||
| ```perl | 10:42 | ||
| my @pascal = lazy (pascal-sequence $rows); | |||
| say @pascal[0]; | |||
| say @pascal[0].WHERE; | |||
| say @pascal[1]; | |||
| say @pascal[1].WHERE; | |||
| say (pascal-sequence $rows); # OUTPUT: ([1] [1 1] [1 2 1] [1 3 3 1] [1 4 6 4 1]) | |||
| ``` | |||
| so yes | |||
| it's the very same variable retrieved in multiple states | 10:43 | ||
| okay, now, this makes it fairly obvious why retrieving a part of the list will contain the same value | |||
| as gfldex pointed out with his very first code example (calling .clone), your array doesn't have copies | 10:44 | ||
| it has the same variable over and over | |||
| zacque | Can I know why does it matter? | 10:45 | |
| This is a bit over my head right now | |||
| I see, didn't know about `WHERE` before this | |||
| Let me see what if without the `lazy` keyword? | |||
| Nemokosch | it will be the same pretty sure, except the values will match | 10:46 | |
| gfldex | `return @k` doesn't return the values in `@k` but `@k` itself. You keep overwriting the values in `@k`, so you end up with the values of the very last overwriting. | 10:47 | |
| Nemokosch | okay, thankfully we are saying the same thing with different words | ||
| zacque | Okay, I see, I've tried it out myself | ||
| Nemokosch | so you don't have to understand two things at once but one thing twice 😄 | ||
| zacque | Okay, so `take @k` here behaves similarly to `return @k`? | 10:48 | |
| Does it apply to all container variables? Or is it a special case? | 10:49 | ||
| So, when I'm passing a `@var` around, I'm passing the reference around? | |||
| Kaiepi | `take` behaves like `return` wrt containers | ||
| Nemokosch | From what I know, something that has an Array _container_ (like @-sigilled vars by default), cannot just drop that container | 10:50 | |
| gfldex | `take @k[]:v;` works too and might be faster as a `.clone`. The zen slice with `:v` also removes any holes. | ||
| Nemokosch | I noticed a gotcha | 10:52 | |
| m: my @k = <blah foo bar>; @k =:= @k[]:v andthen .say; | |||
| weird parsing as I clearly meant (@k[]:v) | |||
| my @k = <blah foo bar>; @k =:= (@k[]:v) andthen .say; | 10:53 | ||
| <@511826957558611968> =:= will be useful, trust me | 10:54 | ||
| it's the container equivalence | |||
| zacque | I'll pass `:v` for now, thanks you for your time and effort 😄 | ||
| It looks weird... 😄 | |||
| Nemokosch | ie "are these two things the same one thing" | ||
| m: my @k = <blah foo bar>; @k =:= (@k[]:v) andthen .say; | |||
| no, they aren't - thank heavens, in this case | |||
| zacque | Ah, it's the container identity operator, so it checks whether two "references" are equal | 10:56 | |
| Nemokosch | yes, basically | ||
| zacque | I don't think it helps in this case either | ||
| But glad to learn about it | |||
| Nemokosch | it helps to know if you have the "same variable" over and over | ||
| let me take your original code again | |||
| zacque | How is `=:=` different from `===` wrt container? Some experiment shows that they are the same? See: | 10:58 | |
| ```raku | |||
| [0] > (1,2,3) =:= (1,2,3) | |||
| False | |||
| [1] > (1,2,3) === (1,2,3) | |||
| False | |||
| [2] > my @foo = (1,2,3); | |||
| [1 2 3] | |||
| [3] > @foo =:= @foo | |||
| True | |||
| [4] > @foo === @foo | |||
| True | |||
| [5] > @foo === (1,2,3) | |||
| False | |||
| ``` | |||
| Nemokosch | the difference is that === says true if you drop the container on one side | 10:59 | |
| while =:= would say false to that | 11:00 | ||
| zacque | Erm, is there an example for that? I don't know how to "drop the container" | ||
| Nemokosch | in fact, I suspect === always drops the container | ||
| yes, your code is a perfect example | |||
| ```perl | |||
| sub MAIN(Int:D $rows where $rows >= 3) { | |||
| my @pascal = (pascal-sequence $rows); | |||
| say [===] @pascal; | |||
| say @pascal[^$rows]; # OUTPUT: [[1 4 6 4 1] [1 4 6 4 1] [1 4 6 4 1] [1 4 6 4 1] [1 4 6 4 1]] | |||
| say (pascal-sequence $rows); # OUTPUT: ([1] [1 1] [1 2 1] [1 3 3 1] [1 4 6 4 1]) | |||
| } | |||
| ``` | |||
| it will say True | |||
| I wish I could phrase what happened here xD | 11:02 | ||
| zacque | It's okay! I know about `[]`! | ||
| It's the `reduce` operator | |||
| Nemokosch | that helps | ||
| but there is more... | |||
| so @pascal wraps the same Array container into different Scalar containers | |||
| zacque | So, it shows that every element are in fact the same container | ||
| Nemokosch | if you assign to @pascal[0], that won't be reflected in @pascal[1] | ||
| because they are put into different Scalar containers | |||
| you can even try that | |||
| zacque | I don't follow here... | 11:03 | |
| Nemokosch | I mean, understandable, I've been spending more than one year | 11:04 | |
| zacque | What's the deal with Scalar containers? | ||
| Nemokosch | to kinda sorta understand variables | ||
| zacque | Ah, scalar container is a catch indeed | ||
| Nemokosch | let's wait for Kaiepi | ||
| zacque | The doc says it won't get flatten | ||
| But, but, but they have the same value?? | 11:06 | ||
| 🤦♂️ | |||
| Nemokosch | it's like the containers are nested | ||
| there is an item of the array, and that item contains an array | |||
| the items don't match, the underlying arrays do match | |||
| zacque | Ya, I get this, `pascal-sequence` returns a (lazy?) array of list | ||
| Nemokosch | =:= will say false for the items | ||
| === will say true because it drops the scalar container and finds the array | 11:07 | ||
| zacque | Then when I assign `pascal-sequence` to `@pascal` it will be coerced to `array` type | 11:08 | |
| Kaiepi | `my @pascal = ...` makes an empty `Array`, then assigns to fresh `Scalar` containers within this for each element in `pascal-sequence`'s `gather` (`Seq`) | ||
| it does this eagerly because the `gather` isn't `lazy` | |||
| if you assign an array, it copies from the containers within that | |||
| zacque | Okay, so an array assignment to an array performs an implicit iteration? Makes sense... | 11:10 | |
| Nemokosch | array assignment calls .STORE | ||
| zacque | If eager I meant | ||
| Nemokosch | by definition | ||
| Kaiepi | neat thing is if you assign a lazy iterable to an array, consume some values, then assign that to another array, it preserves any laziness left | ||
| zacque | But the state remains right? Make sense... | ||
| I meant it'll follow from last "consumption" | 11:11 | ||
| Kaiepi | yeah | ||
| zacque | But I still don't get the "different Scalar containers" part | ||
| Nemokosch | I'm describing it, hold on | 11:12 | |
| zacque | Ok, thanks | ||
| Nemokosch | pls <@210313526928080896> also hold on in case I mess something up big time 😅 | ||
| Kaiepi | ok 😛 | ||
| zacque | Please take your time! Gtg, I'll be right back in about an hour... | 11:13 | |
| Nemokosch | 1. `my @pascal = ...` this is an "array assignment, hence calling STORE with the content on the right handside | 11:14 | |
| 2. because the rhs wasn't explicitly marked lazy, the content is traversed eagerly | |||
| 3. the content is some Iterable that consists of the very same Array container over and over again (let me call this `gathered` | |||
| 4. STORE allocates Scalar containers, the elements of the @pascal array | |||
| 5. as it traverses `gathered`, it puts the elements of it (which are the same Array container over and over) into the Scalar containers | |||
| 1. `my @pascal = ...` this is an "array assignment, hence calling STORE with the content on the right handside | |||
| 2. because the rhs wasn't explicitly marked lazy, the content is traversed eagerly | |||
| 3. the content is some Iterable that consists of the very same Array container over and over again (let me call this `gathered`) | |||
| 4. STORE allocates Scalar containers, the elements of the @pascal array | |||
| 5. as it traverses `gathered`, it puts the elements of it (which are the same Array container over and over) into the Scalar containers | |||
| so you end up with | 11:15 | ||
| @pascal - an Array container on top | |||
| the elements of @pascal - Scalar containers that you can mutate | |||
| the current contaent of the elements - the same one Array container (for all elements) | |||
| so you end up with | |||
| @pascal - an Array container on top | |||
| the elements of @pascal - Scalar containers that you can mutate | |||
| the current content of the elements - the same one Array container (for all elements) | |||
| Kaiepi | pretty much | 11:18 | |
| repeated `STORE`s clobber any existing containers within the array, but the wrapper remains | |||
| Nemokosch | also, from what I understand (and iirc lizmat told me this), Arrays can not be decontainerized | 11:21 | |
| Kaiepi | the `Array` is the container and the value | ||
| Nemokosch | they are like bundled | ||
| a mnemonic/mental aid to it: Scalars do have one identity while Arrays are inherently divided into pieces | 11:25 | ||
| I always imagine something like this for an array: | |||
| (array as in the container) | |||
| lizmat | note you *can* put an Array into a container | 11:26 | |
| but it will be considered a single object like any other object in a container | |||
| m: my $a = [1,2,3]; .say for $a | |||
| camelia | [1 2 3] | ||
| Nemokosch | a grid is made a grid by its cells, it's not a thing on its own | 11:27 | |
| - unless, of course, you put the whole thing into a Scalar container 😄 | |||
| okay, you were faster 😛 | |||
| lizmat | :-) | ||
| Nemokosch | the more time you spend with it, the more logically sound it becomes | 11:29 | |
| but a thorough demostration of it is still on my wanted list | 11:31 | ||
| yes, I know that article and it did help | |||
| but still, "more more more" | |||
| zacque | Hang on, let me digest your messages 😄 | 12:15 | |
| Okay, so without `lazy`, the RHS (`gathered`) is evaluated eagerly by calling `STORE` on it. `STORE` constructs an `Array` of `Scalar` elements. In this case, the `Scalar` elements are actually `Array` elements (containing other `Scalar` elements), so the result is an `Array` of `Scalar` `Array` of `Scalar` something. Finally, this result is assigned to the variable `@pascal`. | 12:29 | ||
| Ermm, so each of the `Scalar` elements in an `Array` has unique identity? That's why you said it's "different Scalar containers" | 12:31 | ||
| Nemokosch | I think you are on the right track | ||
| zacque | So, that why I got this: ```raku | ||
| sub MAIN(Int:D $rows where $rows >= 3) { | |||
| my @pascal = (pascal-sequence $rows); | |||
| say [===] @pascal; # Output: True | |||
| say [=:=] @pascal; # Output: False | |||
| } | 12:32 | ||
| ``` | |||
|
12:55
saint- joined
13:36
razetime_ left
13:50
razetime joined
14:54
jgaz joined
17:00
razetime left
19:24
jgaz left
20:54
sivoais left,
sivoais joined
22:16
MasterDuke joined
|
|||