Fun with UTF-8: variables and operators

bbkr

Paweł bbkr Pabian

Posted on August 28, 2023

Fun with UTF-8: variables and operators

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
Enter fullscreen mode Exit fullscreen mode

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 λ;
Enter fullscreen mode Exit fullscreen mode

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
Enter fullscreen mode Exit fullscreen mode

Way more natural than 3 <= 3.14 <= 4.

Basic powers

$ raku -e 'say π²'
9.869604401089358
Enter fullscreen mode Exit fullscreen mode

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
'
Enter fullscreen mode Exit fullscreen mode

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
Enter fullscreen mode Exit fullscreen mode

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:

Physics::Measure

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
Enter fullscreen mode Exit fullscreen mode

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
Enter fullscreen mode Exit fullscreen mode

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
Enter fullscreen mode Exit fullscreen mode

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
Enter fullscreen mode Exit fullscreen mode

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.

💖 💪 🙅 🚩
bbkr
Paweł bbkr Pabian

Posted on August 28, 2023

Join Our Newsletter. No Spam, Only the good stuff.

Sign up to receive the latest update from our blog.

Related

UTF-8 series wrap up
unicode UTF-8 series wrap up

September 24, 2023

UTF-8 Byte Order Mark
unicode UTF-8 Byte Order Mark

September 18, 2023

Fun with UTF-8: Homoglyphs
unicode Fun with UTF-8: Homoglyphs

September 15, 2023

UTF-8 regular expressions
unicode UTF-8 regular expressions

September 7, 2023