next up previous
Next: Caesar cipher redux Up: fsqFsHn sGGousG Previous: Simple Ciphers

Defining functions with proc; Local and global variables

We already know how to define functions in Maple. However, all of the functions we have defined so far have consisted of a single Maple expression (no matter how complicated it might be). For example,

> 
  sqr := x -> sqrt(x);


\begin{maplelatex}
\begin{displaymath}
\mathit{sqr} := \mathrm{sqrt}
\end{displaymath}\end{maplelatex}

> 
  sqr(25);


\begin{maplelatex}
\begin{displaymath}5 \end{displaymath}\end{maplelatex}

However, Maple has a more versatile way of defining functions using the proc command. The function sqr2 below behaves exactly the same as sqr defined above. (When using proc, the function begins with the keyword proc, followed by any parameters in parenthesis, then one or more Maple statements, and finally the keyword end. The result of the function is the result of the last Maple command executed.

> 
  sqr2 := proc(x)
     sqrt(x);
  end;


\begin{maplelatex}
\begin{displaymath}
\mathit{sqr2} := \textbf{proc} (x) \mathrm{sqrt}(x) \textbf{end
}
\end{displaymath}\end{maplelatex}

> 
  sqr2(25);


\begin{maplelatex}
\begin{displaymath}5 \end{displaymath}\end{maplelatex}

> 
  sqr2(-25);


\begin{maplelatex}
\begin{displaymath}
5 I
\end{displaymath}\end{maplelatex}

Unlike the functions defined by ->, however, we can use several statements when using proc:

> 
  sqr3 := proc(x)
    if (x >= 0) then
       sqrt(x);
    else
       print("The square root of ",x,"is not a real number");
    fi;
  end;


\begin{maplelatex}
\begin{eqnarray*}
\lefteqn{\mathit{sqr3} := \textbf{proc} (x)...
... number''}) 
\textbf{fi} \\
& & \textbf{end}
\end{eqnarray*}\end{maplelatex}

> 
  sqr3(-25);


\begin{maplelatex}
\begin{displaymath}
\mathit{The square root of },  -25,  \mathit{is not a real\
number}
\end{displaymath}\end{maplelatex}

> 
  sqr3(25);


\begin{maplelatex}
\begin{displaymath}5 \end{displaymath}\end{maplelatex}

Here is another variation on the same idea: we compute a variable y = x2. If y > 25, the result is 25, otherwise it is y. 4.12

> 
  mesa:= proc(x)
    y := x^2;
    if ( y>25) then
       25;
    else
       y;
    fi;
  end;


\begin{maplettyout}
Warning, \lq y\lq  is implicitly declared local
\end{maplettyout}


\begin{maplelatex}
\begin{displaymath}
\mathit{mesa} := \textbf{proc} (x) \text...
...textbf{else}  y
 \textbf{fi}  \textbf{end}
\end{displaymath}\end{maplelatex}

What does that warning mean? It means that Maple has assumed that the variable y used in mesa is local to that procedure. That is, it is different from a variable y that may be used outside the context of the procedure. Let's check that. First, we set y to 35, invoke mesa(19) (which sets its copy of y to 361), then check what the value of y is.

> 
  y:=35;


\begin{maplelatex}
\begin{displaymath}
y := 35
\end{displaymath}\end{maplelatex}

> 
  mesa(19);


\begin{maplelatex}
\begin{displaymath}
25
\end{displaymath}\end{maplelatex}

> 
  y;


\begin{maplelatex}
\begin{displaymath}
35
\end{displaymath}\end{maplelatex}

It is still 35. Now, let's add a line saying that y has a global definition-- the y within the procedure is the same as the y outside.

> 
  mesa2:= proc(x)
    global y;
  

  y := x^2;   if ( y>25) then   25;   else   y;   fi;   end;


\begin{maplelatex}
\begin{displaymath}
\mathit{mesa2} := \textbf{proc} (x) \tex...
...textbf{else}
 y \textbf{fi}  \textbf{end}
\end{displaymath}\end{maplelatex}

> 
  y;


\begin{maplelatex}
\begin{displaymath}
35
\end{displaymath}\end{maplelatex}

> 
  mesa2(19);


\begin{maplelatex}
\begin{displaymath}
25
\end{displaymath}\end{maplelatex}

> 
  y;


\begin{maplelatex}
\begin{displaymath}
361
\end{displaymath}\end{maplelatex}

This time, of course, y was indeed changed by invoking mesa2.


The opposite of global is, not surprisingly, local. In order to stop Maple from giving warnings about variables being implicitly declared local, we can add a the statement     local y;     just after the proc statement. Using such statements is called declaring the scope of the variables. This is a good habit to get into, because it lessens the chance of accidentally using a global variable or of misspelling the name of a variable. Some computer languages require that you declare all variables you use.


Another good habit to get into is to indicate what type of arguments the function will accept. This is optional in Maple, and not always desirable (you may not always know what they will be). This is done by specifying the type after two colons in the argument list. For example,

> 
  ith:=proc(l::list, i::posint)
    return(l[i]);
  end:

is a function that insists its first argument be a list, and the second must be a positive integer. If you call it with something else, you will get an error message.

> 
  ith("Henry",8);


\begin{maplettyout}
Error, invalid input: ith expects its 1st argument, l, to be of type list, but
received Henry
\end{maplettyout}



Footnotes

.... 4.12
Note that this could also be done using piecewise.

next up previous
Next: Caesar cipher redux Up: fsqFsHn sGGousG Previous: Simple Ciphers

Translated from LaTeX by Scott Sutherland
2002-08-29