Special call syntax
Operators
Operators are functions, but they are parsed differently. Here is a complete list:
Unary operators
Operator | Use |
---|---|
!x |
Logical "not". |
x! |
Gets the value from an option, or throws an exception if it is empty. |
-x |
Negates a number. |
~x |
Bitwise negation (flips 0s and 1s in an integral value). |
*x |
Dereferences a pointer. |
Binary operators
These are in order of operator precedence.
For example, *
binds more tightly than +
,
so 1 + 2 * 3
parses as 1 + (2 * 3)
.
Operator | Use |
---|---|
~= , ~~= |
Mutating concatenation; adds one (~= )
or many (~~= ) elements to a collection.
|
|| |
Logical "or"; or for option types, chooses the first non-empty option.
This is lazily evaluated, so in a || b ,
if a is true (or a non-empty option), b won't be evaluated.
|
&& |
Logical "and".
This is lazily evaluated, so in a && b , if a is false,
b won't be evaluated.
|
?? |
Gets a value from an option on the left, or returns the right value.
This is lazily evaluated, so in a ?? b ,
if a is non-empty, b won't be evaluated.
|
foo |
Ordinary named functions; included here to show precedence. |
.. |
Numerical range, e.g. 0 .. 10 |
~ , ~~ |
~ adds one element to a collection.
For ordered collections, x ~ xs adds to x to the left
and xs ~ x adds x to the right.
For unordered collections, only xs ~ x should be implemented.
~~ concatenates two collections (or combines unordered collections).
|
== ,
!= ,
< ,
> ,
<= ,
>= ,
<=>
|
Comparison; <=> is 3-way comparison.
|
| |
Union of sets; or bitwise "or" for integral values. |
& |
Intersection of sets; or bitwise "and" for integral values. |
<< , >> |
Bitshift left and right. |
+ , - |
Addition and subtraction.
For math only; to "add" collections (including strings), use ~~ .
|
* , / , %
|
Multiply, divide, and modulo. |
** |
Exponentiation; 2 ** 3 is 8 .
|
Defining operator functions
Defining an operator looks just like defining a function.
The exception is that !
would be ambiguous,
so you must define a name functions not
or force
.
Also, the operators -
, ~
, and
+
must have explicit visibility,
since the same characters are used to specify visibility.
(Visibility will be explained in Modules).
"new" calls
We've seen ()
a lot in this tutorial.
This is syntax for calling a function new
with no arguments.
To call it with arguments, separate them with commas.
If there is only one argument, leave a trailing comma.
The following example constructs lists, which will be described in more detail in Collections.
The parentheses can often be ommitted.
Named "new"
There is a special syntax for calling new
while specifying argument names.
Each argument name is written on its own line followed by :
.
This is useful for creating instances of large record types. (See Records.)
Subscript
x[y]
is shorthand for x subscript y
and
x[y] := z
is shorthand for x set-subscript y, z
.
This example uses mutable lists, explained more in Collections.
You can define these by defining named functions subscript
and set-subscript
.
Setters
Recall that x := y
is used to set a local variable.
The :=
can accept other kinds of expression on the left.
Syntax | Translation | Use |
---|---|---|
x := y |
y set-x |
If x is a local variable, this writes to that.
Otherwise this may set a global or thread-local variable. |
x.y := z |
x set-y z |
Used to set a field in a record.
This is generated when defining a record, as explained in Records.) |
x[y] := z |
x set-subscript y, z |
Used to set the value in a list at an index, or in a map at a key. |
*x := y |
x set-deref y |
Used to write to a pointer. |
x->y := z |
x set-deref-y z |
Used to write to a field of a record when 'x' is a pointer to the record.
This is generated for extern records.
|
Relatedly, a function name may end with =
.
The idea is that x foo= y
should behave the same as x := x foo y
.
This example uses a lambda, described more in Lambdas.
There's no desugaring for this; you just define the function name with an =
on the end.
Line continuation
Normally a newline indicates the end of an expression,
but sometimes it's clear from context that the line can't end yet.
In these contexts, the parser will skip any newlines:
- After
=
or:=
. - After a binary operator like
+
. - After the
:
in anassert
. -
After a comma in an argument list.
But
x,
on its own does not continue the line since it's equivalent tox.new
.
\
before the newline.