Introduction Welcome Getting Started My First Program     Troubleshooting and Distributing Transforming Data Interactive Programs     Programming Exercises     Making Games
Documentation Declarations     Procedures     Variables Statements     Flow Control Expressions Libraries     Print     IO     Random     Game Engine
Tutorials Complete Tutorials     Introduction to Programming     Quick Start     Programming Exercises     Programming Games

PROCEDURES


All About Procedures in Vizzcode





What are Procedures and How to Create Them?

Procedures (also referred in other programming languages as sub-routines, functions or methods) are a body of code that be referenced by name.
They are very useful for reutilizing pieces of code, because you can execute all of that procedure's commands by simply calling its name.
Procedures may receive values from its callers and give them values as well.

Here is an example of creating a procedure called proc:

Declaring a procedure in Vizzcode
proc
:: () {

}
Procedures are declared by typing their name and then double colon ::
You can enter the parameters inside parenthesis () and return values after an optional ->
After that comes the block to be executed.

Here is how that procedure is called (and its body executed):

Calling a procedure in Vizzcode
...
proc
();
It's as simple as typing a procedure's name and the optional parameters inside ().

Note that a procedure can only be declared in the global scope and only be called in local scopes. Learn more about scopes here.

The entry point of the program (the code that automatically gets executed upon program start) is a procedure called main. You can learn more about the entry point here.




Why Use Procedures

As you create a program, you may notice that some code starts to be repeated multiple times, sometimes with very little modifications or no modification at all.
Besides having to type (or copy) the same thing multiple times, you're making the program bigger and harder to understand; you can also have the need to change that functionality. If you have to change it, you would have to remember all the places where that code is duplicated and modify all of them. As you can imagine, it can be very error-prone.
Procedures can also be used to recursively call themselves providing a useful tool for solving certain kinds of problems.

In this example, a procedure is created to calculate the factorial of a number. That procedure is called from multiple different places in the program that don't need to worry about how the factorial is calculated - because it's abstracted away inside the procedure.

#import
"IO"


factorial
:: (value :
int
) ->
int
{
    result :=
1
;
    
for
2
..var result *= it;
    
return
result;
}

main
:: () {
    
print_int
(
factorial
(
12
));
    
print_int
(
factorial
(
5
));
    
print_int
(
factorial
(
scan_int
(
"Type a number to calculate the factorial for "
)));
}




Parameters

Parameters are values provided to the procedure by the caller.
It essentially works as a variable being declared in the beginning of its scope and receiving the value from the caller.

They are specified inside the parenthesis () in the procedure declaration or (in the Visual Panel) specified as variable declarations from the Parameters pin in the Procedure Declaration Node.

For example, in this code, the procedure "display" receives an int as a parameter.

A program that uses procedures to simpliify its code
#import
"Print"


display
:: (number :
int
) {
    
print
(
"The number is: "
);
    
print_int
(number);
    
print
(
"\n"
);
}

main
:: () {
    
display
(
-10
);
    
display
(
-5
);
    
for
0
..
10
  
display
(it);
    
display
(
1000
);
}


The output of the program is the following:
The number is: -10
The number is: -5
The number is: 0
The number is: 1
The number is: 2
The number is: 3
The number is: 4
The number is: 5
The number is: 6
The number is: 7
The number is: 8
The number is: 9
The number is: 10
The number is: 1000

You can specify as many parameters as you need:

How to specify multiple parameters in Vizzcode
proc
:: (a :
int
, b :
int
, c :
string
, d :
bool
) {

}

Parameters can have default values by simply specifying a value in the parameter declaration.
If the parameter has a default value, the caller can choose to ignore it: if the caller doesn't provide a value, the default 'one' is used.
This can be combined with parameters with no default values.

How to use parameters with default values in Vizzcode
proc
:: (a :
int
, b := 123, c :
string
= "Hello") {

}

main
:: () {
    
proc
(
3
,
5
,
"Bye"
);
    
proc
(
1
,
7
);
    
proc
(
0
);
}

Because parameters have names, they can be used by the caller to change the order or simply make it clearer which values are being passed to which arguments.
proc
:: (a :
int
, b := 123, c :
string
= "Hello") {

}

main
:: () {
    
proc
(a =
3
, b =
5
, c =
"Bye"
);
    
proc
(b =
10
, a =
9
, c =
"Bye"
);
    
proc
(c =
"Test"
, a =
7
);
    
proc
(a =
0
);
}





Returns

Return values are values given back by the procedure to the caller.
They are specified after the parameters in the procedure declaration, following a ->
In the Visual Panel, they as specified as variable declarations connected to the Returns pin of a procedure.

A program that shows parameters and returns
#import
"IO"


sum
:: (a :=
0
, b :=
0
) ->
int
{
    
return
a + b;
}

main
:: () {
    
print_int
(
sum
(
5
,
6
));
    
print_int
(
sum
(
1
,
1
));
    
print_int
(
sum
(
100
,
scan_int
(
"Type a number to be added to 100: "
)));
}

Just like with parameters, you can return as many values as you need:

How to return multiple values in Vizzcode
multiply_and_add
:: (a :=
0
, b :=
0
) ->
int
,
int
{
    
return
a*b, a+b;
}

main
:: () {
    
multiply_and_add
(
10
,
20
);
    mul1 :=
multiply_and_add
(
5
,
10
);
    mul2, add2 :=
multiply_and_add
(
2
,
5
);
}
In order to retrieve more than one return value, the caller as to use a compound declaration. You can learn about it here.

You can also name the return values and refer to them in the return statement.

How name return values in Vizzcode
a
:: () -> (a :
int
, b :
float
) {
    
return
b =
5.6
, a =
4
;
}

You can also specify a default return value that will be used whenever you return from the function without specifying that value:

How to specify default return values in Vizzcode
proc
:: () -> (a :
int
=
4
, b :
float
) {
    
return
b =
5.6
;
}

Procedures that don't return any values can leave the return part of their declaration blank or specify a void return (in the Text Panel):
proc
:: () {

}

proc
:: () ->
void
{

}





Recursive Procedures

Recursive procedures are procedures that call themselves from within their bodies.
They can be very useful to solve certain problems.
For example, you can calculate a factorial using loops this way:
factorial
:: (value :
int
) ->
int
{
    result :=
1
;
    
for
2
..var result *= it;
    
return
result;
}

The same algorithm can be implemented using recursion:
factorial
:: (value :
int
) ->
int
{
    
if
n <=
1
return
1
;
    
return
value *
factorial
(value-
1
);
}

Note how the procedure has a case where it doesn't recurse. This makes sure that the procedure won't loop indefinitely.