Ada Procedures (Including Numeric Get)
Procedures - Topics
- Declaration
- Procedures vs Functions
- Parameter Modes
- Scope, global variables
- Side effects (and ignoring values)
- Parameters in other languages: C and C++
- Parameter mode implementation
Procedure Declarations
- Declare procedures in the declaration section
- Syntax is like main procedure
- Delcare variables for main routine after declaring procedures
(ie immediately before the main routine)!!!
- Parameters have 3 possible modes: in, out, in out
- Default is in mode (ie mode is in if mode is not specified)
Parameter Modes
- In: Pass info in only
- Out: Pass info out only
- In Out: Pass info in and out
Parameter Mode Example
with ada.integer_text_io; use ada.integer_text_io;
with ada.text_io; use ada.text_io;
procedure modes2 is
procedure sumProduct(v: in integer; sv, ss, sc, c: in out integer) is
begin
sv := sv + v;
ss := ss + v * v;
sc := sc + v * v * v;
c := c + 1;
end sumProduct;
procedure doit(a, b, c, d: in integer) is
i: integer;
begin
loop
exit when end_of_file;
get(i);
--sumProduct(i, sumValues, sumSquares, sumCubes, count);
sumProduct(i, a, b, c, d);
end loop;
end doit;
count, sumSquares, sumValues, sumCubes: integer := 0;
begin
doit(count, sumSquares, sumValues,sumCubes);
end modes2;
Table2.adb - Nested Procedures
- Table2.adb
- Table2.adb prettified
- This new version has nested procedures
- Procedures roughly equivalent to Java void methods
- Procedures without parameters don't need parens
- Declaration section: between
procedure X is
and
begin
- declare items (eg variables, procedures)
used by X
Example 3a: Table3a.adb - in test, local variable
- Table3a.adb
- Table3a.adb prettified
- This new version can specify range of powers
-
in
membership test!
- Local variable
tempInt
- Indentation: reflects program hierarchical structure!
- Precondition: putHeader assumes parameters are correct
Declaration Section and Local Variables
- Between the words
procedure ... is
and begin
is the declaration section of the procedure
- A procedure's variables are (normally) declared in its declaration
section
- Later we see how to declare variables within executable part
of a procedure
- Variables declared in a procedures declaration section are called
the local variables of that procedure
- local variables are also called locals
Scope
- The scope of a declaration is the set of statements over
which that declaration is visible.
- The scope of a declaration is from the point of declaration to
the corresponding
end
statement
- Examples:
-
tempInt
is local to
putRows
and is visible from declaration to
end of putRows
-
tempInt
is not visible outside putRows
- Procedures are also visible from the point of
definition to the corresponding
end
statement
Cardinal Rule in Ada
- :A name must be declared before it can be used.
- We will see this rule in many contexts
Global Variables
- Variables that are visible in a routine but not declared
in the routine are called global variables
- Variables for main routine should be placed
immediately before main,
otherwise they are global variables
- Avoid global variables whenever possible!
- Example: scope.adb (prettified)
Example 3b: Table3b.adb - Integer Input, Change parameter
values!
- Table3b.adb
- Table3b.adb prettified
- This version is identical to the previous version except
that it inputs ranges of integers and powers
- ada.integer_text_io.get(x)
- Changes the value of x!
- Reads from standard input (ie keyboard)
Out Mode Parameters
x := 3;
put(x); -- Outputs 3
get(x); -- Assigns value that was in input to x
put(x); -- Outputs whatever was input
A simple class exercise: write a single routine that
returns the sum and difference of its first two parameters
In the procedure definition, a formal parameter that can be
changed must be declared as an out
mode parameter
The value of an out mode formal parameter is given to the
corresponding actual parameter.
This can't be done in Java (with primitive types)
Can you write swap(i, j)
in Java
Parameter Passing Modes
- Note: Make sure you know terms formal and actual parameters
- In mode:
- Used to pass information into the procedure
- Formal parameter is treated like a constant in the
procedure:
- Default mode
- Out mode:
- Used to pass information back from the procedure
- Formal parameter is treated like an uninitialized
variable in the procedure
- In Out mode:
- Used to pass information both in to and back
from the procedure
- Value of actual parameter is used to
initialize formal parameter
Compiling Parameter Passing Modes
- Compiler will not allow assignment to an in mode
parameter
- Compiler gives a warning is given if an out mode
parameter is used before it has a value
- The actual parameter for an out or in out actual must be
a variable; it can't be a literal or a constant.
- The mode gives redundant information that allows the
compiler to check if the parameters are used correctly
- Final note: even though this sounds contradictory,
we say that we "pass in" a variable to an out mode parameter
Implementing Parameters: Swap in Ada, C, ...
- Consider swaptest.adb
- Can we write swap in Java?
- Why not: params are all passed by value: copy is passed in and modified
- What happens in C?
- What happens in C++?
Parameter Passing Mechanism vs Mode
- In C and C++, the language specifies the param passing mechanism
- In Ada, the language specifies the parameter passing mode
- The mechanism is left to the compiler writer
Techniques for Implementing Modes
- Goals:
- Make out mode possible
- Efficiency: space and time
- Security
- Minimize aliases
- Two possible ways of implementing in out mode
- Copy in/copy out (aka by pass by value-result):
- actual parameter has a separate memory location
- on procedure call: value of
formal actual param is copied to
actual formal parameter
- changes to actual parameter are made to the copy (ie to the separate location)
- on procedure exit: value of formal parameter is copied back to the actual
- for in mode (ie pass by value): actual is copied into formal, but nothing is copied back
- for out mode (ie pass by result): formal is copied back to actual, but nothing is copied in
- Reference (aka pass by reference):
- on procedure call: formal parameter receives the address of the actual
- formal is alias for actual
- any changes to formal parameter are actually changes to the actual parameter
- Examples:
- What about the time and space efficiency of these implementation techniques
Implementing Modes In Ada
- Means of implementation affected by type
- In mode can simply be copy in
- Reference sometimes used to reduce copying for
larger types
- In and In Out mode must be reference or copy in/out
- Elementary types (ie type that have no components, like
integers) are passed by copy
- Composite types that we will use (eg array of integers)
may be passed by copy or reference
- Composite types whose elements are pointers
are passed by reference
- Some types which we won't use (eg tagged, task, protected)
are also passed by reference
Default Parameters
- Formal parameters can have default values
- Example:
procedure showDefault is
-- Outputs an integer and a newline
-- Allows user to specify width
-- Default value for width is 11
procedure put_line(i: Integer; width: Integer := 11) is
begin
put(i, width);
newline;
end put_line;
begin
put_line(3, 1);
put_line(4); -- width is 11
end showDefault;
Ada.Text_IO.new_line itself has a default parameter
Keyword Parameters
- Compiler usually considers parameters to be positional
(ie first actual matched to first formal)
- Actual parameters can be passed by keyword
- Example:
procedure showKeyword is
procedure put_line(i: Integer; width: Integer := 11) is
begin
put(i, width); newline;
end put_line;
begin
-- Positional
put_line(3, 1);
-- Keyword
put_line(i => 3, width => 1);
put_line(width => 1, i => 3);
-- Use default width
put(i => 4);
-- Can mix positional and keyword.
-- Keyword must be last.
put(3, width => 1);
end showKeyword;
Common use: Ada.Float_Text_IO.put(x, fore => 1;
aft=> 2; exp => 1); is more readable
than put(x, 1, 2, 3);
Table3c.adb: out mode parameters, validity check
- Table3c.adb
- Table3c.adb prettified
- This version changes the procedure by putting
all input into a single procedure.
- Procedures putHeader and putRows are not changed
- Main routine is simplified by pushing complexity into a
procedure
-
This procedure also checks the validity of the data and
will not return until the input is valid (ie
non-negative and increasing integers)
- Notice these language features:
- out mode parameter
- General loop statement
- How to handle non-numeric input? Add exception handler.
More on Get
- Ada.Integer_Text_IO.get is buffered
- When a get is encountered, an entire line of input is read and
subsequent get statements access this line. When all of the data
in this line have been accessed, more gets will read more lines.
- get skips white space
- Invalid data will raise an exception
- End_Error exception: Attempt to read past end of file
- Data_Error exception: attempt to read non-integer
- Ada.Float_Text_IO.get is similar
In Mode Parameters and Compilation Errors
- You can't assign to an in mode parameter
- You can't pass an in mode parameter to an out mode parameter
- Example: modes2.adb and (prettified)