Paweł bbkr Pabian
Posted on August 28, 2023
Whenever mathematician, physicist, electronics engineer or, for example, navigator wants to use some programming language there is entry level bump. Programming languages use different notation from what they use on daily basis. But what if we could use ability to define UTF-8 variables and operators to bring programming language closer to their expert domains?
Variable names
Raku language allows to use every codepoint from Unicode Letter category in variable names out of the box:
my $λ = 2.5E-9; # photon wavelength in meters
say $λ;
my $ℤ = 10+0.5i; # some electrical impedance
However this language uses sigils. Despite many advantages sigils do not fit well in mentioned notations, so there is a way to mostly (backslash is still required for defining) skip them:
my \λ = 2.5E-9;
say λ;
Note that engineering notation and complex numbers for values are provided out of the box, already a huge bonus!
Operators
Variables and values are nice, but they are worthless without operators to perform actual calculations on them. Raku language has few built-in operators that follow mathematical notation.
Numeric comparison
$ raku -e 'say 3 ≤ 3.14 ≤ 4'
True
Way more natural than 3 <= 3.14 <= 4
.
Basic powers
$ raku -e 'say π²'
9.869604401089358
No need to write cryptic π**2
. And yes, pi is predefined.
Set comparison
Find common lines between two files:
$ raku -e '
.say for ( "file1".IO.lines ∩ "file2".IO.lines ).keys
'
Set operators also have ASCII aliases. But for someone working with sets ∩
notation for set intersection is natural, while (&)
is something they would have to learn.
Custom operators
Raku language allows to define any string to act as an operator. There are few types of them: prefix
before value, postfix
after value, infix
between values and circumfix
around value(s).
Let's implement oversimplified currency calculator (that will convert only to PLN) to illustrate how they work:
sub prefix:<£> ($a) { $a * 5.24 };
sub postfix:<$> ($a) { $a * 4.11 };
sub prefix:<¥> ($a) { $a * 0.028 };
say £4.10 + 20$ + ¥3.15; # 103.77
Operator is just a subroutine which accepts parameters that operator acts on. It can return any object, there are no type restrictions between what comes in and what comes out.
Note that after £
operator was defined £4.10
syntax becomes fully functional part of language. This is a huge deal. Many Raku ecosystem modules utilize this concept. For example:
use Physics::Constants;
use Physics::Measure :ALL;
say "Voltage is ", 20A * 10kΩ # Voltage is 200000V
my $body-temp = 36.8°C;
say "Healthy" if $body-temp == 36.6°C ± 3%; # Healthy
This package uses Math::Constants
and Physics::Constants
modules under the hood, which also provides tons of useful symbol definitions.
Atomic access
How about something by programmers for programmers? Common task in multi threaded applications is to bump some shared variables. Usually it requires locks or semaphores to avoid this race condition:
my $processed = 0;
my @threads = start { $processed++ } for ^10000;
await @threads;
say $processed; # 9967, ooops
Raku provides atomic operators out of the box. And they are literally... atomic:
my atomicint $processed = 0;
my @threads = start { $processed⚛++ } for ^10000;
await @threads;
say $processed; # 10000
Funny story - those were defined at first as ⚛️++
using ATOM SYMBOL VARIATION SELECTOR-16
. People reactions were... interesting :)
Final boss
Now, when you know how to define your own operators, you can show everyone how serious you are about incrementing!
sub postfix:<𒀱𒀱> ($a is rw) { $a++ }
my $a = 4;
$a𒀱𒀱;
say $a; # 5, for sure
Raku note: By default operator arguments are immutable, unless marked as mutable by is rw
.
With that last bit of knowledge it is time to go back to "serious" part or this series.
Posted on August 28, 2023
Join Our Newsletter. No Spam, Only the good stuff.
Sign up to receive the latest update from our blog.