1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253
|
\subsection{proc}
\label{labproc}
\noindent Name: \textbf{proc}\\
\phantom{aaa}defines a \sollya procedure\\[0.2cm]
\noindent Usage:
\begin{center}
\textbf{proc}(\emph{formal parameter1}, \emph{formal parameter2},..., \emph{formal parameter n}) \key{$\lbrace$} \emph{procedure body} \key{$\rbrace$} : \textsf{void} $\rightarrow$ \textsf{procedure}\\
\textbf{proc}(\emph{formal parameter1}, \emph{formal parameter2},..., \emph{formal parameter n}) \key{$\lbrace$} \emph{procedure body} \textbf{return} \emph{expression}; \key{$\rbrace$} : \textsf{void} $\rightarrow$ \textsf{procedure}\\
\textbf{proc}(\emph{formal list parameter} = ...) \key{$\lbrace$} \emph{procedure body} \key{$\rbrace$} : \textsf{void} $\rightarrow$ \textsf{procedure}\\
\textbf{proc}(\emph{formal list parameter} = ...) \key{$\lbrace$} \emph{procedure body} \textbf{return} \emph{expression}; \key{$\rbrace$} : \textsf{void} $\rightarrow$ \textsf{procedure}\\
\end{center}
Parameters:
\begin{itemize}
\item \emph{formal parameter1}, \emph{formal parameter2} through \emph{formal parameter n} represent identifiers used as formal parameters
\item \emph{formal list parameter} represents an identifier used as a formal parameter for the list of an arbitrary number of parameters
\item \emph{procedure body} represents the imperative statements in the body of the procedure
\item \emph{expression} represents the expression \textbf{proc} shall evaluate to
\end{itemize}
\noindent Description: \begin{itemize}
\item The \textbf{proc} keyword allows for defining procedures in the \sollya
language. These procedures are common \sollya objects that can be
applied to actual parameters after definition. Upon such an
application, the \sollya interpreter applies the actual parameters to
the formal parameters \emph{formal parameter1} through \emph{formal parameter n}
(resp. builds up the list of arguments and applies it to the list
\emph{formal list parameter}) and executes the \emph{procedure body}. The
procedure applied to actual parameters evaluates then to the
expression \emph{expression} in the \textbf{return} statement after the \emph{procedure body}
or to \textbf{void}, if no return statement is given (i.e. a \textbf{return}
\textbf{void} statement is implicitly given).
\item \sollya procedures defined by \textbf{proc} have no name. They can be bound
to an identifier by assigning the procedure object a \textbf{proc}
expression produces to an identifier. However, it is possible to use
procedures without giving them any name. For instance, \sollya
procedures, i.e. procedure objects, can be elements of lists. They can
even be given as an argument to other internal \sollya procedures. See
also \textbf{procedure} on this subject.
\item Upon definition of a \sollya procedure using \textbf{proc}, no type check
is performed. More precisely, the statements in \emph{procedure body} are
merely parsed but not interpreted upon procedure definition with
\textbf{proc}. Type checks are performed once the procedure is applied to
actual parameters or to \textbf{void}. At this time, if the procedure was
defined using several different formal parameters \emph{formal parameter 1}
through \emph{formal parameter n}, it is checked whether the number of
actual parameters corresponds to the number of formal parameters. If
the procedure was defined using the syntax for a procedure with an
arbitrary number of parameters by giving a \emph{formal list parameter},
the number of actual arguments is not checked but only a list
\emph{formal list parameter} of appropriate length is built up. Type checks are
further performed upon execution of each statement in \emph{procedure body}
and upon evaluation of the expression \emph{expression} to be returned.
Procedures defined by \textbf{proc} containing a \textbf{quit} or \textbf{restart} command
cannot be executed (i.e. applied). Upon application of a procedure,
the \sollya interpreter checks beforehand for such a statement. If one
is found, the application of the procedure to its arguments evaluates
to \textbf{error}. A warning is displayed. Remark that in contrast to other
type or semantic correctness checks, this check is really performed
before interpreting any other statement in the body of the procedure.
\item Through the \textbf{var} keyword it is possible to declare local
variables and thus to have full support of recursive procedures. This
means a procedure defined using \textbf{proc} may contain in its \emph{procedure body}
an application of itself to some actual parameters: it suffices
to assign the procedure (object) to an identifier with an appropriate
name.
\item \sollya procedures defined using \textbf{proc} may return other
procedures. Further \emph{procedure body} may contain assignments of
locally defined procedure objects to identifiers. See \textbf{var} for the
particular behaviour of local and global variables.
\item The expression \emph{expression} returned by a procedure is evaluated with
regard to \sollya commands, procedures and external
procedures. Simplification may be performed. However, an application
of a procedure defined by \textbf{proc} to actual parameters evaluates to the
expression \emph{expression} that may contain the free global variable or
that may be composed.
\end{itemize}
\noindent Example 1:
\begin{center}\begin{minipage}{15cm}\begin{Verbatim}[frame=single]
> succ = proc(n) { return n + 1; };
> succ(5);
6
> 3 + succ(0);
4
> succ;
proc(n)
{
nop;
return (n) + (1);
}
\end{Verbatim}
\end{minipage}\end{center}
\noindent Example 2:
\begin{center}\begin{minipage}{15cm}\begin{Verbatim}[frame=single]
> add = proc(m,n) { var res; res := m + n; return res; };
> add(5,6);
11
> add;
proc(m, n)
{
var res;
res := (m) + (n);
return res;
}
> verbosity = 1!;
> add(3);
Warning: at least one of the given expressions or a subexpression is not correct
ly typed
or its evaluation has failed because of some error on a side-effect.
error
> add(true,false);
Warning: at least one of the given expressions or a subexpression is not correct
ly typed
or its evaluation has failed because of some error on a side-effect.
Warning: the given expression or command could not be handled.
error
\end{Verbatim}
\end{minipage}\end{center}
\noindent Example 3:
\begin{center}\begin{minipage}{15cm}\begin{Verbatim}[frame=single]
> succ = proc(n) { return n + 1; };
> succ(5);
6
> succ(x);
1 + x
\end{Verbatim}
\end{minipage}\end{center}
\noindent Example 4:
\begin{center}\begin{minipage}{15cm}\begin{Verbatim}[frame=single]
> hey = proc() { print("Hello world."); };
> hey();
Hello world.
> print(hey());
Hello world.
void
> hey;
proc()
{
print("Hello world.");
return void;
}
\end{Verbatim}
\end{minipage}\end{center}
\noindent Example 5:
\begin{center}\begin{minipage}{15cm}\begin{Verbatim}[frame=single]
> fac = proc(n) { var res; if (n == 0) then res := 1 else res := n * fac(n - 1);
return res; };
> fac(5);
120
> fac(11);
39916800
> fac;
proc(n)
{
var res;
if (n) == (0) then
res := 1
else
res := (n) * (fac((n) - (1)));
return res;
}
\end{Verbatim}
\end{minipage}\end{center}
\noindent Example 6:
\begin{center}\begin{minipage}{15cm}\begin{Verbatim}[frame=single]
> myprocs = [| proc(m,n) { return m + n; }, proc(m,n) { return m - n; } |];
> (myprocs[0])(5,6);
11
> (myprocs[1])(5,6);
-1
> succ = proc(n) { return n + 1; };
> pred = proc(n) { return n - 1; };
> applier = proc(p,n) { return p(n); };
> applier(succ,5);
6
> applier(pred,5);
4
\end{Verbatim}
\end{minipage}\end{center}
\noindent Example 7:
\begin{center}\begin{minipage}{15cm}\begin{Verbatim}[frame=single]
> verbosity = 1!;
> myquit = proc(n) { print(n); quit; };
> myquit;
proc(n)
{
print(n);
quit;
return void;
}
> myquit(5);
Warning: a quit or restart command may not be part of a procedure body.
The procedure will not be executed.
Warning: an error occurred while executing a procedure.
Warning: the given expression or command could not be handled.
error
\end{Verbatim}
\end{minipage}\end{center}
\noindent Example 8:
\begin{center}\begin{minipage}{15cm}\begin{Verbatim}[frame=single]
> printsucc = proc(n) { var succ; succ = proc(n) { return n + 1; }; print("Succe
ssor of",n,"is",succ(n)); };
> printsucc(5);
Successor of 5 is 6
\end{Verbatim}
\end{minipage}\end{center}
\noindent Example 9:
\begin{center}\begin{minipage}{15cm}\begin{Verbatim}[frame=single]
> makeadd = proc(n) { var add; print("n =",n); add = proc(m,n) { return n + m; }
; return add; };
> makeadd(4);
n = 4
proc(m, n)
{
nop;
return (n) + (m);
}
> (makeadd(4))(5,6);
n = 4
11
\end{Verbatim}
\end{minipage}\end{center}
\noindent Example 10:
\begin{center}\begin{minipage}{15cm}\begin{Verbatim}[frame=single]
> sumall = proc(L = ...) { var acc, i; acc = 0; for i in L do acc = acc + i; ret
urn acc; };
> sumall;
proc(L = ...)
{
var acc, i;
acc = 0;
for i in L do
acc = (acc) + (i);
return acc;
}
> sumall();
0
> sumall(2);
2
> sumall(2,5);
7
> sumall(2,5,7,9,16);
39
> sumall @ [|1,...,10|];
55
\end{Verbatim}
\end{minipage}\end{center}
See also: \textbf{return} (\ref{labreturn}), \textbf{externalproc} (\ref{labexternalproc}), \textbf{void} (\ref{labvoid}), \textbf{quit} (\ref{labquit}), \textbf{restart} (\ref{labrestart}), \textbf{var} (\ref{labvar}), \textbf{@} (\ref{labconcat}), \textbf{bind} (\ref{labbind}), \textbf{getbacktrace} (\ref{labgetbacktrace}), \textbf{error} (\ref{laberror})
|