Function
- A Function is a collection of statements or a block of code which can be run anytime and anywhere we like.
- Of course, anywhere implicitly assumes that the function is declared in the same scope or an outer scope, just like variables.
-
Ari's functions are first class citizens, meaning that they can be stored in variables and passed around as arguments to other functions.
-
Function names can only contain numbers, alphabets, and the underscore
_
. Also, names cannot begin with a number;
Declaration ¶
- The
fn
keyword indicates the declaration of a new function. -
Declaration syntax must consist of:
-
fn
keyword - functions's name
- a pair of curved brackets which represent's the function's arguments/parameters
- a pair of curly brackets which represent's the functions's scope
1 2 3 4 5 6 7 8 9 10 11
fn function_no_arguments() { println "A"; } fn function_1_argument(a) { println a / 10; } fn function_2_arguments(a, b) { println a + b; }
-
-
Call/invoke the function by specifying the arguments inside a pair of curved brackets and placing them to the right of the function.
1 2 3
function_no_arguments(); function_1_argument(20); function_2_arguments("Good ", "morning");
-
We can redeclare the same function as many times as we like.
1 2 3 4 5 6 7 8 9 10 11 12 13
fn do_something() { println "A"; } fn do_something() { println "B"; } fn do_something() { println "C"; } do_something(); // Prints C
return¶
- A
return
keyword quits the function and returns to where the function was last called. -
The program below does not print anything because
return
stops the loop.1 2 3 4 5
fn hello() { return; println "hello"; } hello();
-
A Function can return any kind of value:
1 2 3 4
fn hello() { return "Hello"; } println hello();
-
For multiple return values, return an array instead:
1 2 3 4 5 6 7
fn hello() { let a = "Hello"; let b = " there"; return [a, b]; } let array_value = hello(); println array_value[0] + array_value[1];
Info
-
If the function returns nothing,
return
is not required.1 2 3 4
fn func() { // do something return; }
should become:
1 2 3
fn func() { // do something }
First class functions¶
-
Functions can be stored inside variables:
1 2 3 4 5
fn add_two_numbers(a, b) { println a + b; } let my_variable = add_two_numbers; my_variable(10, 30); // Prints 40
-
Functions can also return other functions:
1 2 3 4 5 6 7 8
fn outer_function() { fn inner_function(a) { println a * 10; } return inner_function; } let my_function = outer_function(); my_function(7); // Prints 70
Closures¶
- First class functions keep a copy of their outer scope.
- This copy is cloned together with the function if it is assigned to other variables.
The program below is a good demonstration of closures:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 |
|
-
Line 1 declares a function
makeCounter(interval)
which returns a counter. This counter has access to the outer variable,i
, because of the closure property. -
makeCounter(interval)
offers the option to set the interval of the counter using theinterval
argument. -
Line 2 explicitly declares the
interval
argument in the closure so that the counter has access to it. -
Line 11 creates
counter1
which has an interval of 1. -
Lines 12 to 14 prints 1, 2 and 3 respectively because the counter has an interval of 1.
-
Line 16 creates
counter5
which has an interval of 5. -
Lines 17 to 19 prints 5, 10 and 15 respectively because the counter has an interval of 5.
-
Line 21 declares
counter5_copy
which is a copy ofcounter5
. Take note that thei
ofcounter5
is 15 at this point. The closure property causescounter5_copy
to also inherit ani
of 15. -
Lines 22 to 24 prints 20, 25 and 30 respectively because
counter5_copy
starts from ani
of 15. -
Line 26 prints 20 because the
i
ofcounter5
was 15 before this line was executed.
Beware of undeclared closure variables:
-
When returning a function, A, as a value from another function, B, we cannot expect A to capture the arguments of B automatically.
-
Instead, we need to explicitly declare the argument in the closure so that A can inherit it. Refer to Line 2 of the previous example.
-
The program below is similar to the previous example but Line 2 is commented out.
1 2 3 4 5 6 7 8 9 10 11 12 |
|
- Line 12 results in an error shown below because
count()
cannot capture theinterval
argument: