Previous | Table of Contents | Next |
6.2.1.7. Procedures
A procedure consists of a sequence of expressions bounded by the reserved words procedure and end. The name of the procedure and its parameters enclosed in parentheses follow procedure. An example is
procedure max(i, j) if i > j then return i else return j end
which produces the maximum of i and j. The expression return returns its argument as the value of the procedure call.
A procedure may fail instead of producing a result by using fail instead of return. An example is
procedure posmax(i, j) if i > j then { if i > 0 then return i else fail } else if j > 0 then return j else fail end
which produces the maximum of i and j provided it is positive but fails otherwise.
Flowing off the end of a procedure without a return also causes the procedure to fail.
Procedures may be called recursively, directly, or through a sequence of other procedure calls. An example is provided by the familiar factorial operation, n! = 1 × 2 × × n:
procedure factorial(n) if n < 2 then return 1 else return n * factorial(n 1) end
Procedures are values. That is, they can be assigned to variables, passed as arguments, and so on. Consider
procedure nonneg(p, n) if n < 0 then fail else return p(n) end
This procedure fails if n is less than zero but otherwise returns the value produced by p(n). For example,
nonneg(factorial, n)
produces the factorial of n if it is greater than or equal to zero but fails otherwise.
6.2.1.8. Scope
Icon provides three kinds of scope for variables: global, local, and static. Variables have the null value initially, except for global variables that are the names of functions and procedures.
The values of global variables are available to all procedures and for the duration of program execution. Global declarations occur outside procedure declarations. For example,
global state global mode
declares state and mode to be global and available throughout the program.
Local and static variables belong to procedures and are declared inside them. Local variables are created when a procedure is called and destroyed when it returns. For example, in
procedure revolve(x, y) local z
z is local to revolve(). Parameters, in this case x and y, are local, also.
Static variables belong to all calls of the procedure in which they are declared but last throughout program execution and are available to all calls of the procedure. This allows variables to be shared by all calls of a procedure. Static variables can be initialized in an initial expression, which is evaluated only the first time a procedure is called. For example, in
procedure fracture(s) static vowels initial vowels := aeiouAEIOU
the static variable vowels is initialized in the first call of fracture() and that value is available in all subsequent calls of fracture().
6.2.1.9. Input and Output
As indicated by previous examples, read() and write() read and write lines of text, respectively. In the absence of a specified file, read() reads from standard input and write() writes to standard output. Files can be specified, as in
read(database) write(log, entry)
A file is opened by
open(name, options)
where name is the name of the file and options specifies how it is to be opened. The default option, if the argument is omitted, is opening for reading, as in
database := open(backup.db)
The option w opens a file for writing, as in
log := open(newlog.txt, w)
The function open() fails if the named file cannot be opened in the specified manner. It is important to check for this, as in
database := open(backup.db) | stop(*** cannot open backup)
Note the use of alternation to evaluate another expression if the first one fails. The function stop() is like write(), but it writes its argument to standard error output and terminates program execution.
Three keywords, indicated by an initial ampersand, have values for the standard files:
Thus,
write(&errout, ignition failure)
writes an error message to standard error output but does not terminate program execution like stop() does.
In addition to line-oriented input and output, Icon supports binary input and output and random access to files.
6.2.1.10. Preprocessing
Icon has an integrated preprocessor that allows files to be included, symbols to be defined, and so forth. Preprocessor directives begin with $, as illustrated by
$include constants.defs
which inserts the file constants.def in place of the preprocessor directive. Similarly,
$define Width 10
defines the constant Width to have the value 10. Subsequently, appearances of Width are replaced by 10.
6.2.1.11. Storage Management
Many values in Icon require storage space in memory; strings and structures are examples. Icon allocates storage for values when they are created. This is done automatically without explicit allocation expressions in the program.
If there is not enough memory to provide space for a newly created value, memory is garbage-collected to reclaim space that no longer is in use. This also is an automatic process and occurs only as needed.
Previous | Table of Contents | Next |