Home
Up
Intro
Contents
Chapter
1
2
3
4
5
6
7
8
9
10
Design
Assert
Timing
EBNF
Report
Pas
Last Changed: July 12th, 1997
This is a conversion from Oberon text to HTML, and from German to English. The converter software is still under development,
and some features or information may be missing in this converted version.
HTML hypertext facilities are not yet active in this document.
To exploit the interactive facilities, use Oberon System 3 and the source of this text,
available for download using binary ftp as Oberon System 3 archive.
The converter from German to English is still under development as well.
A previous version is also available for Oberon V4.
To access this and other additional material use
ftp.
For the convenience of our students, most of this information and the related material is available
in German as well.
Introduction to Oberon
The Oberon Programming Language
07 Procedures, Functions
Modules can be structured by procedures and functions. A procedure groups
statements in a block and makes this group available under a name, which
is used to activate it. A procedure is introduced by a procedure declaration.
Beside the block of statements, a procedure may also contain formal parameters
and local declarations A procedure is called by its name, possibly followed
by a current parameter list.
As for all declarations an export mark can be attached to procedure declarations.
The usual rules apply: within the module, in which the procedure is defined,
a procedure is called by its name is called. If it is to be called in another
module, the module in which the procedure is defined must be imported, and
the procedure is called by its qualified name module
name.Procedure name.
Procedure Call:
procedure
name [current parameter list]
Current Parameter List:
(
[Parameter {, Parameter }] )
We already met procedure calls. The statement System.Time
calls procedure Time in module System. This is a parameterless procedure.
The statement Texts.WriteString(w, 'Hello') calls
the procedure WriteString in module Texts. Two parameters are transferred:
the Writer w and the stringer 'Hello'. Parameters can be transferred in two
ways. For parameters like the string in this example the value (in this case
'Hello') must be actually transferred. If the current parameter is an expression,
the expression is evaluated first and the result is passed as parameters,
for example when calling Texts.WriteInt(w, i+j, 10).
For other parameters like the Writer w, a reference only needs to be transferred.
The called procedure is to actually operate on the current Writer, possibly
changing it.
The procedure declaration determines which parameters are transferred by
value and which are transferred by reference. Parameters which are transferred
by reference are marked by VAR. In a procedure call these must be represented
by a variable. Parameters which are not marked VAR are passed by value. Constants
or expressions can be used as current parameters as well as variables. Implicitly
a local variable is generated for each value parameter. This is visible only
within the procedure and it is only valid there. The current parameters are
evaluated upon procedure call and the result is transferred in this implicit
local variable.
Procedure Syntax:
PROCEDURE
[target] procedure name [formal parameter list];
Declaration sequence
[BEGIN
statement
sequence ]
END procedure name;
Formal Parameter List
( [ formal parameter {;
formal parameter } ] )[ : type of result ]
Formal Parameter
[ VAR ]
name {, name}: Type
For Texts.WriteString and Texts.WriteInt,
the declaration headings are given in the module Texts as
PROCEDURE WriteString*(VAR W:
Writer; s: ARRAY OF CHAR);
PROCEDURE WriteInt*(VAR W: Writer;
x, n: LONGINT);
With the procedure call the current parameters are assigned to the formal
parameters by position. With value parameters, the appropriate current expressions
are evaluates and the results are assigned to the respective formal parameters,
which then act as local variable. The current parameter list must correspond
to the formal list.
Oberon-2 extends the Oberon syntax by the target, an optional parameter.
The target is inserted in front of the procedure name. The target is treated
in a special way for support of a particular programming style, object oriented
programming. We come back to this issue in a later chapter.
The declaration section of a procedure essentially corresponds to that of
a module. Declarations from a procedure however cannot be exported - only
declarations in the outermost level can be exported. Procedures define local
visibility and ranges of validity. The range of validity begins with the
place of the declaration and extends at the end of the procedure. Names may
be used only within the range of validity of their declaration. No name may
refer to more than one object within its range of validity. The range of
validity can be nested however: a (sub)procedure defines a new range of validity.
If a name is defined which is defined already in the surrounding block, the
local declaration applies up to the end of the procedure; hence the previous
becomes invisible until the end of the local block. In contrat to this, global
variables of a module persist until the module is unloades explicitly.
A procedure can contain more than one RETURN statement. Procedures can have
result type; if so, they are called function procedures if it is necessary
to distinguish them from ordinary procedures. Functional procedures must
always be left with a RETURN statement. With functional procedures, an expression
which is compatible with the type of result must follow the RETURN statement.
This expression is evaluated and the result is passed as result of the functional
procedure.
RETURN Statement
RETURN { expression
}
Example
PROCEDURE MIN(
a,b:REAL): REAL;
BEGIN
IF a<b THEN RETURN
a ELSE RETURN b END
END MIN;
A procedure can be called in its own statement part. This leads then to a
recursion. As a notation. this is usually a very compact representation.
As executable instruction, this usually implies overhead: a procedure call
means that working space has to be allocatd and space must be supplied for
local variable, control needs to be transferred, and a secured return to
the calling statement must be prepared. Usually this is more complex this
than a sequential execution of statements. If recursions can be avoided,
this should be done. In particular a recursion can be avoided whenever it
is called as the last statement of an statement sequence.
Exercises:
1.) In many program libraries there are procedures
to calculate power function. How would you program a functional procedure
XPwrI, for x>=0, i>=0 to calculate the power xi.
PROCEDURE XPwrI(x:LONGREAL; i:LONGINT):
LONGREAL;
2.) Implement the three generators from the previous chapter as function
procedures RandLGM, RandPRB, RandUNIX and test these procedures.
3a.) Write a pseudo-random number generator, which simulates a uniform distribution
on [ 0.1 ] using RandLGM. Implement this generator as function procedure.
3b.) Write a function procedure which produces pseudo-random numbers with
exponential distribution, using the generator from 3a. The rate should be
a parameter of the functional procedure.
4.) Simulate a simple queue with exponential arrival and service time. Simulate
then the flow for 20 customers with a) arrival rate=service rate; b) arrival
rate=service rate/2.
5.) Write a "pretty printer", which writes a real number in a convenient
format for reading, where the format may be data dependent. Example:
Value Output
0.0E0
0
1.2E1
12
1.2345E2 123.45
If you need special mathematical funtions, you will find most of what is
neeeden in module Math. Hint: use a fixed width font to simpliy the task.
Exercises:
Compare the two following implementations of the
factorial function. Which computational effort do they need?
PROCEDURE Fak1(i:INTEGER):LONGINT;
BEGIN
ASSERT(i>=0);
IF i<=1 THEN RETURN 1
ELSE RETURN i*Fak1(i-1)
END;
END Fak2;
PROCEDURE Fak2(i:INTEGER):LONGINT;
VAR res:LONGINT;
BEGIN
ASSERT(i>=0);
res:=1;
WHILE i>1 DO res:=res*i; DEC(i) END;
RETURN res
END Fak2;
Several procedures are pre-defined in Oberon. You find a list of the
pre-defined procedures in the Oberon report. The next source of available
procedures are exported procedures in standard modules. Only the last resort
is writing procedures yourselves.
Introduction to the Oberon programming language. ItO/Ch07.Text
gs (c) G. Sawitzki, StatLab Heidelberg
<http://statlab.uni-heidelberg.de/projects/oberon/intro/>
Home
Up
Intro
Contents
Chapter
1
2
3
4
5
6
7
8
9
10
Design
Assert
Timing
EBNF
Report
Pas