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 ```
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";
```
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