2.1 - Functions

This tutorial will show you what is a function in Algoid and how to use it to make more reusable and more beautifull code.

synopsis

  1. prerequisite
  2. basics
  3. scope
  4. function
  5. parameters
  6. return
  7. anonymous functions
  8. it is your turn to play
  9. summary

  10. << back to tu(r)torials

prerequisite

Before reading this tutorial, it is important to have a good knowledge of: 1.3 - Loops1.4 - Variables

basics

What is a function and what is its goal ?
Long time ago, functions was called sub programs. And it was true, in fact functions are a piece of independent program.
So function are a group of code lines that are able to do something special.
The advantage of funcions is that functions can be used and used again, as often as you like.
Ok, but why independent ? Because function keep it own scope.... Yes, but what is a Scope ?

scope

In loop tutorial, we have seen that a block is a container of some code lines.
It represent a group of instruction that create a compound behaviour.
The other property of a block is that everything is created inside is accessible inside and inside a nested block ; when program come outside of the scope, the values are lost and variables become unaccessible.
It is called the scope of the block.
And a block inside another defines in fact a nested scope in another.
In fact the only non nested scope is the root one. The root scope is the first scope of you program. When Algoid launch your program, it creates a default and first scope called root.

 
scope: 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
// into the root scope
{
  // into the first nested scope child of root
  {
    // into the second nested scope child of first nested scope
  }
  // back to the first nested scope
}
// back to the root (I think we should)
 

And what about scope variables creations ?

 
scope: 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23

// nothing is accessible here
set a;
// now a is accessible
{
  // a is already accessible
  set b;
  // a is already accessible
  // b is now accessible too
  {
    // a is already accessible
    // b is already accessible too
    set c;
    // a is already accessible
    // b is already accessible too
    // c is now accessible too
  }
  // a is already accessible
  // b is already accessible too
  // but not c
}
// only a is accessible here not b and c
 

So, as functions has their own scopes, each variables created inside a function is not accessible from the outside.

function

A function can be declared as following :

 
function: 
  • 1
  • 2
  • 3
  • 4

function () {
};
 


We recognize the {} that defined a block (and then a scope).
Yes but what is the difference with a simple block.
The difference is : a function can have an identifier (a variable name in AL) and can be called from another point of the program (if the identifier is accessible, remember scopes).

 
yet another square: 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13

set square = function () {
  loop (4) {
    algo.go (100);
    algo.turnRight (90);
  }
};

// use it
square();
algo.jump(150);
square();
 

Interesting. We are now able to draw square each time we want.
To call the function we have just to give its name followed by parenthesis ().

Note : in AL function can be declared without assign it to a variable name.
It is not a usual way to design a language. Java, c, c++, pascal, ect. ect. that defines function like this :
void function square () { .... }
Ok, I completly assume this choice !!! You will see why in another tutorial about functional programming.
This choise is not conventional but so powerfull in fact.... I don't tell more at the moment.

parameters

We have seen we need parenthesis to declare a function and to call it.
Why are we need parentheses ?
To declare parameters !!!!
We have seen what are scope and that function has its own.
So to pass it values we need a way. This way is parameters.

Imagine we need to tell our square function the size of a side :

 
square parameter: 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14

set square = function (size) {
  loop (4) {
    algo.go (size);
    algo.turnRight (90);
  }
};

// use it
square(50);
square(100);
square(150);
square(200);
 


Yeah.... so we can re-use a block of code and it is possible to configure it to change some properties.
Now we can imagine a lots of think. Why not changind the number of side itself ?
Ok it is not a scare, why not a polygon :

 
polygon: 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14

set polygon = function (number, size) {
  loop (number) {
    algo.go (size);
    algo.turnRight (360 / number); // important to change the angle. A complete turn is 360 degree.
  }
};

// use it
algo.turnLeft(90);
polygon(4, 100); // nothing changed, already a square
polygon(3, 100); // yes but ....
polygon(5, 100); // why not ....
 


Play with parameters to create fun geomeritcs shapes.
So when you design you program with functions, they can have as many parameter as you want.
It is also possible to combine it with variables like this :

 
polygon loop: 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15

set polygon = function (number, size) {
  loop (number) {
    algo.go (size);
    algo.turnRight (360 / number); // important to change the angle. A complete turn is 360 degree.
  }
};

algo.turnLeft(90);

// use it in a for loop
for (set i = 2; i < 8; i++) {
  polygon (i, 100);
}
 


Possibilities are infinites. It only depends of your imagination.

return

Now imagine we need to create a function to calculate something.
We have to treat the result of the calculus. How it is possible to retreive it.
With the return instruction.

 
operation 1: 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10

set add5times = function (a, b) {
  set res = (a + b) * 5;
  return res;
};

ui.showLog();
util.log("(1 + 2) * 5 = " .. add5times(1, 2));
util.log("(2 + 3) * 5 = " .. add5times(2, 3));
 


Function return the result that will be used in the string concatenation to be written in the Algoid logger.
As every value in the language, it is also possible to use the function returning as parameter of another function or to assign it to a variable.

 
operation 2: 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19

set add = function (a, b) {
  return a + b;
};
set sub = function (a, b) {
  return a - b;
};

ui.showLog();
// calculate (1 + 2) - 3
set res = sub (add (1, 2), 3);
util.log("(1 + 2) - 3 = " .. res);

// calculate (1 + 2) - (8 - 7)
res = sub (add (1, 2), sub (8, 7));
util.log ("(1 + 2) - (8 - 7) = " .. res);

// ect.... ect....
 


Conclusion, parameters are the input of a function and return is the output.
A function, in AL and a lots of another languages, accept multiple parameters and only one returned value (but it is possible to turn around with arrays, see next tutorial).

it is your turn to play

ex1: reuse square

Re-use square function to draw a group of 4 cubes like this :

 
Solution: 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14

set square = function () {
  loop (4) {
    algo.go (100);
    algo.turnRight (90);
  }
  algo.turnLeft (90);
};

loop (4) {
  square();
}
// use step by step to understant how it works
 

ex2: reuse previous exercise

Re-use revious exercise to create a function to obtain :

 
Solution: 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19

set square = function () {
  loop (4) {
    algo.go (100);
    algo.turnRight (90);
  }
  algo.turnLeft (90);
};

set squareGroup = function () {
  loop (4) {
    square(); // function call other function
  }
}

squareGroup();
algo.turnLeft (45);
squareGroup();
 

ex3: stairecase

Thanks to Jean-Philippe Lemariey for this exercise, draw the following figure with two functions (stairStep and staireCase) :

 
Solution: 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20

set staireStep = function (size) {
  algo.go (size);
  algo.turnRight (90);
  algo.go (size);
  algo.turnLeft (90);
};

set staireCase = function (number, size) {
  loop (number) {
    staireStep(size);
  }
}

ui.showAlgo();
algo.goTo(-200, 200);
staireCase(4, 100);
algo.turnRight(180);
staireStep(400, 1);
 

ex4: stairecase

It gives me immediatly an idea :

 
Solution: 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24

set staireStep = function (size) {
  algo.go (size);
  algo.turnRight (90);
  algo.go (size);
  algo.turnLeft (90);
};

set staireCase = function (number, size) {
  loop (number) {
    staireStep(size);
  }
}

ui.showAlgo();
algo.goTo (-200, 100);

staireCase(4, 50);
algo.turnRight(90);
staireCase(4, 50);

algo.turnLeft(180);
algo.go(400);
 

ex5: random geometry

Re-use our polygon function to draw random geometry like this :

 
Solution: 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24

set polygon = function (number, size) {
  loop (number) {
    algo.go (size);
    algo.turnRight (360 / number);
  }
};

ui.showAlgo();

loop (10) {
  // create local variables
  set x = math.random(200) - 100;
  set y = math.random(200) - 100;
  set size = math.random (100);
  set number = math.random (10);
  set color = math.random (16);

  // draw
  algo.setColor(color);
  algo.goTo(x, y);
  polygon (number, size);
}
 


summary

Summary

In this tutorial, you have learned:

  • what is a scope ?
  • what is a function ?
  • how to write the previous examples with function refactoring ?
  • how to use it to make beautifull and reusable code ?

Functions used

FunctionDescription