\chapter{Control flow}
\label{chap:hp-ctrlflow}

The primary means for controlling the flow of execution in a hansl
script are the \cmd{if} statement (conditional execution), the
\cmd{loop} statement (repeated execution), the \cmd{catch} modifier
(which enables the trapping of errors that would otherwise halt
execution), and the \cmd{quit} command (which forces termination).

\section{The \cmd{if} statement}

Conditional execution in hansl uses the \cmd{if} keyword. Its fullest
usage is as follows
\begin{code}
if <condition>
   ...
elif <condition>
   ...
else 
   ...
endif  
\end{code}

Points to note:
\begin{itemize}
\item The \texttt{<condition>} can be any expression that evaluates to a
  scalar: 0 is interpreted as ``false'', non-zero is interpreted as
  ``true''; \texttt{NA} generates an error.
\item Following \cmd{if}, ``then'' is implicit; there is no \texttt{then}
  keyword as found in, e.g., Pascal or Basic.
\item The \cmd{elif} and \cmd{else} clauses are optional: the minimal
  form is just \texttt{if} \dots{} \texttt{endif}.
\item Conditional blocks of this sort can be nested up to a maximum
  depth of 1024.
\end{itemize}

Example:
\begin{code}
scalar x = 15

# --- simple if ----------------------------------
if x >= 100
   printf "%g is more than two digits long\n", x
endif

# --- if with else -------------------------------
if x >= 0
   printf "%g is non-negative\n", x
else
   printf "%g is negative\n", x
endif

# --- multiple branches --------------------------
if missing(x)
   printf "%g is missing\n", x
elif x < 0
   printf "%g is negative\n", x
elif floor(x) == x
   printf "%g is an integer\n", x
else
   printf "%g is a positive number with a fractional part\n", x
endif
\end{code}

Note, from the example above, that the \cmd{elif} keyword can be
repeated, making hansl's \cmd{if} statement a multi-way branch
statement. There is no separate \cmd{switch} or \cmd{case} statement
in hansl. With one or more \cmd{elif}s, hansl will execute the first
one for which the logical condition is satisfied and then jump to
\cmd{endif}.

\tip{Stata users, beware: hansl's \cmd{if} statement is fundamentally
  different from Stata's \texttt{if} option: the latter selects a
  subsample of observations for some action, while the former is used
  to decide if a group of statements should be executed or not;
  hansl's \cmd{if} is what Stata calls ``branching \texttt{if}''.}


\subsection{The ternary query operator}

Besides use of \texttt{if}, the ternary query operator, \texttt{?:},
can be used to perform conditional assignment on a more ``micro''
level. This has the form
\begin{code}
result = <condition> ? <value-if-true> : <value-if-false>
\end{code}

If \texttt{<condition>} evaluates as ``true'' (non-zero) then the
first following value is assigned to \texttt{result}, otherwise the
value after the colon is so assigned.\footnote{Some readers may find
  it helpful to note that the conditional assignment operator works in
  exactly the same way as the \texttt{=IF()} function in
  spreadsheets.}  This is obviously more compact than \texttt{if}
\dots{} \texttt{else} \dots{} \texttt{endif}. The following example
replicates the \cmd{abs} function by hand:
\begin{code}
scalar ax = x>=0 ? x : -x
\end{code}
Of course, in the above case it would have been much simpler to just
write \texttt{ax = abs(x)}. Consider, however, the following case,
which exploits the fact that the ternary operator can be nested:
\begin{code}
scalar days = (m==2) ? 28 : maxr(m.={4,6,9,11}) ? 30 : 31
\end{code}
This example deserves a few comments. We want to compute the number of
days in a month, coded in the variable \texttt{m}. The value we assign
to the scalar \texttt{days} comes from the following pathway.
\begin{enumerate}
\item First we check if the month is February (\texttt{m==2}); if so,
  we set \texttt{days} to 28 and we're done.\footnote{OK, we're ignoring
    leap years here.}
\item Otherwise, we compute a matrix of zeros and ones via the
  operation \verb|m.={4,6,9,11}| (note the use of the ``dot'' operator
  to perform an element-by element comparison---see section
  \ref{sec:mat-op}); if \texttt{m} equals any of the elements in the
  vector, the corresponding element of the result will be 1, and 0
  otherwise;
\item The \cmd{maxr} function gives the maximum of this vector, so
  we're checking whether \texttt{m} is any one of the four values
  corresponding to 30-day months.
\item Since the above evaluates to a scalar, we put the correct value
  into \texttt{days}.
\end{enumerate}

The ternary operator is more flexible than the ordinary \cmd{if}
statement. With \cmd{if}, the \texttt{<condition>} to be evaluated
must always come down to a scalar, but the query operator just
requires that the condition is of ``suitable'' type in light of the
types of the operands.  So, for example, suppose you have a square
matrix \texttt{A} and you want to switch the sign of the negative
elements of \texttt{A} on and above its diagonal. You could use a loop
(see below) and write a piece of code such as
\begin{code}
matrix A = mnormal(4,4)
matrix B = A

loop r = 1 .. rows(A)
  loop c = r .. cols(A)
     if A[r,c] < 0
       B[r,c] = -A[r,c]
     endif
  endloop
endloop
\end{code}

By using the ternary operator, you can achieve the same effect via a
considerably shorter (and faster) construct:
\begin{code}
matrix A = mnormal(4,4)
matrix B = upper(A.<0) ? -A : A
\end{code}

\tip{At this point some readers may be thinking ``Well, this may be as
  cool as you want, but it's way too complicated for me; I'll just use
  the traditional \cmd{if}''. Of course, there's nothing wrong with
  that, but in some cases the ternary assignment operator can lead to
  substantially faster code, and it becomes surprisingly natural when
  one gets used to it.}

\section{Loops}
\label{sec:hr-loops}

The basic hansl command for looping is (doh!) \cmd{loop}, and
takes the form
\begin{code}
loop <control-expression> <options>
    ...
endloop
\end{code}
In other words, the pair of statements \cmd{loop} and \cmd{endloop}
enclose the statements to repeat. Of course, loops can be nested.
Several variants of the \texttt{<control-expression>} for a loop are
supported, as follows:
\begin{enumerate}
\item unconditional loop
\item while loop
\item index loop
\item foreach loop
\item for loop.
\end{enumerate}
These variants are briefly described below.

\subsection{Unconditional loop}

This is the simplest variant. It takes the form
\begin{code}
loop <times>
   ...
endloop
\end{code}
where \texttt{<times>} is any expression that evaluates to a scalar,
namely the required number of iterations. This is only evaluated at
the beginning of the loop, so the number of iterations cannot be
changed from within the loop itself. Example:
\begin{code}
# triangular numbers
scalar n = 6
scalar count = 1
scalar x = 0
loop n
    scalar x += count
    count++
    print x
endloop
\end{code}
yields
\begin{code}
              x =  1.0000000
              x =  3.0000000
              x =  6.0000000
              x =  10.000000
              x =  15.000000
              x =  21.000000
\end{code}

Note the usage of the increment (\texttt{count++}) and of the
inflected assignment (\texttt{x += count}) operators.

\subsection{Index loop}

The unconditional loop is used quite rarely, as in most cases it is
useful to have a counter variable (\texttt{count} in the previous
example). This is easily accomplished via the \emph{index loop}, whose
syntax is
\begin{code}
loop <counter>=<min>..<max>
   ...
endloop
\end{code}
The limits \texttt{<min>} and \texttt{<max>} must evaluate to scalars;
they are automatically turned into integers if they have a fractional
part. The \texttt{<counter>} variable is started at \texttt{<min>} and
incremented by 1 on each iteration until it equals \texttt{<max>}.

The counter is ``read-only'' inside the loop. You can access either
its numerical value through the scalar \texttt{i} or use the accessor
\dollar{i}, which will perform \emph{string substitution}: inside the
loop, the hansl interpreter will substitute for the expression
\dollar{i} the string representation of the current value of the index
variable. An example should made this clearer: the following input
\begin{code}
scalar a_1 = 57
scalar a_2 = 85
scalar a_3 = 13

loop i=1..3
    print i a_$i
endloop
\end{code}
%$
has for output
\begin{code}
    i = 1.0000000
  a_1 = 57.000000
    i = 2.0000000
  a_2 = 85.000000
    i = 3.0000000
  a_3 = 13.000000
\end{code}

In the example above, at the first iteration the value of \texttt{i}
is 1, so the interpreter expands the expression \verb|a_$i| to
\verb|a_1|, finds that a scalar by that name exists, and prints
it. The same happens through the rest of the iterations. If one of the
automatically constructed identifiers had not been defined, execution
would have stopped with an error.

\subsection{While loop}

Here you have
\begin{code}
loop while <condition>
   ...
endloop
\end{code}
where \texttt{<condition>} should evaluate to a scalar, which is
re-evaluated at each iteration. Looping stops as soon as
\texttt{<condition>} becomes false (0). If \texttt{<condition>}
becomes \texttt{NA}, an error is flagged and execution stops.  By
default, \texttt{while} loops cannot exceed 100,000 iterations. This is
intended as a safeguard against potentially infinite loops. This
setting can be overridden if necessary by setting the
\dtk{loop_maxiter} state variable to a different value.
% (see chapter \ref{chap:settings}).

\subsection{Foreach loop}
\label{sec:loop-foreach}

In this case the syntax is
\begin{code}
loop foreach <counter> <catalogue>
   ...
endloop
\end{code}
where \texttt{<catalogue>} can be either a collection of
space-separated strings, or a variable of type \texttt{list} (see
section \ref{sec:lists}). The counter variable automatically takes on
the numerical values 1, 2, 3, and so on as execution proceeds, but its
string value (accessed by prepending a dollar sign) shadows the names
of the series in the list or the space-separated strings; this sort of
loop is designed for string substitution.

Here is an example in which the \texttt{<catalogue>} is a collection
of names of functions that return a scalar value when given a scalar
argument.
\begin{code}
scalar x = 1
loop foreach f sqrt exp ln
    scalar y = $f(x)
    print y
endloop
\end{code}
%$
This will produce
\begin{code}
              y =  1.0000000
              y =  2.7182818
              y =  0.0000000
\end{code}

\subsection{For loop}

The final form of loop control emulates the \cmd{for} statement in the
C programming language.  The syntax is \texttt{loop for}, followed by
three component expressions, separated by semicolons and surrounded by
parentheses, that is
\begin{code}
loop for (<init>; <cont>; <modifier>)
   ...
endloop
\end{code}

The three components are as follows:
\begin{enumerate}
\item Initialization (\texttt{<init>}): this must be an assignment
  statement, evaluated at the start of the loop.
\item Continuation condition (\texttt{<cont>}): this is evaluated at
  the top of each iteration (including the first).  If the expression
  evaluates as true (non-zero), iteration continues, otherwise it
  stops. 
\item Modifier (\texttt{<modifier>}): an expression which modifies the
  value of some variable.  This is evaluated prior to checking the
  continuation condition, on each iteration after the first.
\end{enumerate}

Here's an example, in which we find the square root of a number by
successive approximations:
\begin{code}
# find the square root of x iteratively via Newton's method
scalar x = 256
d = 1
loop for (y=(x+1)/2; abs(d) > 1.0e-7; y -= d/(2*y))
    d = y*y - x
    printf "y = %15.10f, d = %g\n", y, d
endloop

printf "sqrt(%g) = %g\n", x, y
\end{code}
Running the example gives
\begin{code}
y =  128.5000000000, d = 16256.3
y =   65.2461089494, d = 4001.05
y =   34.5848572866, d = 940.112
y =   20.9934703720, d = 184.726
y =   16.5938690915, d = 19.3565
y =   16.0106268314, d = 0.340172
y =   16.0000035267, d = 0.000112855
y =   16.0000000000, d = 1.23919e-11

Number of iterations: 8

sqrt(256) = 16
\end{code}
Be aware of the limited precision of floating-point arithmetic. For
example, the code snippet below will iterate forever on most platforms
because \texttt{x} will never equal \textit{exactly} 0.01, even though
it might seem that it should.
\begin{code}
loop for (x=1; x!=0.01; x=x*0.1)
    printf "x = .18g\n", x
endloop  
\end{code}
However, if you replace the condition \texttt{x!=0.01} with
\texttt{x>=0.01}, the code will run as (probably) intended.
 
\subsection{Loop options}

Three options can be given to the \cmd{loop} statement. One is
\option{verbose}. This has simply the effect of printing extra output
to trace progress of the loop; it has no other effect and the
semantics of the loop contents remain unchanged.

The \option{decr} option can be applied to an index loop to indicate
that the counter should be decremented by 1, not incremented, on each
iteration. Note that the default behavior with an index loop is that
the code is skipped altogether if the starting index value exceeds the
ending value.

The \option{progressive} option is mostly used as a quick and
efficient way to set up simulation studies. When this option is given,
a few commands (notably \cmd{print} and \cmd{store}) are given a
special, \emph{ad hoc} meaning. Please refer to \GUG\ for more
information.
 
\subsection{Breaking and continuing}
\label{sec:loop-break}

The \cmd{break} command makes it possible to break out of a loop if
necessary. Note that if you nest loops, \cmd{break} in the innermost
loop will interrupt that loop only and not the outer ones.  Here is an
example in which we use the \texttt{while} variant of the \cmd{loop}
statement to perform calculation of the square root in a manner
similar to the example above, using \cmd{break} to jump out of the
loop when the job is done.
\begin{code}
scalar x = 256
scalar y = 1
loop while 1
    d = y*y - x
    if abs(d) < 1.0e-7
        break
    else
        y -= d/(2*y)
        printf "y = %15.10f, d = %g\n", y, d
    endif
endloop

printf "sqrt(%g) = %g\n", x, y
\end{code}

The \cmd{continue} command can be used to short-circuit an iteration:
execution jumps from the line on which \cmd{continue} occurs to the
top of the loop. Iteration will then proceed if the continuation
condition is met. This can promote efficiency if a condition is met at
a certain point in an iteration such that the subsequent code becomes
irrelevant.

\section{The \cmd{catch} modifier}

Hansl offers a simple form of exception handling via the \cmd{catch}
keyword. This is not a command in its own right but can be used as a
prefix to most regular commands: the effect is to prevent termination
of a script if an error occurs in executing the command. If an error
does occur, this is registered in an internal error code which can be
accessed as \dollar{error} (a zero value indicating success). The
value of \dollar{error} should always be checked immediately after
using \texttt{catch}, and appropriate action taken if the command
failed. Here is a simple example:

\begin{code}
matrix a = floor(2*muniform(2,2))
catch ai = inv(a)
scalar err = $error
if err
    printf "The matrix\n%6.0f\nis singular!\n", a
else
    print ai
endif
\end{code}
%$

Note that the catch keyword cannot be used before \cmd{if}, \cmd{elif}
or \cmd{endif}. In addition, it should not be used on calls to
user-defined functions; it is intended for use only with gretl
commands and calls to ``built-in'' functions or operators. Suppose
you're writing a function package which includes some subsidiary
functionality which may fail under certain conditions, and you want to
prevent such failure from aborting execution. In that case you should
use \cmd{catch} \textit{within} the particular function in question,
and if an error condition is detected, signal this to the caller by
returning a suitable ``invalid'' value---say, \texttt{NA} (for a
function that returns a scalar) or an empty matrix. For example:

\begin{code}
function scalar may_fail (matrix *m)
  catch scalar x = ... # call to built-in procedure
  if $error
    x = NA
  endif
  return x
end function

function scalar caller (...)
  matrix m = ... # whatever
  scalar x = may_fail(&m)
  if na(x)
    print "Couldn't calculate x"
  else
    printf "Calculated x = %g\n", x
  endif
end function
\end{code}

What you should \textit{not} do here is apply catch to
\dtk{may_fail()}

\begin{code}
function scalar caller (...)
  matrix m = ... # whatever
  catch scalar x = may_fail(&m) # No, don't do this!
  ...
end function
\end{code}

as this is likely to leave gretl in a confused state.

\section{The \cmd{quit} statement}

When the \cmd{quit} statement is encountered in a hansl script,
execution stops. If the command-line program \app{gretlcli} is running
in batch mode, control returns to the operating system; if gretl is
running in interactive mode, gretl will wait for interactive input.

The \texttt{quit} command is rarely used in scripts since execution
automatically stops when script input is exhausted, but it could be
used in conjunction with \cmd{catch}. A script author could arrange
matters so that on encountering a certain error condition an
appropriate message is printed and the script is halted. Another use
for \texttt{quit} is in program development: if you want to inspect the
output of an initial portion of a complex script, the most convenient
solution may to insert a temporary ``quit'' at a suitable point.

%%% Local Variables: 
%%% mode: latex
%%% TeX-master: "hansl-primer"
%%% End: 
