1
1
= begin pod :kind("Language") :subkind("Language") :category("beginning")
2
2
3
- = TITLE Raku by example P6- 101
3
+ = TITLE Raku by example 101
4
4
5
5
= SUBTITLE A basic introductory example of a Raku program
6
6
@@ -29,20 +29,15 @@ Here's one way to solve that problem in Raku:
29
29
= begin code :solo
30
30
use v6;
31
31
32
- # Single line comments like this one start with '#'.
33
- my $file = open 'scores.txt'; # Comments can also follow code on a line.
34
- my @names = $file.get.words;
32
+ # start by printing out the header.
33
+ say "Tournament Results:\n";
34
+
35
+ my $file = open 'scores.txt'; # get filehandle and...
36
+ my @names = $file.get.words; # ... get players.
35
37
36
38
my %matches;
37
39
my %sets;
38
40
39
- #`( Multiple line comments
40
- are denoted by a #, then `, then one of {,[, or (
41
- and closed by the corresponding },], and ).
42
- Nested pairs of square brackets, curly braces and
43
- parentheses are matched, so
44
- something like this () will not end the comment.
45
- In this case, closed by: )
46
41
for $file.lines -> $line {
47
42
next unless $line; # ignore any empty lines
48
43
@@ -60,9 +55,6 @@ for $file.lines -> $line {
60
55
}
61
56
}
62
57
63
- #`[
64
- This is another multi-line comment. ]
65
- #`{ So is this, though it's not actually multi-line. }
66
58
my @sorted = @names.sort({ %sets{$_} }).sort({ %matches{$_} }).reverse;
67
59
68
60
for @sorted -> $n {
@@ -74,37 +66,55 @@ for @sorted -> $n {
74
66
75
67
This produces the output:
76
68
77
- = for code :lang<text>
69
+ = begin code :lang<text>
70
+ Tournament Results:
71
+
78
72
Ana has won 2 matches and 8 sets
79
73
Dave has won 2 matches and 6 sets
80
74
Charlie has won 1 match and 4 sets
81
75
Beth has won 1 match and 4 sets
76
+ = end code
82
77
83
- = head3 X < C < v6 > |v6 (Basics)>
78
+ = head1 Pragma X < C < v6 > |v6 (Basics)>
79
+
80
+ = begin code
81
+ use v6;
82
+ = end code
84
83
85
84
Every Raku program should begin with a line similar to C < use v6; > . This line
86
85
tells the compiler which version of Raku the program expects. For instance,
87
86
6.c is an example of a Raku version. Should you accidentally run the file
88
87
with Perl, you'll get a helpful error message.
89
88
90
- = head3 X < C < statement > |statement (Basics)>
89
+ = head1 X < Statements|statement (Basics) >
90
+
91
+ = begin code
92
+ # start by printing out the header.
93
+ say "Tournament Results:\n";
94
+ = end code
91
95
92
96
A Raku program consists of zero or more statements. A I < statement > ends with
93
- a semicolon or a curly brace at the end of a line:
97
+ a semicolon or a curly brace at the end of a line.
98
+
99
+ In Raku, single line comments start with a single hash character C < # > and
100
+ extend until the end of the line. Raku also supports
101
+ L < multi-line/embedded comments|/language/syntax#Multi-line_/_embedded_comments > .
102
+ The compiler doesn't evaluate comments as program text and they're only intended
103
+ for human readers.
104
+
105
+ = head1 X < Lexical scope|my (Basics) > and X < block >
94
106
95
107
= begin code
96
108
my $file = open 'scores.txt';
97
109
= end code
98
110
99
- = head3 X < C < lexical > > and X < C < block > >
100
-
101
111
C < my > declares a lexical variable, which are visible only in the current block
102
112
from the point of declaration to the end of the block. If there's no enclosing
103
113
block, it's visible throughout the remainder of the file (which would
104
114
effectively be the enclosing block). A block is any part of the code enclosed
105
115
between curly braces C < { } > .
106
116
107
- = head3 X < C < sigil > > and X < C < identifier > |identifier (Basics)>
117
+ = head2 X < Sigils|sigils (Basics) > and X < identifiers|identifiers (Basics)>
108
118
109
119
A variable name begins with a I < sigil > , which is a non-alpha-numeric
110
120
symbol such as C < $ > , C < @ > , C < % > , or C < & > E < mdash > or occasionally the double
@@ -115,7 +125,7 @@ consist of letters, digits and the underscore. Between letters you can
115
125
also use a dash C < - > or an apostrophe C < ' > , so C < isn't > and
116
126
C < double-click > are valid identifiers.
117
127
118
- = head3 X < C < scalar > >
128
+ = head2 X < Scalar| scalar (Basics) >
119
129
120
130
Sigils indicate the default access method for a variable. Variables
121
131
with the C < @ > sigil are accessed positionally; variables with the C < % >
@@ -126,25 +136,25 @@ C<Array> or a C<Hash>; the C<$> sigil signifies that it should be
126
136
treated as a single value, even in a context that expects multiple
127
137
values (as with an C < Array > or C < Hash > ).
128
138
129
- = head3 X < C < filehandle > > and X < C < assignment > >
139
+ = head2 X < Filehandle| filehandle (Basics) > and X < assignment|assignment (Basics) >
130
140
131
141
The built-in function C < open > opens a file, here named C < scores.txt > ,
132
142
and returns a I < filehandle > E < mdash > an object representing that file. The
133
- equality sign C < = > I < assigns > that filehandle to the variable on the left,
143
+ assignment operator C < = > I < assigns > that filehandle to the variable on the left,
134
144
which means that C < $file > now stores the filehandle.
135
145
136
- = head3 X < C < string literal > >
146
+ = head2 X < String literals| string literal (Basics) >
137
147
138
148
C < 'scores.txt' > is a I < string literal > . A string is a piece of text, and a
139
149
string literal is a string which appears directly in the program. In this line,
140
150
it's the argument provided to C < open > .
141
151
142
- = begin code :preamble<my $file>
152
+ = head1 X < Arrays|array (Basics) > , X < methods|method (Basics) > and X < invocants|invocant (Basics) >
153
+
154
+ = begin code :preamble<my @names>
143
155
my @names = $file.get.words;
144
156
= end code
145
157
146
- = head3 X < C < array > > , X < C < method > |method (Basics)> and X < C < invocant > |invocant (Basics)>
147
-
148
158
The right-hand side calls a I < method > E < mdash > a named group of
149
159
behavior E < mdash > named C < get > on the filehandle stored in C < $file > . The C < get >
150
160
method reads and returns one line from the file, removing the line ending. If
@@ -159,13 +169,13 @@ Finally, this list gets stored in the L<Array|/type/Array> C<@names>.
159
169
The C < @ > sigil marks the declared variable as an C < Array > .
160
170
Arrays store ordered lists.
161
171
172
+ = head1 X < Hashes|hash (Basics) >
173
+
162
174
= begin code
163
175
my %matches;
164
176
my %sets;
165
177
= end code
166
178
167
- = head3 X < C < hash > >
168
-
169
179
These two lines of code declare two hashes. The C < % > sigil marks each variable
170
180
as a C < Hash > . A C < Hash > is an unordered collection of key-value pairs. Other
171
181
programming languages call that a I < hash table > , I < dictionary > , or I < map > .
@@ -176,14 +186,14 @@ In the score counting program, C<%matches> stores the number of matches each
176
186
player has won. C < %sets > stores the number of sets each player has won. Both
177
187
of these hashes are indexed by the player's name.
178
188
189
+ = head1 X < C < for > |for (Basics)> and X < blocks|block (Basics) >
190
+
179
191
= begin code :preamble<my $file>
180
192
for $file.lines -> $line {
181
193
...
182
194
}
183
195
= end code
184
196
185
- = head3 X < C < for > |for (Basics)> and X < C < block > >
186
-
187
197
C < for > produces a loop that runs the I < block > delimited by curly braces
188
198
once for each item of the list, setting the variable C < $line >
189
199
to the current value of each iteration. C < $file.lines > produces a list of
@@ -259,24 +269,30 @@ there is no need to include a separate statement like C<%sets{$p1} = 0> before
259
269
you can meaningfully add C < $r1 > to it. We'll look at this is behavior in a bit
260
270
more detail below.
261
271
272
+ = head2 X < C < Any > |Any (Basics)> and X < C < += > |+= (Basics)>
262
273
263
- = head3 X < C < Any > | Any (Basics)> and X < C < += > >
274
+ = begin code :preamble<my %sets;my $p1;my $p2;my $r1;my $r2>
275
+ %sets{$p1} += $r1;
276
+ %sets{$p2} += $r2;
277
+ = end code
264
278
265
- C < += $r1 > means I < increase the value in the variable on the left by $r1 > . In the
266
- first iteration C < %sets{$p1} > is not yet defined, so it defaults to a special
279
+ C < %sets{$p1} += $r1> means I < increase the value in the variable on the left by $r1 > .
280
+ In the first iteration C < %sets{$p1} > is not yet defined, so it defaults to a special
267
281
value called C < Any > . The C < += > operator conveniently treats the undefined value
268
282
C < Any > as a number with the value C < 0 > , allowing it to sensibly add some other
269
283
value to it. To perform the addition, the strings C < $r1 > , C < $r2 > , etc. are
270
284
automatically converted to numbers, as addition is a numeric operation.
271
285
272
- = head3 X < C < fat arrow > > , X < C < pair > > and X < C < autovivification > >
286
+ = head2 X < Fat arrow| fat arrow (Basics) > , X < pairs| pair (Basics) > and X < autovivification|autovivification (Basics) >
273
287
274
288
Before these two lines execute, C < %sets > is empty. Adding to an entry that is
275
289
not in the hash yet will cause that entry to spring into existence
276
- just-in-time, with a value starting at zero. (This is I < autovivification > ).
277
- After these two lines have run for the first time, C < %sets > contains C << 'Ana'
278
- => 3, 'Dave' => 0 >> . (The fat arrow C << => >> separates the key and the value
279
- in a C < Pair > .)
290
+ just-in-time, with a value starting at zero. This behavior is known as
291
+ I < autovivification > . After these two lines have run for the first time, C < %sets >
292
+ contains C « 'Ana' => 3, 'Dave' => 0 » . (The fat arrow C « => » separates the
293
+ key and the value in a C < Pair > .)
294
+
295
+ = head2 X < Postincrement|postincrement (Basics) > and X < preincrement|preincrement (Basics) >
280
296
281
297
= begin code :preamble<my $r1;my $r2;my $p1;my $p2;my %matches;>
282
298
if $r1 > $r2 {
@@ -291,20 +307,18 @@ If C<$r1> is not larger than C<$r2>, C<%matches{$p2}> increments. Just as in
291
307
the case of C < += > , if either hash value did not exist previously, it is
292
308
autovivified by the increment operation.
293
309
294
- = head3 X < C < postincrement > > and X < C < preincrement > >
295
-
296
310
C < $thing++ > is a variant of C < $thing += 1 > ; it differs from the latter in that
297
311
the return value of the expression is C < $thing > I < before > the increment, and not
298
312
the incremented value. As in many other programming languages, you can use C < ++ >
299
313
as a prefix. Then it returns the incremented value: C < my $x = 1; say ++$x >
300
314
prints C < 2 > .
301
315
316
+ = head1 X < Topic variable|topic variable (Basics) >
317
+
302
318
= begin code :preamble<my @names;my %sets;my %matches>
303
319
my @sorted = @names.sort({ %sets{$_} }).sort({ %matches{$_} }).reverse;
304
320
= end code
305
321
306
- = head3 X < C < variables, $_ > >
307
-
308
322
This line consists of three individually simple steps. An array's C < sort >
309
323
method returns a sorted version of the array's contents. However, the default
310
324
sort on an array sorts by its contents. To print player names in winner-first
@@ -313,7 +327,7 @@ names. The C<sort> method's argument is a I<block> used to transform the array
313
327
elements (the names of players) to the data by which to sort. The array items
314
328
are passed in through the I < topic variable > C < $_ > .
315
329
316
- = head3 X < C < block > |block (Basics) >
330
+ = head2 Blocks
317
331
318
332
You have seen blocks before: both the C < for > loop C << -> $line { ... } >> and
319
333
the C < if > statement worked on blocks. A block is a self-contained piece of
@@ -325,13 +339,13 @@ have both won two matches. That simple sort doesn't account for the number of
325
339
sets won, which is the secondary criterion to decide who has won the
326
340
tournament.
327
341
328
- = head3 X < C < stable sort> >
342
+ = head2 Stable sort
329
343
330
344
When two array items have the same value, C < sort > leaves them in the same order
331
345
as it found them. Computer scientists call this a I < stable sort > . The program
332
346
takes advantage of this property of Raku's C < sort > to achieve the goal by
333
- sorting twice: first by the number of sets won (the secondary criterion), then
334
- by the number of matches won.
347
+ sorting twice: first by the number of sets won (the primary criterion), then
348
+ by the number of matches won (the secondary criterion) .
335
349
336
350
After the first sorting step, the names are in the order C < Beth Charlie Dave
337
351
Ana > . After the second sorting step, it's still the same, because no one has
@@ -342,6 +356,8 @@ C<sort> sorts in ascending order, from smallest to largest. This is the
342
356
opposite of the desired order. Therefore, the code calls the C < .reverse > method
343
357
on the result of the second sort, and stores the final list in C < @sorted > .
344
358
359
+ = head1 Standard output
360
+
345
361
= begin code :preamble<my @sorted;my %matches;my %sets>
346
362
for @sorted -> $n {
347
363
my $match-noun = %matches{$n} == 1 ?? 'match' !! 'matches';
@@ -350,8 +366,6 @@ for @sorted -> $n {
350
366
}
351
367
= end code
352
368
353
- = head3 X < C < say > | say (Basics)> , X < C < print > | say (Basics)> and X < C < put > |put (Basics)>
354
-
355
369
To print out the players and their scores, the code loops over C < @sorted > ,
356
370
setting C < $n > to the name of each player in turn. Read this code as "For each
357
371
element of sorted, set C < $n > to the element, then execute the contents of the
@@ -370,16 +384,16 @@ want the newline at the end.)
370
384
Note that C < say > will truncate certain data structures by calling the C < .gist >
371
385
method so C < put > is safer if you want exact output.
372
386
373
- = head3 X < C < interpolation > >
387
+ = head2 X < Variable interpolation|variable interpolation (Basics) >
374
388
375
389
When you run the program, you'll see that C < say > doesn't print the contents of
376
390
that string verbatim. In place of C < $n > it prints the contents of the variable
377
- C < $n > E < mdash > the names of players stored in C < $n > . This automatic substitution
378
- of code with its contents is I < interpolation > . This interpolation happens only
379
- in strings delimited by double quotes C < "..." > . Single quoted strings C < '...' >
380
- do not interpolate:
391
+ C < $n > E < mdash > a player's name stored in C < $n > . This automatic substitution
392
+ of code with its contents is called I < interpolation > . This interpolation happens
393
+ only in strings delimited by double quotes C < "..." > . Single quoted strings
394
+ C < '...' > do not interpolate:
381
395
382
- = head3 X < C < double-quoted strings > > and X < C < single-quoted strings > >
396
+ = head2 X < Double-quoted strings| double-quoted strings (Basics) > and X < single-quoted strings|single-quoted strings (Basics) >
383
397
384
398
= begin code
385
399
my $names = 'things';
@@ -389,7 +403,7 @@ say "Do not call me $names"; # OUTPUT: «Do not call me things»
389
403
390
404
Double quoted strings in Raku can interpolate variables with the C < $ >
391
405
sigil as well as blocks of code in curly braces. Since any arbitrary
392
- Perl code can appear within curly braces, C < Array > s and C < Hash > es may be
406
+ Raku code can appear within curly braces, C < Array > s and C < Hash > es may be
393
407
interpolated by placing them within curly braces.
394
408
395
409
Arrays within curly braces are interpolated with a single space character
@@ -429,7 +443,7 @@ followed by a postcircumfix E<mdash> a bracketing pair that follows a
429
443
statement. It's also ok to have a method call between the variable name and
430
444
the postcircumfix.
431
445
432
- = head3 X < C < Zen slice > | Zen slice (Basics) >
446
+ = head1 Zen slices
433
447
434
448
= begin code
435
449
my @flavors = <vanilla peach>;
@@ -447,7 +461,6 @@ say "we have @flavors.sort.join(', ')";
447
461
# OUTPUT: «we have peach, vanilla»
448
462
= end code
449
463
450
-
451
464
= head1 Exercises
452
465
453
466
B < 1. > The input format of the example program is redundant: the first line
0 commit comments