Fun with UTF-8: variables and operators
Tags: unicode, utf, raku
Published: 2023-08-28 08:18:14

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](https://www.raku.org/) language allows to use every codepoint from Unicode Letter category in variable names out of the box:

```raku
my $λ = 2.5E-9; # photon wavelength in meters
say $λ;

my $ℤ = 10+0.5i; # some electrical impedance
```

However this language uses sigils. Despite [many advantages](https://raku-advent.blog/2022/12/20/sigils/) 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](https://www.raku.org/) 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](https://docs.raku.org/language/setbagmix#Operators_with_set_semantics) 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](https://www.raku.org/) language allows to [define](https://docs.raku.org/language/optut) 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:

```raku
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](https://modules.raku.org/) modules utilize this concept. For example:

**[Physics::Measure](https://modules.raku.org/dist/Physics::Constants:zef:zef:librasteve)**

```
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`](https://modules.raku.org/dist/Math::Constants:zef:zef:jjmerelo) and [`Physics::Constants`](https://modules.raku.org/dist/Physics::Constants:zef:zef:librasteve) 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](https://www.raku.org/) provides [atomic operators](https://docs.raku.org/type/atomicint#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](https://www.raku.org/) 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.