A new minor release of ABS: always be shipping! 🚢
Named functions
Functions can now be "named":
f my_func(x) {
return x**2
}
Earlier, you would have had to assign
the function to a variable:
my_func = f(x) {
return x**2
}
while right now function names are first-class
citizens. For example, the string representation
of a function will actualy include its name (to be
included in stacktraces as well):
⧐ f test() {echo(1)}
f test() {echo(1)}
Decorators
A decorator is a plain-old function that
accepts 1 + N
arguments, where 1
is the
function being wrapped, and returns a new
function that wraps the original one:
f log_if_slow(original_fn, treshold_ms) {
return f() {
start = `date +%s%3N`.int()
res = original_fn(...)
end = `date +%s%3N`.int()
if end - start > treshold_ms {
echo("mmm, we were pretty slow...")
}
return res
}
}
That's as simple as that: a named function
that returns a new function that executes the
decorated one (original_fn
) and returns its
result, while logging if it takes longer than
a few milliseconds.
Now that we've declared our decorator, it's time
to use it, through the @
notation:
@log_if_slow(500)
f return_random_number_after_sleeping(seconds) {
`sleep $seconds`
return rand(1000)
}
and we can test our decorator has takn the stage:
⧐ return_random_number_after_sleeping(0)
493
⧐ return_random_number_after_sleeping(1)
mmm, we were pretty slow...
371
Accessing a function's arguments
Functions can receive a dynamic number of arguments,
and arguments can be "packed" through the special
...
variable:
f sum_numbers() {
s = 0
for x in ... {
s += x
}
return s
}
sum_numbers(1) # 1
sum_numbers(1, 2, 3) # 6
...
is a special variables that acts
like an array, so you can loop and slice
it however you want:
f first_arg() {
if ....len() > 0 {
return ...[0]
}
return "No first arg"
}
first_arg() # "No first arg"
first_arg(1) # 1
When you pass ...
directly to a function,
it will be unpacked:
f echo_wrapper() {
echo(...)
}
echo_wrapper("hello %s", "root") # "hello root"
and you can add additional arguments as well:
f echo_wrapper() {
echo(..., "root")
}
echo_wrapper("hello %s %s", "sir") # "hello sir root"
Call a function with an array of arguments
call
calls a function "spreading" the array of arguments into the function's arguments:
multiplier = f(x, y) { x * y }
multiplier.call([10, 2]) # 20