Functions
Like mathematical functions, Sidef's functions can be recursive, take arguments and return values.
1
func hello (name) {
2
say "Hello, #{name}!"
3
}
4
5
hello("Sidef")
Copied!
The special __FUNC__ keyword refers to the current function:
1
func factorial (n) {
2
if (n > 1) {
3
return (n * __FUNC__(n - 1))
4
}
5
return 1
6
}
7
8
say factorial(5) # prints: 120
Copied!

Closures

In Sidef, all functions are first-class objects which can be passed around like any other object. Additionally, all functions (including methods) are lexical closures.
1
func curry(f, *args1) {
2
func (*args2) {
3
f(args1..., args2...)
4
}
5
}
6
7
func add(a, b) {
8
a + b
9
}
10
11
var adder = curry(add, 1)
12
say adder(3) #=> 4
Copied!

Caching functions

By specifying the cached trait in a function (or method) declaration, Sidef will automatically cache it for you.
1
func fib(n) is cached {
2
return n if (n <= 1)
3
fib(n-1) + fib(n-2)
4
}
5
say fib(100) #=> 354224848179261915075
Copied!

Optional arguments

The parameters of a function can also be declared with a default value, which provides support for optional arguments.
1
func hello (name="Sidef") {
2
say "Hello, #{name}!"
3
}
4
5
hello() # prints: "Hello, Sidef!"
6
hello("World") # prints: "Hello, World!"
Copied!
The default value of a parameter is evaluated only when an argument is not provided for that particular parameter, and it can be any arbitrary expression:
1
func foo (a = 1.25.sqrt, b = 1/2) {
2
a + b
3
}
4
5
say foo() # prints the result of: sqrt(1.25) + 1/2
6
say foo(21, 21) # prints: 42
Copied!

Named parameters

This is a very nice feature borrowed from Perl 6 which allows a function to be called with named parameters, giving us the flexibility to put the arguments in no specific order:
1
func divide(a, b) {
2
a / b
3
}
4
5
say divide(b: 5, a: 35) # prints: 7
Copied!

Variadic functions

A slurpy variable in the form of *name can be used as a function parameter to collect the remaining arguments inside an array:
1
func f(*args) {
2
say args #=> [1, 2, 3]
3
}
4
5
f(1, 2, 3)
Copied!
Alternatively, by using a named variable in the form of :name, the arguments are collected inside an hash:
1
func f(:pairs) {
2
say pairs #=> Hash(a=>1, b=>2)
3
}
4
5
f(a => 1, b => 2)
Copied!

Typed parameters

A function can be declared with typed parameters, which are checked at run-time.
1
func concat(String a, String b) {
2
a + b
3
}
Copied!
Now, the function can only be called with strings as arguments:
1
say concat("o", "k") # ok
2
say concat(1, 2) # runtime error
Copied!
The typed parameters require a specific type of object, but they do not default to anything when no value is provided. This means that all typed-parameters are mandatory, unless a default value is provided:
1
func concat(String a="foo", String b="bar") {
2
a + b
3
}
4
5
say concat() # prints: "foobar"
6
say concat("mini") # prints: "minibar"
7
say concat(1, 2) # this is still a run-time error
Copied!
Last modified 1yr ago