summaryrefslogtreecommitdiff
path: root/content/posts/2018/2018-02-05-why-perl6.md
blob: f2a8ea331eec6c3b574b6a498c7d42c31ff965e8 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
---
title: Why Perl 6?
date: 2018-02-05
tags:
- Perl6
- Raku
---

For about a year now, I've been working in Perl 6. Telling this to other people
often brings about some confused faces. I've grown quite fond of Perl 6 the
more I learn about it, yet the general developer community still seems to think
Perl is a dirty word. In this article, I will detail some of the features that
make me like Perl 6, and why I try to use it wherever possible.

== Hassle-free command line arguments
Whet creating an application, you usually want to be able to specify some
arguments at runtime. Most times this happens using command line arguments or
options. Perl 6 allows you to specify these in the
[`MAIN`](https://docs.perl6.org/language/functions#index-entry-MAIN) subroutine
signature.

For instance, if I want the application to accept two string arguments, I can
do it as easy as this:

```raku
sub MAIN (
	Str $arg-one,
	Str $arg-two,
) {
	...
}
```

Now, if you wanted to add an option like `--output=/path/to/file`, you can do
it just like this:

```raku
sub MAIN (
	Str $arg-one,
	Str $arg-two,
	Str :$output,
) {
	...
}
```

By default, if there's a `MAIN` available in your Perl 6 program, but the
arguments or options supplied by the user are incorrect, it will display the
right way to invoke the command, called the
[`USAGE`](https://docs.perl6.org/language/functions#index-entry-USAGE).
Ofcourse, this message can be changed if you wish, but the default is quite good
for most use-cases.

However, sometimes you want to add a little explanation to what the argument or
option is intended for. Just for a liitle bit of additional user friendliness.

Fear not, for this is also already covered by the defaults. In Perl, there was
POD to document your code. In Perl 6, we have
[POD](https://docs.perl6.org/language/glossary#index-entry-POD) as well. And
these comments can be inspected at runtime to provide the user some
information. And that's exactly what the default `USAGE` also does. So if you
want to add some helpful comments to the arguments or the program itself,
simply add the comments where you want them:

```raku
#| This is a sample program, just to showcase the awesome stuff available in
#| Perl 6.
sub MAIN (
	Str $arg-one, #= Just a random argument
	Str $arg-two, #= Yet another argument used for showcasing
	Str :$output, #= Last but not least, an option which allows for a value
) {
	...
}
```

## Unicode

What if you could support all languages with a single implementation? That's
where unicode comes in. And Perl 6 currently has the best support for Unicode
out of all programming languages available. Its only real competitor seems to
be Swift (at the time of writing this).

But not just for handling strings, Perl 6 uses unicode as a core language
feature. This means you can use them in your source code as well. And that
opens up some nice possibilities. Using the right unicode characters allows you
to write cleaner and more concise code, reducing the cognitive load while
trying to understand the program.

For instance, if you're trying to do any kind of math, you can just use the
π character as a regular character. Or use the ² to get the square of a certain
number. This little piece is completely valid in Perl 6:

```raku
my $a = $r² ÷ π;
```

Now, if you're thinking "that looks neat, but how am I ever going to write
these?", do not worry. Most operating systems and many editors have tools to let
you input these. For instance, using `vim` with
[`vim-perl6`](https://github.com/vim-perl/vim-perl6), you can just write "pi"
and hit space (or type any non-alphabetical character).

But not everyone is using an OS or an editor that makes it easy. And for those
people, Perl 6 simply supports using [ASCII based
operators](https://docs.perl6.org/language/unicode_ascii). The previous block
could also be written as follows:

```raku
my $a = $r ^ 2 / pi;
```

As unicode becomes more accepted, input methods will hopefully improve to make
input easier for everyone in the long run. Those who can already input it
easily don't have to wait for this future, Perl 6 already supports it.

## Multithreading

Multi-core processors are virtually everywhere these days. Yet many programming
languages still don't support multithreaded application development natively,
if at all. In Perl 6, running something in a different thread is as easy as
wrapping it in a [`start`](https://docs.perl6.org/routine/start) block:

```raku
start {
	do-something();
}
```

`start` returns a [`Promise`](https://docs.perl6.org/type/Promise), which you can
store in a scalar variable just like any other object. You can check on whether
the `Promise` has completed already and check whether it died, for instance.

Other aspects which can often be spread over multiple threads are loops or
maps. For instance, consider the following
[`map`](https://docs.perl6.org/routine/map) function:

```raku
@cats.map: {
	$^cat.pat;
}
```

This will pat each cat in turn, in the order they appear in the list. But you
can speed up the patting process by patting multiple cats at the same time. And
to get there, all you need to do is add a
[`race`](https://docs.perl6.org/routine/race):

```raku
@cats.race.map: {
	$^cat.pat;
}
```

This will attempt to pat the cats over multiple threads, speeding up the
process to pat all the cats. If the result of the pattings needs to be in the
same order as the patting order, you use
[`hyper`](https://docs.perl6.org/routine/hyper) instead of `race`:

```raku
@cats.hyper.map: {
	$^cat.pat;
}
```

## Object orientation

Object oriented programming seems to be getting out of fashion with the new
generation of developers. But it's still in wide use, being taught at most
universities, and is often easy to explain to new developers as well.

And Perl 6 has [OO](https://docs.perl6.org/language/classtut#index-entry-OOP)
support built into its core:

```raku
class Foo
{
	has Str $some-field;

	method bar (
		Str $some-arg,
	) {
		...
	}
}
```

You can also have
[multi-dispatch](https://docs.perl6.org/language/glossary#index-entry-Multi-Dispatch)
methods on your classes, which are methods with the same names, but accepting
different arguments or argument types. For instance:

```raku
class Foo
{
	multi method bar (
		Str $some-arg,
	) {
		...
	}

	multi method bar (
		Int $some-arg,
	) {
		...
	}
}
```

Which method is being used will be decided by the type of argument is being
passed in, in this case either a [`Str`](https://docs.perl6.org/type/Str) or an
[`Int`](https://docs.perl6.org/type/Int).

## Functional programming

Whilst OO is considered being old more and more, functional programming is
gaining ground. And this paradigm is fully supported in the core of Perl 6 as
well. You've seen the `map` example already while patting cats earlier, for
instance.

But there's much more on the functional playing field, such as the
[`==>`](https://docs.perl6.org/routine/==%3E) operator, known as the [`feed
operator`](https://docs.perl6.org/language/operators#infix_==%3E). It simply
passed the output of a statement as the last argument to the next statement:

```raku
@grumpy-cats
	==> feed()
	==> pat()
	==> snuggle()
	==> my @happy-cats;
```

This will take the `@grumpy-cats`, feed them, pat them, snuggle them and put
the result into `@happy-cats`. You could've chained the calls using a `.`
instead, and Perl 6 allows you to do this too. But the `==>` looks much more
readable to me, which is why I prefer using this instead.

I'm still exploring the functional programming field myself, but these few
things have made me happy exploring it.

## Community

(Almost) last, but certainly not least, the Perl 6 community is amazing. It's
been the friendliest bunch I've been with, both on IRC, their mailing lists and
in real life. Everyone is welcoming, and they try to help you whenever they
can.

Community is important to help you out whenever you get stuck for whatever
reason. A friendly community is the best you can get here to keep you a happy
developer yourself as well.

## Other little aspects

There's a few neat things I can do in Perl 6 that I can't do in (most) other
languages, but aren't important enough to warrant a large section to show them
off.

### Dashes in names

You can use dashes in names: Things like `my $foo-bar` is valid, just like
`method foo-bar`. It's nothing big on itself, but I've found it makes reading
code much more enjoyable than pascalCase, CamelCase or snake_case.

### Gradual typing

You don't *need* to use types in Perl 6. But when you want to use them (for
making use of multi-dispatch, for example), you can just start using them. If
types are added, the compiler will make sure the types are correct. If not, you
can always do them yourself (but why would you, when the compiler can do a
better job for free).