## Programming

### Overview

User defined functions may be transformed into programs by using the `if, if-else, for, while, return, break, switch, do-while` and `continue` statements along with the opening "{" and closing "}" brackets.

Printing intermediate values is done by using functions `printf()`, `sprintf()`, `print()`, or `println()`.

The basic rules are:

• No need to declare variables. In fact, as seen above, all variables have a mutable nature; they can be redefined.
• It is an error to try to use a variable that has not been defined yet.
• If you need to enter several statements, open a block by entering a "{" and placing a "`;`" after each statement. Close the block with a "}".
• If no `return` keyword is found when evaluating the function, the value returned is a value of type void.
• All variables defined in a function have local scope.
• If a variable is not found in the function scope, the symbol is searched in the next enclosing scope.
• Functions can be passed as arguments.
• All parameters are passed by reference. If an argument is a constant, a dummy copy is passed.
• You may define functions inside functions.
• Commentaries are entered using `//` or `#`. Everything after `//` or after `#` is discarded (until the end of line).

Here is an simple example program that finds the roots of a quadratic equation of the form a*x^2 + b*x + c = 0. Notice that this program is a function that returns either a scalar value or a vector depending on the value of a.

```   //------------------------------------------
// Roots of a quadratic equation
//------------------------------------------
quaroot(a,b,c) = {
if( a==0 ) {
println( "a == 0." );
return -c/b;
}
x1 = (-b + sqrt(b*b-4*a*c))/(2*a);
x2 = (-b - sqrt(b*b-4*a*c))/(2*a);
return (x1, x2);
}
```

User defined function can be used like any other library function:

a=3; b=2; c=-3;
quaroot(a,b,c)
0.7208  -1.3874

You may create functions using other used defined functions. The next example program plots the quadratic function and prints the roots.

```   //------------------------------------------
// Plot and roots, quadratic equation
//------------------------------------------
quaplot(a,b,c) = {
x = quaroot(a,b,c);
sort(x);
x1 = x;
x2 = x;
println( "Plot of quadratic equation" );
println( "Roots are:" );
println( "x1=", x1, " x2=", x2 );

if( x1.isComplex() ) {
x1 = 0;
x2 = 10;
}
else {
x1 = x1-2;
x2 = x2+2;
}

// Create the function and plot it
f(x) = a*x*x + b*x + c;
plot( f, x1, x2, 100, "red", "canvas:lightGray" );
}
```

Next example is a function that modifies the calling argument.

```   //------------------------------------------
// Modify calling argument
//------------------------------------------
g(x) = {
if( x<0 )
x = -x;
else
x = x*x;
return x;
}
```

An example of using this function follows.

a = 8
8
g(a)
64
a
64

### The `global` keyword

Calcugator programs have a different rule than simple user-defined functions.

While simple functions resolve symbols by looking into the global scope, user-defined programs look in the local scope. The next example shows this issue:

a = 8
8
f(x)={ return x*a; }
Identifier "a" is not defined.
f(x)={ return a*x; }
^

The reason for the error above is that variable `a` was not found in the local scope of function `f`. If you need to access variables located in the global scope, use the `global` keyword:

a = 8
8
f(x)={ global a; return x*a; }
f(x)={ global a; return x*a; }
f(3)
24

If you need to create local variables, follow the pattern below:

a = 8
8
f(x)={ a=3; return x*a; }
f(x)={ a=3; return x*a; }
f(5)
15
a
8

Notice that in the example above there are two variables with the same name. Variable `a` located in the global scope has a value equal to 8 while variable `a` located in the local scope of function `f` has a value of 3.

Notice that the value of `a` in the global scope was not modified.

There is no need to use the `global` keyword to access library functions or user-defined functions.

### Argument passing

All arguments are passed by reference. The next example shows the feature.

Example:

f(x)={ if(x<0) x=x*x; else x=x+4; return x; }
f(x)={ if(x<0) x=x*x; else x=x+4; return x; }
a = 5
5
f(a)
9
a
9
f(3)
7

Notice that the call `f(a)` changed the value of variable `a`. The reason is that variable `x` in scope of function `f` becomes a reference of variable `a`.

Also notice the call to `f(3)`. In the latter call, Calcugator takes care of the making variable `x` a reference to a temporary variable that is initialized with the value `3`.

### Operators

Calcugator implements a basic set of operators allowing the construction of expressions involving matrices, arrays, vectors, complex numbers, real numbers, and boolean values. Some operators have synonyms, for example the exponential operator is either `^` or `**` (for the nostalgic FORTRAN lover).

 Operator Description `! a` Negates the boolean expression `a`. `~ a` Negates the boolean expression `a`. `- a` Changes the sign of expression `a`. `int a` Removes the decimal part of expression `a`. `++a, a++` Increments `a` by one. See Note 1 below. `--a, a--` Decrements `a` by one. See Note 1 below. `a^b` Raises `a` to the power `b`. `a**b` Raises `a` to the power `b`. `a*b` Computes the multiplication of `a` times `b`. `a/b` Computes the division of `a` by `b`. `a mod b` Computes the residue of dividing `a` by `b`. `a cross b` Computes the cross product of vectors `a` and `b`. `a dot b` Computes the dot product of vectors `a` and `b`. `a + b` Computes the addition of `a` and `b`. `a - b` Computes the subtraction of `a` and `b`. `a < b` Returns true if `a` is smaller than `b`. `a <= b` Returns true if `a` is smaller or equal to `b`. `a > b` Returns true if `a` is greater than `b`. `a >= b` Returns true if `a` is greater or equal than `b`. `a == b` Returns true if `a` is equal to `b`. `a != b` Returns true if `a` is not equal to `b`. `a || b` Returns true if either `a` or `b` is true. `a or b` Returns true if either `a` or `b` is true. `a && b` Returns true if both `a` and `b` are true. `a and b` Returns true if both `a` and `b` are true. `a xor b` Exclusive or of operands `a` and `b`. `a -> b` Returns the implication of `a` and `b`. `a then b` Returns the implication of `a` and `b`. `a iff b` Returns the equivalence of `a` and `b`. `a = b` Assigns a copy of `b` to `a`.

Note 1: The decrement/increment operators are limited to a expressions with a single identifier.

Strict rules of precedence and associativity are enforced when parsing expressions. The table below shows the rules adopted by the Calcugator language.

 Operator Precedence Associates from the `!, ~, -(unary), int` high right `++, --` right `**, ^` right `*, /, mod, cross` left `dot` left `+, -` left `<, <=, >, >=` left `==, !=` left `||, or, &&, and, xor` left `->, then, iff` left `=` low right

### The if statement

The if statement has two forms:

```   if( test ) expr;

if( test ) expr1; else expr2;
```

Expression test must be a boolean expression. Any of the expressions expr, expr1 and expr2 can be a single statement or a block of statements. You may nest if statements.

Example:

```   if( x<0 )
return "x is negative";
```

Example:

```   if( x<0 and -2<x )
return;
else
x++;
```

Example:

```   p = q or (x>0);
if( p )
if( q ) {
x = 2;
y = sqrt(s*s-2);
}
else
return "No";
else
print( "No data" );
```

### The for statement

The form of the for statement is:

```   for( expr1; test; expr2 ) expr3;
```

Expression test must be a boolean expression. Both expressions expr1 and expr2 must be single expressions. Calcugator does not define a comma (",") operator like C/C++. Expression expr3 may be a single expression or a block of expressions.

Example:

```   j = size(a);
for( i=1; i<n and i<j; i++ ) {
s = s + i*j;
a[i] = a[i]*s;
}
```

A continue statement forces a loop and a break statement causes an immediate exit of the loop.

Example:

```   for( i=1; i<n; i++ ) {
if( i==n )
continue;
a[i] = a[i]*s;
if( a[i]<=0 )
break;
}
```

### The while statement

The form of the while statement is:

```   while( test ) expr;
```

Expression test must be a boolean expression and expression expr may be a single expression or a block of expressions.

Example:

```   p = q or r;
while( p ) {
if( q )
i++;
else {
p = a[i]>a[j];
q = (a[i] mod 2)==0;
}
}
```

A continue statement forces a loop and a break statement causes an immediate exit of the loop.

Example:

```   while( isComplex(z[i]) ) {
println( "z=", z[i] );
z[i] = z[i] + 0.25j;
i++;
if( abs(z[i])<1 )
continue;
if( i>10 )
break;
}
```

### The do-while statement

The form of the do-while statement is:

```   do exrp; while( test );
```

Expression expr may be a single expression or a block of expressions. Expression test must be a boolean expression.

Example:

```   p = q or r;
do {
if( q )
i++;
else {
p = a[i]>a[j];
q = (a[i] mod 2)==0;
}
} while( p and q );
```

A continue statement forces a loop and a break statement causes an immediate exit of the loop.

Example:

```   do {
println( "z=", z[i] );
z[i] = z[i] + 0.25j;
i++;
if( abs(z[i])<1 )
continue;
if( i>10 )
break;
} while ( isComplex(z[i]) );
```

### The switch statement

The switch statement has two forms:

```   switch( expr ) {
case test_1 :
expr_1;
case test_2 :
expr_2;
...
case test_n :
expr_n;
}

switch( expr ) {
case test_1 :
expr_1;
case test_2 :
expr_2;
...
case test_n :
expr_n;
default :
default_expr;
}
```

Expression expr must be a single expression. Expressions test_1, test_2,... test_n must be single expressions. Expressions expr_1, expr_2,... expr_n and default_expr can be single expressions or block of statements. Consult a C/C+++/java reference to learn on how a switch statement works.

Example:

```   switch( x<y ) {
case true:
println( "It's true" );
break;
case false:
println( "It's false" );
break;
}
```

Example:

```   switch( t ) {
case x+y:
a = 9;
break;
case abs(z):
a = 8;
break;
default:
a = 7;
}
```

Calcugator's implementation is a generalization of the C/C++ switch version for it allows non integer and non constants expressions. The use of a break statement is supported as well as the use of "cascading" cases.

Example:

```   switch( true ) {
case x<y :
case isVector(z):
return s;
case y>=x :
case !isVector(z) :
return t;
}
```

### The return statement

The return statement works like in C/C++/java. However, Calcugator allows functions to return different types from the same function including function objects.

Next example illustrates the case in which you can create your own sin function following MATLAB's1 conventions. Let's call the function Sin:

Example:

```   Sin( a ) = {
if( isArray(a) or isMatrix(a) ) {
// Work on a copy
acopy = a;
return apply(acopy,sin);
}
if( isScalar(a) )
return sin(a);
}
```

Function Sin defined above returns an array or a matrix or a scalar depending on the argument used. For any other type, the result would be void.

a = pi/2;
Sin(a)
1.0
b = ( pi/2, -pi/2 );
Sin(b)
1.0  -1.0

The following function illustrates how returning functions may be very helpful. Let's assume we want to compute a function that computes the central derivative of a given function.

Example:

```   CentralDeriv( f, h ) = {
df(x) = (f(x+h)-f(x-h))/(2*h);
return df;
}
```

We test this function with the library function sin using h=0.0001. A check is made using the fact that cos is the exact derivative.

dsin = CentralDeriv( sin, 0.0001 )
dsin(x) = (sin(x + 0.0001)
- sin(x - 0.0001) / (2 * 0.0001);
dsin(.7)
0.7648
cos(.7)
0.7648

### Using arrays, lists, stacks

Arrays can also behave like lists or stacks.

To create an empty list or stack named `a`, do the following:

a=()
()

Array `a` is now an empty stack or list. Let's use array `a` as an stack.

You may now push any kind of value on "top" of the stack. For example, we may push a string, some numbers and an array:

push(a, "ABC")
"ABC"
push(a, 4/5)
"ABC"  4/5
push(a, 7.2)
"ABC"  4/5  7.2
push(a, (3,3))
"ABC"  4/5  7.2  ( 3, 3 )

The stack now has 4 elements:

size(a)
4

To retrieve the data stored in the stack use the function `pop`:

x = pop(a)
3  3

The call to `pop` removes the last pushed element on the stack. The size of the stack reduces by one.

You may use these functions with stacks and lists:

• `a=()` defines `a` to be an empty stack or list.
• `push(a,b)` pushes object `b` on "top" of the stack `a`.
• `x=pop(a)` returns the last pushed object on the stack `a` removing it from the stack.
• `x=peek(a)` returns the last "pushed" object on the stack `a` without removing it.
• `size(a)` returns the number of objects stored on the stack `a`.
• `pushf(a,b)` pushes object `b` at the "front" of the stack `a`.
• `x=popf(a)` returns the object at the "front" of the stack and removes it from the stack `a`.
• `x=peekf(a)` returns the object at the "front" of the stack `a` without removing it.

You may use arrays as lists too. List oriented functions are:

• `insert(a, value, index)` inserts object `value` at index `index` in array `a`.
• `remove(a, index)` removes the object located at index `index` in array `a`.

Using an array as a list or as an stack doesn't stop you from using the square brackets to modify or use any entry of the array.

Example:

Given an input array `a`, the program below returns an array with all entries `a[i]` such that `a[i]<5`:

```// --------------------------------------
// Given array "a", returns an array with
// all entries smaller than 5
// --------------------------------------
condition(a) = {
b = ();           // Empty stack
for( i=1; i<=size(a); i=i+1 ) {
c = a[i];
if( c<5 )     // Test if c is smaller than 5
push(b, c);
}
return b;
}
```

For example, given:

a=(9, 4, 1, 3, 7, 8, 2, 6)
9  4  1  3  7  8  2  6

Using the program `condition` we obtain:

b = condition(a)
4  1  3  2

What if we need to return all entries that hold a condition other than "less than 5"? In that case you may change the test condition in the program but a better solution consist of passing the condition as a function.

The new version is as follows:

```// --------------------------------------
// Given array "a", returns an array with
// all entries "x" such "f(x)" is true.
// --------------------------------------
condition2(a, f) = {
b = ();           // Empty stack
for( i=1; i<=size(a); i=i+1 ) {
c = a[i];
if( f(c) )     // Test if f(c) is true
push(b, c);
}
return b;
}
```

Let's test this program using the condition "greater than 5". A suitable function is:

f(x) = x>5
f(x) = x>5

Using the `condition2` program we obtain:

b= condition2(a, f)
9  7  8  6

### Predicates

Predicates are a set a query functions used inside programs. These functions may i nform about the type or value of an object.

• `isArray(obj)` returns true if object `obj` is an array.
• `isBool(obj)` returns true if object `obj` stores a boolean value.
• `isComplex(obj)` returns true if object `obj` is a complex number.
• `isContinuousDistribution(obj)` returns true if `obj` is a continuous distribution object.
• `isDiagonal(obj)` returns true if `obj` is a diagonal matrix.
• `isDiscreteDistribution` returns true if `obj` is a discrete distribution object.
• `isDistribution` returns true if `obj` is a distribution object.
• `isEven(obj)` returns true if object `obj` is an even integer.
• `isFunction(obj)` returns true if object `obj` is a function (library or user defined).
• `isHermitian` returns true if `obj` is a Hermitian matrix.
• `isInteger(obj)` returns true if object `obj` is an integer.
• `isMatrix(obj)` returns true if object `obj` is a matrix.
• `isOdd(obj)` returns true if object `obj` is an odd integer.
• `isPositiveDefinite` returns true if `obj` is a positive definite matrix.
• `isRational(obj)` returns true if object `obj` is a rational number.
• `isReal(obj)` returns true if object `obj` is a real number but it is not integer nor rational.
• `isScalar(obj)` returns true if object `obj` is a scalar. An object is scalar if it is real or complex or integer or rational.
• `isString(obj)` returns true if object `obj` is a string.
• `isSymmetric` returns true if `obj` is a symmetric matrix.
• `isUnity` returns true if `obj` is unity or a unitary matrix.
• `isVector(obj)` returns true if object `obj` is a three-dimensional vector.
• `isZero(obj)` returns true if object `obj` is zero scalar or zero matrix.

To test for unity, zero, infinity or NaN, you may directly compare an object with `1`, `0`, `Infinity` or `NaN` using the comparison operators. For example:

x=-1/0
-Infinity
5>x
true
Infinity==NaN
false

### Examples

```//----------------------
// Factorial of a number
//----------------------
f(x) = {
if( !isInteger(x) )
return "Argument must be an integer";
if( x==1 || x==0 ) return 1;
if( x<0 )
return "Integer must be 0 or bigger";
y = x;
res = 1;
while( y>1 ) {
res = res*y;
y = y - 1;
}
return res;
}

#----------------------------------------------
# Root of a function. Bisection method
# notice function f(x) is passed as a parameter
#----------------------------------------------
root( f, a, b, tol ) = {
fa = f(a);
fb = f(b);
if( fa * fb > 0 )
return "Can not find a root in given interval";
x  = (a + b)/2.;
fx = f(x);
while( abs(fx) > tol ) {
if( fa * fx < 0 ) {
fb = fx;
b  = x;
}
else {
fa = fx;
a  = x;
}
x  = ( a + b )/2.;
fx = f(x);
}
return x;
}
```

(1) MATLAB © is a registered mark of the MathWorks.