Tutorial - Functions

From Mesham
Revision as of 12:35, 15 January 2013 by Polas (talk | contribs) (Created page with '== Introduction == In this tutorial we will be looking at the use of functions in Mesham, both writing our own functions and calling others. Functional abstraction is a very use…')
(diff) ← Older revision | Latest revision (diff) | Newer revision → (diff)
Jump to navigationJump to search

Introduction

In this tutorial we will be looking at the use of functions in Mesham, both writing our own functions and calling others. Functional abstraction is a very useful aspect to many languages and allows for one to make their code more manageable.

My first function

#include <io>
#include <string>

function Int myAddFunction(var a:Int, var b:Int) {
   return a+b;
};

function void main() {
   var a:=10;
   var c:=myAddFunction(a,20);
   print(itostring(c)+"\n");
};

The above code declares two functions, myAddFunction which takes in two Ints and return an Int (which is the addition of these two numbers) and a main function which is the program entry point. In our main function you can see that we are calling out to the myAddFunction using a mixture of the a variable and the constant value 20. The result of this function is then assigned to variable c which is displayed to standard output.

There are a number of points to note about this - first notice that each function body is terminated via the sequential composition (;) token. This is because all blocks in Mesham must be terminated with some composition and functions are no exception, although it is meaningless to terminate with parallel composition currently. Secondly, move the myAddFunction so that it appears below the main function and recompile - see that there is an error now? This is because we are attempting to use this function in the declaration of variable c and will infer the type from the function. If you wish to do this then the function must appear before that point in the code but if we just wanted to use the function in any other way then it can appear in any order. As an exercise place the myAddFunction after the main function and then explicitly type c to be an integer and on the following line assign the value of c to be the result of a call to the function - see that it now works fine. As a further exercise notice that we don't really need variable c at all - remove it and in the print function call replace the reference to c with the call to our own function itself.

Function arguments

By default all element types and records are pass by value, whereas arrays and reference records are pass by reference. This is dependant on the manner in which these data types are allocated, the former using the stack type whereas the later using the heap type. We can determine whether a function's arguments and return value are pass by value or reference by specifying the stack (value), static (value) or heap (reference) type in the chain.

#include <io>
#include <string>

function void main() {
   var a:=10;
   myChangeFunction(a);
   print(itostring(a)+"\n");
};

function void myChangeFunction(var mydata:Int) {
   mydata:=76;
};

If you compile and execute the following code, then you will see the output 10 which is because, by default, an Int is pass by value such that the value of a is passed into myChangeFunction which sets mydata to be equal to this. When we modify mydata, because it has entirely different memory from a then it has no effect upon a.

#include <io>
#include <string>

function void main() {
   var a:=10;
   myChangeFunction(a);
   print(itostring(a)+"\n");
};

function void myChangeFunction(var mydata:Int::heap) {
   mydata:=76;
};

This code snippet is very similar to the previous one, but we have added the heap type to the chain of mydata - if you compile and execute this you will now see the output 76. This is because, by using the heap type, we have changed to pass by reference which means that mydata and a share the same memory and hence a change to one will modify the other.