# A Tour of Morfa

## Declaring new operators

### Infix `^` for exponentiation

Here is how the exponentiation operation `^` may be introduced to Morfa (there is no built-in one).

An operator declaration introduces `^` as a new infix operator with a high precedence (so that it binds stronger than any built-in arithmetic operators).

``````operator ^ { kind = infix, precedence = call }
``````

Then we provide an implementation for integer exponentiation:

``````func ^ (base: int, power: int): int
{
assert (power >= 0);

if (power == 0)
return 1;

var x = base ^ (power / 2);
var xx = x * x;

return if (power % 2 == 0) xx else xx * base;
}
``````

Time for some tests:

``````unittest
{
assert (0 ^ 3 == 0);
assert (2 ^ 0 == 1);
assert (2 ^ 3 == 8);
assert (2 * 2 ^ 2 == 8); // should be 2 * (2 ^ 2), not (2 * 2) ^ 2
}
``````

One thing still needs fixing: `2 ^ 3 ^ 2` evaluates to `(2 ^ 3) ^ 2`, that is `64`. But exponentiation is usually treated as right-associative (see for example the Wikipedia entry for Associative property), that is, xyz = x(yz) holds for all `x`, `y` and `z`. Thus `2 ^ 3 ^ 2` should be equal to `2 ^ (3 ^ 2) = 512`.

To achieve this we add an associativity annotation to the operator declaration. We have to declare a new operator to avoid conflicts with `^` declared above as left-associative, which is the default when the associativity is not set explicitely:

``````operator ^^ { kind = infix, precedence = call, associativity = right }

alias ^^ = ^; // Use the same implementation for both operators

unittest
{
assert (2 ^ 3 ^ 2 == 64);    // '^' is left-associative
assert (2 ^^ 3 ^^ 2 == 512); // '^^' is right-associative
}
``````

### Overloading `^`

We may add another implementation of `^` for text exponentiation:

``````func ^ (base: text, power: int): text
{
assert (power >= 0);

if (power == 0)
return "";

var x = base ^ (power / 2);
var xx = x ~ x;

return if (power % 2 == 0) xx else xx ~ base;
}

unittest
{
assert ("la" ^ 3 == "lalala");
assert ("la" ^ 2 ^ 2 == "lalalala");
}
``````

### Prefix `!` for negation

In Morfa, boolean negation is written using the operator `not`: ```not true = false``` and `not false = true`. In many languages the prefix `!` is used instead. This is easy to mimic in Morfa:

``````operator ! { kind = prefix, precedence = not }

func ! (b: bool)
{
return not b;
}

unittest
{
assert (!true == false);
assert (! !true == true);
}
``````

Note the space between two `!`'s in the last `assert` statement. The expression `!!true` would be treated as an application of the operator `!!` to `true`.

Instead of implementing the function `!` we may create an alias as well:

``````unittest
{
alias ! = not;
assert (!false == true);
}
``````

### Postfix `!` for factorial

The operator `!` is also commonly used for the factorial function. Let us introduce this notation in Morfa:

``````operator ! { kind = postfix, precedence = call }

func \$! (n: int)
{
assert (n >= 0);

if (n == 0)
return 1;

return n * (n-1)!;
}

unittest
{
assert (0! == 1);
assert (5! == 120);
}
``````

Note that the function implementing the factorial is called `\$!`, not `!`. This way implementations of the prefix `!` and the postfix `!` with arguments of the same type may exist in the same scope.

### `quoting` attribute

The attribute `quoting` allows for some customizable syntactic sweetening when used in an operator declaration:

``````import morfa.base;
operator ' { kind = prefix, precedence = max, quoting }
``````

Now, operator `'` will wrap the identifier to the right in quoting marks `""` to turn it into a string literal.

``````func '(t: text): void
{
println(t);
}

unittest
{
'Hello;
'World;
}
``````