Procedures &
Concurrency
in Ada
Thanks to:
Fatemeh Salehi, Maryam Foroughi
Fatemeh Farzian, Maryam Khademi
Control Structures
Rich set of Control
Structures
•
•
•
•
•
•
•
A Conditional
An iterator (definite and indefinite)
A case-statement
Subprograms
A goto-statement
Facilities of handling exceptions
Facilities for concurrent
programming
All-Purpose Iterator
• Quite general, quite baroque
• Syntax:
loop <sequence of statements> end loop
• exit-statement:
• aborts the loop and resumes control after the
end loop
• Any number of exits, at any depth
• Exit from blocks (not from subprograms)
• Has some of the characteristics of nonlocal
goto
• Multiple mid-decision loops
Loop example
I := A’First;
loop
if I > A’Last then exit; end if;
if A(I) = k then exit; end if;
I := I + 1;
end loop;
exit when (abbreviation)
I := A’First;
loop
exit when I > A’Last;
exit when A(I) = k;
I := I + 1;
end
loop;us from typing
 Saves
 Loop termination conditions are clearly marked
X Exit can be buried deeply in the body of the loop
therefore be hard to spot
While loop
I := A’First;
When I <= A’Last
Loop
exit when A(I) = k;
I := I + 1;
end loop;
For loop
for I in A’Range
loop
exit when A(I) = K;
end loop
• The for-phrase automatically declares the
control variable I, thereby making it local
to the loop
• Outside of the loop it will not be possible to
determine where K was found
Using a controlled variable
to save K’s location
for J in A’Range
loop
if A(I) = K then
I := J;
exit;
end if;
end loop;
K was actually found or not?
Declare
Found: Boolean := False;
begin
for J in A’Range
loop
if A(J) = K then
I := J;
Found := True;
exit;
end if;
end loop;
if Found then
--Handle found case
else
--Handle not found case
end if;
end;
Ada’s Exception
Mechanism
• Ada is intended for embedded
computer applications
• Allows us to define exceptional
situations, signal their occurrence,
and respond to their occurrence
Exception Handling
• Example
– User attempts to push an item when the
stack is full
– Push function raises Stack_Error,
causing the exception mechanism to be
called
• Assume exception mechanism pops a few
elements off the top of the stack and
throws them away since they’re older. Then
it adds the new data.
– Execution of Push and the body of
Producer is aborted.
Definition of an
Exception Handler
Use Stack1;
procedure Producer (...);
begin
...
Push (Data);
...
Exception
when Stack_Error =>
declare Scratch: Integer;
begin
for I in 1..3 loop
if not Empty then Pop (Scratch); end if;
end loop;
Push (Data);
end;
end Producer;
Propagation of
exceptions
• If the exception is defined in the
local environment, we go to its
handler, otherwise we look for a
handler in the caller’s environment.
• Exceptions are bound dynamically:
– Violate Structure and Regularity
Principles.
Parameters
• In
– Transmit information into a procedure
– Analogous to constant parameters in
original Pascal
– Read-only
– Elementary types  pass by value
– Composite types  up to compiler
– Remaining types  pass by reference
Parameters
• Out
– Transmit results out of a subprogram
– Ada 83: write-only
– Ada 95: may be read after value set
within subprogram
– Elementary types  pass by value
– Composite types  up to compiler
Parameters
• In Out
– Used for parameters that are to be
used as both a source and a destination
by the subprogram
– Elementary types  pass by valueresult
– Composite types  pass by reference or
value-result, compiler’s choice
Ada’s orthogonal solution
How does the compiler
decide?
•
•
•
•
Composite parameter: s words
Each component of the parameter: 1 word
Accessing components: n times
Cost of passing the parameter by copying:
C = 2s + n
• Cost of passing the parameter by
reference:
R = 2n + 1
Reference or Copy
Position-Independent & Default
Parameters
Procedure Draw_Axes (X_Origin, Y_Origin:
Coord; X_Scale ,Y_Scale: Float;
X_Spacing, Y_Spacing: Natural;
X_Logarithmic, Y_Logarithmic: Boolean;
X_Labels, Y_Labels: Boolean;
Full_Grid: Boolean);
Draw_Axes (500, 500, 1.0, 0.5, 10, 10, False,
True, True, True, False )
Position-Independent & Default
Parameters
Problem of programs with many parameters:
 hard memorization
 error-prone
Solution (also suggested by OS command Languages):
Position-Independent Parameters:
 Parameters can be listed in any order.
 A name is associated with each
parameter.
Position-Independent & Default
Parameters
Example of Position-Independent:
Draw_Axes (X_Origin => 500,
Y_Origin => 500, X_Spacing =>10,
Y_Spacing => 10,
Full_Grid => False,
X_Scale => 1.0, Y_Scale=>0.5 ,
X_Labels => True, Y_Labels=> True,
X_Logarithmic => False, Y_Logarithmic=> True);
Position-Independent & Default
Parameters
Position-Independent:
Readable.
Much less prone to mistakes than the
position-dependent version.
Illustration of the Labeling Principle.
Like advantages of Pascal’s labeled
case-statement over earlier unlabeled
case-statements.
Position-Independent & Default
Parameters
Most users will not want a full grid or
logarithmic axes.
All users must specify those options.
Violation of the Localized Cost Principle
(users should not have to pay for what they
do not use).
Solution:
Default Parameters
Position-Independent & Default
Parameters
Example of Default Parameters:
Procedure Draw_Axes (X_Origin, Y_Origin: Coord
:= 0; X_Scale ,Y_Scale: Real :=1.0;
X_Spacing, Y_Spacing: Natural :=1; X_Label,
Y_Label: Boolean:= True; X_Logarithmic,
Y_Logarithmic: Boolean:= False; Full_Grid:
Boolean:= False);
Draw_Axes (500, 500, Y_Scale =>0.5,
Y_Logarithmic => True, X_Spacing => 10,
Y_Spacing => 10);
Position-Independent & Default
Parameters
 Position-dependent and PositionIndependent parameters can be
mixed in a single call.
Draw_Axes (500, 500, Y_Scale =>0.5,
Y_Logarithmic => True, X_Spacing =>
10, Y_Spacing => 10);
Position-Independent & Default
Parameters Complicate Operator
Identification
In Ada:
A less obvious cost results from feature
interaction; in this case, the interaction
of overloading with PositionIndependent and Default Parameters.
Position-Independent & Default
Parameters Complicate Operator
Identification
Procedure P (x: Integer ; Y:Boolean := False);
Procedure P (x: Integer ; Y:Integer := 0);
Procedure P bears 2 meaning at onceP is overloaded
 P(9,True)
 P(5,8)
What is the meaning of the call P(3)?
P(3) is ambiguous  Ada dose not allow the two
procedure declaration shown above.
Position-Independent & Default Parameters
Complicate Operator Identification
A set of declarations is illegal if it introduces
the potential for ambiguous calls.
Type primary is (Red, Blue, Green);
Type Stop_Light is (Red, Yellow, Green);
Procedure Switch (Color: Primary; x: Float; Y: Float);
Procedure Switch (Light: Stop_Light; Y: Float; x:Float)
Switch (Red, x => 0.0, Y => 0.0)
Call is ambiguous  declarations is illegal
Position-Independent & Default Parameters
Complicate Operator Identification
Switch (Red, x => 0.0, Y => 0.0)
2 over-loading:
I. Overloaded enumeration
II. Overloaded procedure
 Human reader and the compiler can
have difficulty with a program that
makes extensive use of overloading
and position- independent and
default parameters.
Ada Permits Concurrent Execution
Ada provides a tasking facility that allows
a program to do more than one thing at a
time.
Example:
Small, stand-alone word-processing system
that allows users to print one file while
they are editing another.
Ada Permits Concurrent Execution
Defining disjoint tasks:
Procedure word_Processor is
task Edit; end Edit;
task body Edit is
begin
------ edit the file selected -----end;
task Print; end Print;
task body Print is
begin
------ print the file selected -----end;
Begin
--- initiate tasks and wait for their completion --end word_Processor;
Ada Permits Concurrent Execution
A task is declared very much like a
package, with a separate specification
and body.
We do 3 things at once:
We begin executing the bodies of
Word_Processor
Edit
Print
Ada Permits Concurrent Execution
What does Word_Processor do?
In this case not very much.
Body of procedure is empty  we
immediately encounter the end and try
to return.
Ada prevents a procedure from returning
as long as it has active local tasks.
Ada Permits Concurrent Execution
Word_Processor
Edit
Print
Ada Permits Concurrent Execution
Why Ada require all local tasks to finish
before a procedure can exit?
Suppose Word_Processor had some local variables;
those are visible to Edit and Print.
When Word_Processor exits:
- its activation record is deleted  any reference in
Edit and Print to the local variables of
Word_Processor will be meaningless
dangling
references
Ada Permits Concurrent
Execution
Alternative:
Delay Word_Processor’s return until it can
be done safely.
This is an example of the Security Principle.
Will See:
1: Tasks Synchronize by
Rendezvous
2: Control Access to Data
Structures
task DB_System is
task Summary; end Summary;
task body Summary is
{…};
task Retrieval;
entry Seek (K: Key);
entry Fetch (R: out Recd);
end Retrieval;
task body Retrieval is
{seek record and return it};
begin
...await completion of local tasks
end DB_System;
task body Retrieval is{
loop
accept Seek (K: Key) do
RK := K;
end Seek;
... Seek record RK and put in
Recd_Value
accept Fetch(R:outRecd) do
task body Summary is{
.
Seek(id);
.
.
fetch(New_Rec);
.
.
R := Recd_Value;
end Fetch;
end loop;
};
}
Guards and Protected Types
Control Concurrent Access to
Data Structures
Our word processor
• Edit sends documents to Print for
printing.
task Print is
entry Send (D: Document)
entry Terminate
end Print;
task body Print is
begin
loop
select
accept Send (D: Document) do
… print the document
end Send;
or
accept Terminate do
exit
end Terminate;
end select;
end loop;
End Print;
Task Edit
….
Print.Send(D);
Making it more loosely
coupled
• Put a buffer (Communication) in
between
• We have a Send : used by Edit
• And a Receive : used by Print
Communication
Specification (1)
• Package communication is
Size : constant integer :=100;
Avail: integer rang 0..size:=0;
Procedure Send (D: in Document);
Procedure Receive (d: out Document);
Private
in_ptr, out_ptr: integer range o..size-1
:=0;
buffer: array (0..size-1) of Document;
End Communication;
Communication Body (1)
• Package body Communication is
Procedure Send( d: in document)
{
buffer (in_ptr) := d;
In_ptr := (in_ptr+1) mod size;
avail++;
}
Procedure receive( d: out document)
{
d := buffer (out_ptr);
out_ptr := (out_ptr+1) mod size;
avail--;
}
• Avail is a critical section, we need to
have mutual exclusion.
• Or the implementation will be
incorrect.
• One way: have Communication as a
task and Send and Receive as
guarded entries
Communication
Specification (2)
• Task communication is
entry Send (D: in Document);
entry Receive (D: out Document);
entry Terminate;
Private
Size : constant integer :=100;
Avail: integer rang 0..size:=0;
in_ptr, out_ptr: integer range o..size-1 :=0;
buffer: array (0..size-1) of Document;
End communication;
Communication Body (2)
task body Communication is
Begin
loop
select
when Avail < size accept Send (D: in Document)
do
…
end Send;
or when Avail > 0 accept Receive (D: out Document)
do
…
end Receive;
or accept Terminate do exit end Terminate;
end select;
end loop;
end Communication;
• It has an overhead: an additional
task, actively waiting
• Ada 95 has an additional construct :
– Protected type
– Only one of its entries can be executed
at a time
Communication
Specification (3)
• Protected type communication is
entry Send (D: in Document);
entry Receive (D: out Document);
Private
Size : constant integer :=100;
Avail: integer range 0..size:=0;
in_ptr, out_ptr: integer range 0..size-1 :=0;
buffer: array (0..size-1) of Document;
End communication;
Communication Body (3)
Protected body Communication is
Begin
entry Send (D: in Document) when Avail< size
is
begin
…
end Send;
entry Receive (D: out Document) when Avail>0
is
begin
…
end Receive;
end Communication;
Syntactic Structures
• Similar to Pascal
declare
<local declarations>
begin
<statements>
exceptions
<exception handlers>
end
procedure <name> (<formals>) is
<local declarations>
begin
<statements>
exceptions
<exception handlers>
end
Procedures vs. Blocks
• Procedures
– Have a name
– Have formal parameters
– Can be “called” from diff. contexts
• Blocks
-are called where they are written
Which Principle?
Syntactic Consistency
Principle
Things that look similar should
be similar; things that are
different should look different
Semicolons
• Pascal
– semicolons are separators – between
statements
• Ada
– semicolons are terminators
– Believed to be less error-prone
Fully Bracketed syntax
• Compound statement have a terminating
statement
• Pascal examples:
for i:= ... do begin ... end
if ... then begin ...end else begin ... end
procedure ... begin ... end
function ... begin ... end
case ... of a: begin ... end; ... end
while ... do begin ... end
with ... do begin ... end
record ... end
Ada Brackets
•
•
•
•
•
•
•
•
•
loop ... end loop
if ... end if
case ... end case
record ... end record
function <name> (<formals>) is ... begin ... end
<name>;
procedure <name (<formals>) is ... begin ... end
<name>;
package <name> is ... end <name>;
package body <name> is ... end <name>;
accept <name> (<formals>) do ... end <name>;
Ada Summary
• An engineering trade-off
• DoD Still disallows subsets
• Criticized for Size
–
–
–
–
–
Suffers from “feature bloat” in some ways
Ada-83 BNF: 1600 tokens
Pascal: 500
Algol: 600
Ada 95 is even larger
Ada Summary
• C. A. R. Hoare suggested Ada is so big that
few programmers will master it.
– “Do not allow this language in its present state
to be used in applications were reliability is
critical ... By careful pruning of the Ada
language, it is still possible to select a very
powerful subset that would be reliable and
efficient in implementation with safe and
economic use. ... If you want a language with no
subsets, you must make it small.”
Ada Summary
• Moderately Successful
– Widely used in DoD
– Not widely used in universities or the
commercial market
Fourth-Generation
Languages
• Both consolidation of 3rd generation
characteristics and addition of new
characteristics
• Major contribution: extensions to
name structures to give full data
abstraction language.
• Control structure improvements
Fourth-Generation
Languages
• Dynamically scoped exception
mechanism
• Data structure constructors
corrected some problems with 3rd
generation constructors (e.g., array
parameters)
– Name equivalency is the rule
• Syntactic structures
– Fully bracketed notation
Bottom Line
“... culmination and fulfillment of the
evolutionary process that began with
FORTRAN.”
Any
Question?
And Now
Quiz !
Descargar

Document