Functions
Functions are defined using the *
character.
Both the function's name and its parameters come before this *
character, in
that order, separated by spaces.
The function body is enclosed in curly brackets.
The function's return value is preceded by a *
character as well.
(Functions may also have multiple return statements, or none at all.)
add a b * {
sum: a + b;
* sum;
}
Calling a function is done as in C-like languages, with the function name, followed by its arguments in parentheses, separated by commas.
a: /;
b: /\;
c: add(a, b);
If no value is returned, the semicolon after *
may be omitted:
exit code * {
? code {*}
"Success"!;
}
Main Function
The main function/entrypoint of the program is denoted by =>
.
This function will be implicitly called on execution of the program.
The return value of the main function indicates the exit code of the program
(optional, defaults to 0). This function will not be called when importing
the module it's located in. Command line arguments can be gotten as an array
with an optional parameter in this function.
=> argv * {
== program here
}
Optional Parameters
Parameters can be made optional by adding a ?
character after the parameter's
name. Optional parameters are required to have a default value defined in the
function's body using the param <> default
syntax.
== string.leftpad
leftpad string length char? * {
char <> " ";
* pad(string, length, char) + string;
}
leftpad("hello", /\/\)!; == hello
leftpad("hello", /\/\, "-")!; == -----hello
Varargs
A function can accept a variable number of arguments by adding ...
after the
last parameter's name. Packed arguments will be passed into the function as an
array.
product nums... * {
prod: /;
... n ->? nums {
prod++: n;
}
* prod;
}
prod()!; == 1
prod(///)!; == 7
prod(///, /\/\/)!; == 147
prod(/\/, /\\\/\, /\, /\\/\\\, ///)!; == 171360
Argument Unpacking
Arguments can be spread into a function by using the **
unary operator:
pow a b * {
* a +++ b;
}
arguments = [/\, //];
pow(**arguments)!;
== equivalent to pow(/\, //)!;
Decorators
Decorators are syntactic sugar for calling a function/class which argument is another callable.
To use a function as a decorator, write the name, @
and then declare the
function it is decorating.
== Decorator
double func * {
wrapper args... * {
* func(**args) ++ /\;
}
* wrapper;
}
== Decorated functions
double @ multiply a b * {
* a ++ b;
}
double @ code_to_char code * {
* code%;
}
multiply(/\, /\\)!; == 16
code_to_char(/\\\\/)!; == !!
Iterators
Functions can yield values instead of returning them, thus making the function
behave like an iterator. Values are yielded with the **
operator:
<=math.is_prime;
prime_generator * {
x: /\;
.. {
? is_prime(x) {
** x;
}
x+: /;
}
}
pg: prime_generator();
pg!;
"Primes below 100:"!;
... i ->? pg {
? i > /\/\ +++ /\ {
!;
<-
}
""?!(i) + " " ~> /;
}
<Iterator@7fd890475860>
Primes below 100:
2 3 5 7 11 13 17 19 23 29 31 37 41 43 47 53 59 61 67 71 73 79 83 89 97
Just like with *
, the semicolon after **
can be omitted if no value is
yielded:
foo * {**}
[]?!(foo())! == [null]
Iterators support special $
and cast %
methods.
Iterator%
returns the length of the iterator if available, and null otherwise.
Iterator$
yields the next value of the iterator.
Iterators are always truthy.
Function Composition
Functions, types, and type aliases in Samarium can be composed together by using
the &
operator:
(<-math.sqrt & <-operator.add)(//, //\)! == 3
(<-types.Boolean & /?!)("1")! == true
<=math.[abs, max, min];
arrmap: []?! & <-iter.map;
arrmap(abs, [/, `/, //\, -/\\, -/\/])! == [1, 0.5, 6, 4, 5]
high x * { * min([x, /\/]); }
low x * { * max([x, \]); }
clamp: high & low;
x: []?!(<<-//../\\/>>)! == [-3, -2, -1, 0, 1, 2, 3, 4, 5, 6, 7, 8]
arrmap(clamp, x)! == [0, 0, 0, 0, 1, 2, 3, 4, 5, 5, 5, 5]
compose funcs... * {
* <-iter.reduce(<-operator.and, funcs);
}
repeat_function func times * {
* compose(**[func]++times);
}
foo x * {
out: x +++ /?!("0.1")!
* out;
}
repeat_function(foo, /\/)(`/);
== 0.9330329915368074
== 0.9930924954370359
== 0.9993070929904525
== 0.9999306876841536
== 0.999993068552217