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. |
|||
03:14
Kaipei joined
03:16
Kaiepi left
06:43
discord-raku-bot left,
discord-raku-bot joined
|
|||
yabobay | i'm doing the raku guide, and i'm at the "purchase table" exercise, and i entered this code: | 07:14 | |
``` | |||
my $chair'price = 20.57; | |||
my $chair'quant = 4; | |||
my $chair'total = $chair'price * $chair'quant; | |||
my $table'price = 50.18; | |||
my $table'quant = 1; | |||
my $table'total = $table'price * $table'quant; | |||
my $currency = '€'; | |||
print ( | |||
"Item\tPrice\tN\tTotal\n", | |||
"Chairs\t$currency$chair'price\t$chair'quant\t$currency$chair'total\n", | |||
"Tables\t$currency$table'price\t$table'quant\t$currency$table'total\n", | |||
); | |||
``` | |||
the output looks like this: | |||
``` | |||
Item Price N Total | |||
Chairs €20.57 4 €82.28 | |||
Tables €50.18 1 €50.18 | |||
Nemokosch | in Python, space separates arguments of print. Wouldn't be surprised if it was the same case | 07:15 | |
yabobay | doesn't look like it | 07:16 | |
Nemokosch | wait wait wait | 07:18 | |
you pass one argument to print | |||
yabobay | no i don't | ||
Nemokosch | yes you do | ||
a list | |||
this is a stringified list | |||
and lists are stringified with a bare space separator | |||
yabobay | because of the parentheses? | ||
Nemokosch | because of the random space in front of it | 07:19 | |
yabobay | no i mean.. it's a list because i used parentheses in the code? | 07:20 | |
Nemokosch | that's what I say | ||
the parens could be fine - without the space in front of the opening paren | |||
yabobay | ``` | ||
"Item\tPrice\tN\tTotal\n", | |||
"Chairs\t$currency$chair'price\t$chair'quant\t$currency$chair'total\n", | |||
"Tables\t$currency$table'price\t$table'quant\t$currency$table'total\n"; | |||
``` | |||
i'm doing it like this now | |||
ohh i get it now. thank you | |||
Nemokosch | this is a "gotcha" but eventually it does make sense I think | ||
parentheses have too many meanings | |||
so `function-call (blah1, blah2)` could be ambiguous | 07:21 | ||
the resolution is: it's considered one list argument | 07:22 | ||
while `function-call(blah1, blah2)` or `function-call blah1, blah2` are two arguments | |||
yabobay | thats kinda fun | ||
Nemokosch | The grammar of Raku is quite sophisticated and therefore whitespaces can make the difference | 07:24 | |
this is probably the most basic case where they do | |||
while we are at it... | |||
I think it's better to learn this on time | |||
brackets don't actually complement semicolons, they don't make a statement | |||
the reason why we can usually pretend that they do is | |||
a closing bracket AND A NEWLINE do make a block | 07:25 | ||
yabobay | i don't understand what you mean | ||
Nemokosch | moment | ||
m: class Foo {} say 'Bar' | 07:26 | ||
<@853712446660673566> hello? wakey wakey rise and shine | |||
anyway, you can run this in the REPL as well | |||
THANK YOU | |||
yabobay | i don't know class syntax yet, what is this code supposed to do? | 07:27 | |
ohhh i get it | |||
Nemokosch | well, be syntactically valid | ||
but it's not | |||
because } in itself didn't finish the statement | 07:28 | ||
you'd need the semicolon | |||
yabobay | but if it was | ||
``` | |||
class Foo{} | |||
say 'Bar'; | |||
``` | |||
is valid? | |||
Nemokosch | yep | ||
or `class Foo {}; say 'Bar'` | |||
yabobay | thats pretty strange | ||
Nemokosch | I think this is good to be aware of | 07:29 | |
`}` didn't finish a statement, however, `}\n` does | 07:30 | ||
`}` doesn't finish a statement, however, `}\n` does | |||
Again, this is not something that would often concern you | |||
but if you ever write something like | |||
```perl | 07:31 | ||
(2 .. 10) | |||
.map: { $_ ** $_ } | |||
andthen .say | |||
``` | |||
and wonder why doesn't work | |||
yabobay | i dont even know what im looking at | 07:32 | |
Nemokosch | well, let's see the output, I'm gonna escape the linebreak | ||
m: ```(2 .. 10) | 07:33 | ||
.map: { $_ ** $_ }\ | |||
andthen .say | |||
``` | |||
this should run I think | |||
damn, it ate the backticks | |||
it should say | 07:35 | ||
``` | |||
(4 27 256 3125 46656 823543 16777216 387420489 10000000000) | |||
``` | |||
yabobay | what am i doing wrong in <#619193814653075477> ? | 07:37 | |
Nemokosch | <@989550365533937664> what is your programming background, if I may ask? | 07:48 | |
07:50
discord-raku-bot left,
discord-raku-bot joined
|
|||
yabobay | basically none | 08:08 | |
08:09
dakkar joined
|
|||
Nemokosch | haha, it just makes it more exciting 🥺 | 08:10 | |
yabobay | or it depends what you mean background | ||
i've done many very small things for fun | |||
but i dont think i really "know" any of the languages | |||
Nemokosch | it made me wonder why you tried to write a C-style for loop with the for keyword | 08:12 | |
and you know, in general, it's good to know what comparisons can be made | |||
yabobay | cause i have spent the most amount of time writing in languages that have for loops like that | ||
so `loop` in raku is for writing those kinds of loops? | 08:14 | ||
08:19
dakkar left
08:20
dakkar joined
|
|||
Nemokosch | yes | 08:48 | |
but it's really better to get used to the foreach approach | 08:49 | ||
or map, even 😂 | |||
m: m: for 1 .. 10 -> $i { say $i } | 08:50 | ||
there is more: topic variable ($_) is set if you don't specify otherwise | 08:51 | ||
m: m: for 1 .. 10 { say $_ } | |||
oops | |||
m: for 1 .. 10 { say $_ } | |||
Nahita | yeah i think `loop` is only good practice for infinite loops... `loop { ... }` | ||
Nemokosch | okay I guess :DD | ||
... but there is even more: say is available as a method and you can make method calls on the topic variable without typing it out | 08:53 | ||
m: for 1 .. 10 { .say } | |||
lizmat | m: for 1..10 { .say } | 09:06 | |
camelia | 1 2 3 4 5 6 7 8 9 10 |
||
lizmat | m: .say for 1..10 | ||
camelia | 1 2 3 4 5 6 7 8 9 10 |
||
yabobay | is `for` just better because it's shorter to do? | 09:08 | |
Nemokosch | it expresses the idea more clearly and it doesn't expose mutation unneecessarily | 09:12 | |
yabobay | expose mutation? | 09:13 | |
Nemokosch | well, if you set a variable by hand, that's quite heavyweight mutation, no? | 09:14 | |
yabobay | what is mutation? | ||
lizmat | m: my $a = 42; say $a; $a = 666; say $a # $a got mutated from 42 to 666 | 09:17 | |
camelia | 42 666 |
||
Nemokosch | where are you from, if I may? | 09:18 | |
umm... changing-ish? | |||
except with Romance vocabulary | |||
yabobay | so mutation is changing variables? | ||
Nemokosch | basically | 09:23 | |
changing values behind adressable content, I would say | 09:24 | ||
so like assigning to an element of an array also classifies | |||
yabobay | addressable? | 09:26 | |
and why is it a problem? | |||
man i feel like an idiot | 09:28 | ||
Nemokosch | it's just harder to maintain code like that, at this point | ||
Nahita | me too; i don't know how `for` vs `loop` discussion ended up in container stuff | 09:30 | |
gfldex | It always ends in container stuff. :-> | ||
Nahita | my summary is: we write `for` because it's easier to type, it's shorter, it's more idiomatic, more powerful; only using `loop` for infinite loops | ||
in my opinion | |||
yabobay | why not just use while(True) for infinite loops | 09:31 | |
why not just use while (True) for infinite loops | |||
lizmat | yabobay that works too in Raku | ||
Nahita | it's uglier than `loop { ... }` i think :p | ||
lizmat | m: my $a; while True { last if ++$a == 5; say $a } | 09:32 | |
camelia | 1 2 3 4 |
||
yabobay | do you just write loop { } to make an infinite loop? | ||
without conditions and stuff? | |||
Nahita | yeah | ||
yabobay | what happens if someone tells raku bot to do an infinite loop | 09:33 | |
Nemokosch | it will timeout | 09:34 | |
pretty sure | |||
yabobay | ohh ok | 09:35 | |
Nahita | m: loop {} | ||
yabobay | i remember trying to learn perl 5 a while ago, does last mean break? i think i remember that being the case | ||
Nahita | yeah but it is `last` in Perl too | ||
yabobay | i dont like that decision tbh. cause i'ts not a verb | ||
Nemokosch | bang bang bang 😂 | 09:37 | |
you do have a point though | |||
yabobay | i guess "break" isn't exactly clear on what it means, but in that case, you could've had "stop" or something | ||
and "skip" for continue | 09:39 | ||
and then you have skip and stop which sounds really nice as well | |||
and because it sounds nice, it's easy to remember | |||
Nemokosch | skip does exist as a method for ?positionals? I think | 09:41 | |
m: (1, 2, 3, 5).skip.say | |||
yabobay | oh so you can't have the keyword | ||
what are positionals? | |||
Nemokosch | well you could, it would work | ||
I'm just saying that there is a thing called `skip` indeed | |||
yabobay | what does it do? | ||
Nemokosch | Positionals are everything you can index with natural numbers | ||
yabobay | im confused | 09:42 | |
Nemokosch | what do you think it does? 🙂 | 09:43 | |
yabobay | it removes the first one? | ||
from a list that is passed to it | |||
also i realise i'm breaking the rule of not posting too many messages as part of the same thought but i'm really bad with that and i keep thinking things to append | |||
Nemokosch | whatever, this is just a chat | 09:45 | |
well, yes, "removes" | 09:46 | ||
yabobay | returns a different list with all the elements shifted to the left :p | 09:47 | |
Nemokosch | yes, or from what I can see, a Sequence | ||
Sequences can be lazy | |||
and infinite 😼 | |||
yabobay | i should really read more about raku before i keep saying things here haha, cause i don't know anything | ||
i was interested cause it sounded like fun, and then the website says it's fun, and then i try it and it turns out that it is fun indeed | |||
Nemokosch | 😂 | 09:49 | |
It's a long journey imo | |||
Shameless plug: conf.raku.org/ I also had a presentation about my first year with Raku | |||
it was the first presentation actually 😁 | |||
yabobay | that's pretty cool | 09:51 | |
i wish i used raku for a year+ | |||
or any language for that matter | |||
i keep going "ooh shiny!" and doing something else | |||
so at the end of the day i end up not knowing anything about anything | |||
gfldex | `for` demands an iterable thing. We got `loop` because somethimes we have to handle the iteration and stop-condition by hand. | 09:52 | |
m:``` | 09:55 | ||
for ^5 { | |||
last if True; | |||
.say; | |||
CONTROL { when CX::Last { say .^name } } | |||
} | |||
``` | |||
Sadly, `CX::Last` is not resumable. Or I could write a mightily confusing example of the usage of `last`. :-> | 09:58 | ||
Nemokosch | do you think this wasn't confusing enough? | 09:59 | |
gfldex | aye :) | ||
And I do believe the confusion isn't the student but the teacher fault. If you know what the compiler does, everything becomes clear. That is hardly surprising, because CPUs are dumb as fuck. Yet we manage to explain Raku to it. | 10:00 | ||
yabobay | if it says "last if True" then how come the loop does anything at all | 10:01 | |
i get that it's got something to do with the CONTROL part but i don't know what any of that is and i should probbly stop asking thinsg | 10:02 | ||
gfldex | Because `last` isn't just a conditional `jmp`. | ||
Nemokosch | anyway, this does seem inconsistent | 10:03 | |
yabobay | what is jmp? (i really ought to stop talking and just go read the manual lol) | ||
gfldex | see: github.com/rakudo/rakudo/blob/mast...l.pm6#L108 | ||
Nemokosch | you didn't do anything to "handle" last, hence it should have succeeded | 10:04 | |
like with exceptions | |||
just logging something about them won't stop them from exploding | |||
gfldex | We need to `.resume` control exceptions to negate their meaning completely. | ||
Nemokosch | yes, and this should be just like that | ||
gfldex | Also, there is sink context going on. | 10:05 | |
Nemokosch | just subscribing to them shouldn't keep the loop running, unless one wants to create confusion | 10:06 | |
gfldex | m:``` | ||
say do for ^5 { | |||
last(42) if True; | |||
.say; | |||
CONTROL { when CX::Last { say .^name; .resume } } | |||
} | |||
``` | |||
As soon as we remove sink context, the compiler doesn't want to cheat anymore and allows us to `.resume`. | |||
Nemokosch | it needs 6.e | ||
yabobay | what is happening aaa | ||
gfldex | m:``` | ||
use v6.*; | |||
say do for ^5 { | |||
last(42) if True; | |||
.say; | |||
CONTROL { when CX::Last { say .^name; .resume } } | |||
} | |||
``` | |||
Nemokosch | do you know `return`? | 10:08 | |
yabobay | yes | ||
unless it means something different in raku | |||
gfldex | <@989550365533937664> what happens here, is the Raku exposes structures the compiler uses internally to do it's magic. Often, we can borrow that magic to gain superpowers. | ||
Nemokosch | `return` can take a value | ||
and eventually `last` will also be able to take a value | |||
coming in v6.e | 10:09 | ||
the rest is very much phaser magic for me as well | 10:10 | ||
yabobay | what will giving last a value do? | ||
Nemokosch | return from the loop with that value | 10:12 | |
all blocks can have return values | |||
you can even assign them to a variable with `do` | |||
yabobay | so i can like | ||
i dont know how to do this syntactically but like | |||
say ( {return "hello"} ) | |||
that's definitely wrong | |||
but like the idea of that | |||
Nemokosch | almost | ||
gfldex | `for` basically maps to `map`, outside of sink-context. `last` with a value is meant to be used with `map`. | ||
Nemokosch | return only exists in subs, not code blocks | ||
but yeah, `{ "hello" }` in itself is a banal code block | 10:13 | ||
that gives "hello" upon execution | 10:14 | ||
yabobay | aaaaaa | ||
Nemokosch | see, it is a block 😄 | ||
yabobay | but it didn't do the thing i thought it was supposed to do | ||
Nemokosch | because you haven't executed it | ||
yabobay | ohhh | 10:15 | |
gfldex | m: (40,41,'answer',43) .map({ last(42) if .contains('answer'); say "It's not $_."; Empty }).say; | ||
yabobay | it's literally telling me the block | ||
i figured it out | 10:16 | ||
gfldex | m:``` | ||
use v6.*; | |||
(40,41,'answer',43) .map({ last(42) if .contains('answer'); say "It's not $_."; Empty }).say; | |||
``` | |||
Nemokosch | well done 🍬 | ||
yabobay | that's a pretty cool thing | ||
it reminds me of when i tried to do emacs lisp and failed miserably | |||
Nemokosch | talking about code blocks | 10:19 | |
as you might suspect now, map received a code block | 10:20 | ||
and the `last` inside actually stops the loop of `map` | |||
now I wonder | 10:23 | ||
yabobay | i think i like, half- get it | 10:24 | |
Nemokosch | m: | ||
```use v6.*; | |||
(40,41,'answer',43) .map({ next(42) if .contains('answer'); say "It's not $_."; Empty }).say;``` | |||
will `next` also get a return value? | |||
come ooon | |||
yabobay | oHHH im starting to actually get what it does | ||
Nemokosch | <@195453211409121280> how do you do it? 🥺 | ||
map kinda mimics a for loop that collects values inside a Sequence | 10:26 | ||
unlike in many other languages, it doesn't even demand a 1-to-1 correspondence between input items and produced output elements | 10:27 | ||
that is, it can give multiple values or even none, per item | |||
now I expect the one with `next` to say | 10:28 | ||
It's not 40. | |||
It's not 41. | |||
It's not 43. | |||
(42) | |||
m: | 10:29 | ||
use v6.*; | |||
(40,41,'answer',43) .map({ next(42) if .contains('answer'); say "It's not $_."; Empty }).say; | |||
🥳 | |||
(42) is a one-element sequence: the output of map | 10:30 | ||
only 'answer' generated data, the others gave Empty | |||
yabobay | so if there are two iterations where you call next, does that mean you get a 2 element sequence? | 10:41 | |
Nemokosch | remember: `next` is "continue" | 10:45 | |
in this example, if you don't "continue", you end up with Empty | |||
so within the scope of this code, if you don't call `next`, you don't get elements | 10:46 | ||
but it could easily be the other way around | 10:47 | ||
yabobay | i really should just get learning | ||
Nemokosch | I will sort out even numbers using map and next: | ||
Kaiepi | `for` is `map` in Rakudo | ||
Nemokosch | m: | ||
<1 5 2 4 8 5 6 7>.map({ next if $_ %% 2; $_ }).&dd | |||
it's funny that it's not the other way around | 10:49 | ||
m: | 10:50 | ||
<1 5 2 4 8 5 6 7>.map({ next if $ %% 2; $ }).say | |||
oh right, it ate my underscores | |||
m: | 10:51 | ||
<1 5 2 4 8 5 6 7>.map({ next if $_ %% 2; $_ }).say | |||
^ so yeah, same thing, without the scare debug-ish output | 10:53 | ||
Kaiepi | m:``` | 10:55 | |
put (do for ^5 { $_ }) eqv (eager map { $_ }, ^5); | |||
put (-> { for ^5 { } })() eqv (-> { sink map { $_ }, ^5 })(); | |||
``` | |||
m:``` | 10:56 | ||
put (do for ^5 { $_ }) eqv (eager map { $_ }, ^5); | |||
put (-> { for ^5 { $_ } })() eqv (-> { sink map { $_ }, ^5 })(); | |||
``` | |||
Nemokosch | is it === tho | 10:57 | |
Kaiepi | `===` is the `WHICH`-y one. i don't tend to use it because it's an `Any` operator | 10:58 | |
m:``` | 10:59 | ||
put (do for ^5 { $_ }) === (eager map { $_ }, ^5); | |||
put (-> { for ^5 { $_ } })() === (-> { sink map { $_ }, ^5 })(); | |||
``` | |||
Nemokosch | hmmm | 11:01 | |
Kaiepi | m:``` | ||
say @(^5) === @(^5) | |||
``` | |||
depending on which kind of `WHICH` a `List` has, it might not work | |||
Nemokosch | okay but how does eqv work? it would simply give `True` on the same content, right? | 11:02 | |
which we anticipate | |||
(why not *ante*cipate though, it happens _before_, not _against_ ) | 11:04 | ||
Kaiepi | i think of `eqv` as a stricter `~~`. they can both recurse over themselves, just in the case of a typecheck, `eqv` is invariant instead of covariant like `~~` | 11:06 | |
in the case of an `Iterable:D` like this, it looks to be a reduction of a zipped `eqv` | 11:08 | ||
that leaves `eqv` on `Int:D`, which is a numeric comparison + invariant typecheck | |||
that's another thing - it takes the type into account usually | |||
that's another thing - it takes the type into account strictly usually | |||
gfldex | <@297037173541175296> outside of sink-context, `for` is actually replaced by github.com/rakudo/rakudo/blob/mast...s.pm6#L885 | 11:34 | |
Nemokosch | <@989550365533937664> don't ever fear that you'll have nothing to learn about Raku in a few months 😅 it's way too big for that | 11:37 | |
but I like how the source is mostly Raku | |||
gfldex | m:``` | 11:39 | |
class C { method map(|) { put ‚custom map‘ } } | |||
do for C.new { } | |||
``` | |||
unless the object implements it's own `.map` | |||
yabobay | yeah but at the moment i have *every* thing to learn about raku | 11:55 | |
Nemokosch | Do the weekly challenges 😛 they are usually very doable | 11:57 | |
yabobay | 1. weekly challenges? | ||
2, i am doing the "raku essentials" thing right now | |||
just very slowly | 11:58 | ||
cause i'm telling myself i should be doing homework, but i don't do that either. so i end up making no progress in either thing | |||
Nemokosch | theweeklychallenge.org/ | ||
yabobay | that's interesting | 11:59 | |
i noticed perl & raku are very community-ish | |||
gfldex | That `do for` calles `.map` is an ENODOC. :-/ | 12:01 | |
Kaiepi | i'm not sure how much of `for`/`map` is spec and how much is rakudo implementation detail offhand | 12:08 | |
implementation details are documentable, just brittle | |||
yabobay | this is very fun | 12:10 | |
Kaiepi | `do ... for` *is* eager and an iteration of sorts, so it could at least hint that they should generate comparable values | ||
`do ... for` *is* eager and an iteration of sorts, so it could at least hint that they should generate comparable results | |||
stevied | I got a windows 11 machine up and running. I'm not a windows guy. But I want to test a module directly on windows. But I can't seem to get `run` command to work at all. | 13:12 | |
`say run('ls')` throws an error | |||
`say run('dir') also throws an error` | |||
`say run('dir')` also throws an error | 13:14 | ||
Nemokosch | good for you - I didn't manage to get rakubrew working on Windows 10 at all | 13:31 | |
stevied | I got errors with rakubrew | 13:32 | |
i installed the binary | |||
rakubrew is now working for me and installing new raku builds. just tested it | 13:49 | ||
Nemokosch | good for you... | 13:56 | |
stevied | I think installing the binary must have configured things properly. Not sure though. | 13:57 | |
Nemokosch | I don't know | ||
For me, it fails while extracting the release | |||
16:36
dakkar left
19:23
n1to joined
21:21
n1to left
|