Contemporary programming is (perhaps unfortunately) based upon seven-bit ASCII, leading to a distict paucity of available operator symbols, particularly compared with the rich variety used in mathematics.

This paucity is accentuated in SML by the design inability to
distinguish between prefix and infix uses of an operator symbol such
as `-`. This forces SML to use tilde for unary negation
and `!` for dereferencing, in jarring discord with contemporary
practice.

C avoids this problem by adopting the rule that every pair of alphabetic
identifiers must be separated by a binary symbolic operator; this allows
any following symbolic operators to be unambiguously identified as prefix.
This is why C can use `*` for both binary multiplication and unary
dereferencing. This design approach is unworkable in the functional
programming context due to the pervasive use of `f x` functional
application syntax.

Mythryl, participating in a recent trend, uses the presence or absence of whitespace to distinguish infix from prefix operator application:

f-g # Infix --- subtraction. f -g # f(-g). f - g # Infix --- subtraction. f- g # Postfix. (No default Mythryl library semantics.)

This effectively doubles or triples the size of the available operator namespace and allows Mythryl to use default operator definitions which are much more in tune with contemporary C-influenced intuition.

This also allows Mythryl to support some mathematical notations not (yet?) commonly used in the programming community, such as this definition of the factorial function, taken from the Mythryl standard library src/lib/std/src/multiword-int-guts.pkg package:

fun 0! => 1; n! => n * (n - 1)! ; end;

Mythryl similarly supports a limited set of circumfix operators:

fun |i| = (i > 0) ?? i :: -i;

This allows certain common mathematical notations to be used in the Mythryl programming context for brevity and readability.

To resolve correctly, such expressions must be surrounded by whitespace and there must be no whitespace between the circumfix operator symbols and the enclosed expression.

The set of such operators currently supported is:

- |x|
- <x>
- /x/
- {i}

(Although in a nod to quantum mechanics, Mythryl does also support mismatched bracket
constructs like like `<f|`

and `/`

g>/. The standard library defines
no meanings for these.)

The compiler resolves these operators to equivalent but more conventional
names early in the front end, renaming them `(|x|) (<x>) (/x/) ({x})`
respectively. These names may be used in contexts where the functions
involved need to be named independent of immediate application ot a value.

A closely related Mythryl frontend tweak internally resolves `a[i]`
to `(_[]` early. Defining this as a synonym for the usual vector
`get` operation via code like

my (_[]): (Vector(X), Int) -> X = inline_t::poly_vector::get_with_boundscheck;

(taken from src/lib/std/src/vector.pkg)

allowing more natural reference to vector elements:

linux> my eval: v = #[1, 2, 3]; #[1, 2, 3] eval: v[1]; 2

A matching frontend tweak resolves `a[i] = v;`
to `(_[]:=)(a,i,v);` Defining `(_[]:=)` as a synonym
for the usual vector `set` operation via code like

(_[]:=) = set;

(again from src/lib/std/src/vector.pkg) allows use of traditional notation for setting a vector entry:

linux> my eval: v = #[1, 2, 3]; #[1, 2, 3] eval: v[1] := 222; #[1, 222, 3]

Comments and suggestions to: bugs@mythryl.org