6 Loops and Functions

In this section, we take on the task of writing a function that computes square roots. This will lead us to consider conditional looping and the definitions of functions, or in BETA terms, patterns that can return values.

To compute a square root we will use Newton's algorithm where the computation is done by successive approximations until the error is less than a preset level (epsilon).

The usual way to program this involves a while loop. In C, the code to get the root of X could look like this:

Root= X;
while (abs(X-Root**2) > epsilon) {
  Root= (Root+X/root) / 2;
}

Assuming that X = 100, the calculated values of Root in each iteration will be:

150.5
226.2401
315.0255
410.8404
510.0326
610.0001
710.0000... and the loop ends.

Surprisingly, there is no while loop in BETA language. BETA is designed with a more fundamental (and extensible) feature as the ability to either leave or restart any labeled imperative. In the basic BETA environment betaenv, a loop pattern using these features is defined and can be used like:

X -> Root;
Loop(# while::(# do (X-Root*Root -> fabs) > X / 10E6 -> value #);
    do (Root + X/root) / 2 -> root;
    #);

A while loop can also directly be implemented using a labeled imperative with a restart. The following BETA code is a repeated conditional imperative implemented using a labeled if with a restart imperative at the end:

X -> Root;
L: (if (X-Root*Root -> fabs) > X / 10E6 then
       0.5 * (Root + X div Root) -> Root;
       restart L;
   if);

Here, the error, epsilon, is set at one part in a million. The complete program code is given in Program 5 below. Here the code for the Square Root has been put in the form of a procedure which returns a value: that is to say a function. As shown in the example, a function call has the following syntax:

i -> Sqrt -> Res;

We have already seen the notation <parameters> -> <procedure> whereby data is passed (as parameters) to the procedure object. In BETA, the same syntax is used to show that results are obtained from Sqrt and passed on to Res.

Program 7: SquareRoot.bet

ORIGIN '~beta/basiclib/betaenv';
INCLUDE '~beta/basiclib/numberio'
        '~beta/basiclib/math';
---- program: descriptor ----
(# 
   
   (*  SquareRoot.bet: Exploring functions
    *                  + conditional loops
    ***********************************************************)
   
   Res: @real;
   
   Sqrt: 
     (# X, Root: @real;
     enter X
     do X->Root;
        Loop(# while:: (# do (X-Root*Root->fabs) > (X / 10E6)->value #)
            do (Root + X/root) / 2->root;
            #);
     exit Root
     #);
   
   tab: 
     (# N: @integer;
     enter N
     do (for N repeat ' '->put for)
     #);
   
do '\n\t ** Functions and variables **\n'->putline;
   ' I   sqrt(i) '->putline;
   (for i: 10 repeat
        i->Sqrt->Res;
        i->screen.putint(# format:: (# do 2->width#)#);
        3->tab;
        Res->putreal;
        newline;
   for)
#)

The declaration of Sqrt shows an exit list which defines the list of values obtained after executing the body of the function. In this case, there is only one value, a real, but BETA functions could return multiple results.

The output obtained upon execution are shown below.

** Functions and variables **

 I   sqrt(i) 
 1   1.000000
 2   1.414214
 3   1.732051
 4   2.000000
 5   2.236068
 6   2.449490
 7   2.645751
 8   2.828427
 9   3.000000
10   3.162278


Libraries Tutorial
© 1994-2004 Mjølner Informatics
[Modified: Thursday January 16th 2003 at 10:23]