Date post: | 17-Jan-2016 |
Category: |
Documents |
Upload: | colin-james |
View: | 217 times |
Download: | 0 times |
1http://libre.adacore.com © AdaCore under the GNU Free Documentation License
Franco Gasperoni
http://libre.adacore.com
7http://libre.adacore.com © AdaCore under the GNU Free Documentation License
• Programming in the Large
– specification & implementation
– privacy
– abstract data types
– hierarchical packages
8http://libre.adacore.com © AdaCore under the GNU Free Documentation License
Separate CompilationSeparate CompilationTHE PROBLEM
Compiler object
CODE
Compiler object
CODE
Compiler object
CODE
Linker
executable
libraries
9http://libre.adacore.com © AdaCore under the GNU Free Documentation License
Problem with this approachProblem with this approach
CODE
CODE
CODE
• No structure
• To write your own code– YOU MUST understand
everybody else’s code
CODE
CODE
10http://libre.adacore.com © AdaCore under the GNU Free Documentation License
IdeaIdea
SPECIFY WHAT EACH
MODULESHOULD DO
11http://libre.adacore.com © AdaCore under the GNU Free Documentation License
SPECIFICATION
Software module
?
BODY
12http://libre.adacore.com © AdaCore under the GNU Free Documentation License
• Programming in the Large– specification &
implementation•specification
• implementation
• specification rules in Ada
13http://libre.adacore.com © AdaCore under the GNU Free Documentation License
A Specification is a ...A Specification is a ...
CONTRACTImplementorof themodule
Users/clientsof themodule
• On the SERVICES provided by the module
14http://libre.adacore.com © AdaCore under the GNU Free Documentation License
• SPEC = list of services provided
• BODY = implementation of the services (hidden)
Software module
Service_1Service_2Service_3
Service_1 implementation
Service_2 implementation
Service_3 implementation
15http://libre.adacore.com © AdaCore under the GNU Free Documentation License
SPECIFICATION
?BODY
16http://libre.adacore.com © AdaCore under the GNU Free Documentation License
ExampleExample
• Create a Queue module that can– Add an Integer to the Queue
– See the First integer in the Queue
– Get the first integer in the Queue
– Test whether the Queue is Empty
17http://libre.adacore.com © AdaCore under the GNU Free Documentation License
package Queue is procedure Add (Element : Integer);
function First return Integer; function Get return Integer;
function Empty return Boolean;end Queue;
package Queue is procedure Add (Element : Integer);
function First return Integer; function Get return Integer;
function Empty return Boolean;end Queue;
queue.adsqueue.ads
18http://libre.adacore.com © AdaCore under the GNU Free Documentation License
package Queue
?
BODY
package Queue is procedure Add (Element : Integer);
function First return Integer; function Get return Integer;
function Empty return Boolean;end Queue;
package Queue is procedure Add (Element : Integer);
function First return Integer; function Get return Integer;
function Empty return Boolean;end Queue;
queue.adsqueue.ads
19http://libre.adacore.com © AdaCore under the GNU Free Documentation License
Using package QueueUsing package Queue
with Queue;procedure Client is Queue_Error : exception; X : Integer;begin Queue.Add (3); Queue.Add (4);
if not Queue.Empty then X := Queue.Get; else raise Queue_Error; end if;end Client;
client.adb
20http://libre.adacore.com © AdaCore under the GNU Free Documentation License
Specifications Reduce ComplexitySpecifications Reduce Complexity
SPECSPEC
SPECSPEC
SPECSPEC
SPECSPEC
• To write your own code– only need to understand
specs for the services you need
21http://libre.adacore.com © AdaCore under the GNU Free Documentation License
package Queue?
package Queue is procedure Add (Element : Integer);
function First return Integer; function Get return Integer;
function Empty return Boolean;end Queue;
package Queue is procedure Add (Element : Integer);
function First return Integer; function Get return Integer;
function Empty return Boolean;end Queue;
queue.adsqueue.ads
To write Client only need to look atTo write Client only need to look at
22http://libre.adacore.com © AdaCore under the GNU Free Documentation License
Aside: use clauseAside: use clause
with Queue; use Queue;procedure Client is Queue_Error : exception; X : Integer;begin Queue. Add (3); Queue. Add (4);
if not Queue. Empty then X := Queue. Get; else raise Queue_Error; end if;end Client;
23http://libre.adacore.com © AdaCore under the GNU Free Documentation License
• Programming in the Large– specification &
implementation• specification
• implementation
• specification rules in Ada
24http://libre.adacore.com © AdaCore under the GNU Free Documentation License
ONEONE possible possible implementationimplementation
of packageof packageQueueQueue
This implementationThis implementation raises Constraint_Error raises Constraint_Errorif more than Max_Sizeif more than Max_Size
elements are put in the Queue.elements are put in the Queue.
25http://libre.adacore.com © AdaCore under the GNU Free Documentation License
Circular BufferCircular Buffer
Q
0 1Max_Size - 1
Q_Last Q_First
28http://libre.adacore.com © AdaCore under the GNU Free Documentation License
ANOTHERANOTHER possible possible implementationimplementation
of packageof packageQueueQueue
29http://libre.adacore.com © AdaCore under the GNU Free Documentation License
Linked ListLinked List
Q_LastQ_First
Free
34http://libre.adacore.com © AdaCore under the GNU Free Documentation License
A Spec can have several A Spec can have several implementationsimplementations
• Can change implementation
• WITHOUT having to change ANY of the client’s code
package Queue is procedure Add (Element : Integer);
function First return Integer; function Get return Integer;
function Empty return Boolean;end Queue;
package Queue is procedure Add (Element : Integer);
function First return Integer; function Get return Integer;
function Empty return Boolean;end Queue;
queue.adsqueue.ads
firstimplement.
firstimplement.
secondimplement.second
implement.
35http://libre.adacore.com © AdaCore under the GNU Free Documentation License
• Programming in the Large– specification &
implementation• specification
• implementation
•specification rules in Ada
36http://libre.adacore.com © AdaCore under the GNU Free Documentation License
In AdaIn Ada
• Spec always checked against implementation
• Must with the specs that you are going to
use (not in C)
• Packages provide multiple name spaces
38http://libre.adacore.com © AdaCore under the GNU Free Documentation License
Must with Specs usedMust with Specs used
with Queue;procedure Client is ...begin Queue.Add (3); ...end Client;
Compilationerror
39http://libre.adacore.com © AdaCore under the GNU Free Documentation License
Multiple Name SpacesMultiple Name Spacespackage Queue is procedure Add (E : Integer); ...end Queue;
package Queue is procedure Add (E : Integer); ...end Queue;
package Set is procedure Add (E : Integer); ...end Set;
package Set is procedure Add (E : Integer); ...end Set;
with Queue;with Set;procedure Client isbegin Queue.Add (3);
Set.Add (99);end Client;
40http://libre.adacore.com © AdaCore under the GNU Free Documentation License
Use Clause and AmbiguitiesUse Clause and Ambiguitiespackage Queue is procedure Add (E : Integer); ...end Queue;
package Queue is procedure Add (E : Integer); ...end Queue;
package Set is procedure Add (E : Integer); ...end Set;
package Set is procedure Add (E : Integer); ...end Set;
with Queue; use Queue;with Set; use Set;procedure Client isbegin Add (123);end Client;
Compilationerror
ambiguity
41http://libre.adacore.com © AdaCore under the GNU Free Documentation License
But … Ada has overloadingBut … Ada has overloadingpackage Queue is procedure Add (E : Integer); procedure Add (E : Float); ...end Queue;
package Queue is procedure Add (E : Integer); procedure Add (E : Float); ...end Queue;
with Queue; use Queue;
procedure Client isbegin Add (123);
Add (3.141);end Client;
42http://libre.adacore.com © AdaCore under the GNU Free Documentation License
• Programming in the Large
– specification & implementation
– privacy
– abstract data types
– hierarchical packages
43http://libre.adacore.com © AdaCore under the GNU Free Documentation License
package Queues is type Queue is …;
procedure Add (Q : Queue; Element : Integer); function First (Q : Queue) return Integer; function Get (Q : Queue) return Integer; function Empty (Q : Queue) return Boolean;end Queues;
package Queues is type Queue is …;
procedure Add (Q : Queue; Element : Integer); function First (Q : Queue) return Integer; function Get (Q : Queue) return Integer; function Empty (Q : Queue) return Boolean;end Queues;
Having Several QueuesHaving Several Queues
45http://libre.adacore.com © AdaCore under the GNU Free Documentation License
Using Several QueuesUsing Several Queues
with Queues; use Queues;procedure Client is Q1 : Queue; Q2 : Queue;
begin Add (Q1, 123);
Add (Q2, 3);
Add (Q2, Get (Q1));end Client;
46http://libre.adacore.com © AdaCore under the GNU Free Documentation License
One possible One possible implementation ...implementation ...
package Queues is type Queue is …;
procedure Add (Q : Queue; Element : Integer); function First (Q : Queue) return Integer; function Get (Q : Queue) return Integer; function Empty (Q : Queue) return Boolean;end Queues;
type Q_Element;type Element_Ptr is access Queue_Element;
type Queue_Element is record Val : Integer; Next : Element_Ptr;end record;
type Queue is record First : Element_Ptr; Last : Element_Ptr;end record;
type Q_Element;type Element_Ptr is access Queue_Element;
type Queue_Element is record Val : Integer; Next : Element_Ptr;end record;
type Queue is record First : Element_Ptr; Last : Element_Ptr;end record;
47http://libre.adacore.com © AdaCore under the GNU Free Documentation License
Client code allowed to Client code allowed to depend on the depend on the
implementation !implementation !with Queues; use Queues;procedure Client is Q1 : Queue; Q2 : Queue;
begin Add (Q1, 123); Add (Q2, 3);
Q2.Last := null;
end Client;
OK
48http://libre.adacore.com © AdaCore under the GNU Free Documentation License
Another implementation ...Another implementation ...
package Queues is type Queue is …;
procedure Add (Q : Queue; Element : Integer); function First (Q : Queue) return Integer; function Get (Q : Queue) return Integer; function Empty (Q : Queue) return Boolean;end Queues;
Max_Size : constant := 100;type Q_array (Natural range <>) of Integer;
type Queue is record Q : Q_Array (0 .. Max_Size); First : Natural; Last : Natural; Size : Natural;end record;
Max_Size : constant := 100;type Q_array (Natural range <>) of Integer;
type Queue is record Q : Q_Array (0 .. Max_Size); First : Natural; Last : Natural; Size : Natural;end record;
49http://libre.adacore.com © AdaCore under the GNU Free Documentation License
… … breaks client code !breaks client code !
with Queues; use Queues;procedure Client is Q1 : Queue; Q2 : Queue;
begin Add (Q1, 123); Add (Q2, 3);
Q2.Last := null;
end Client;
Compilationerror
50http://libre.adacore.com © AdaCore under the GNU Free Documentation License
Even without changing Even without changing the implementationthe implementationthere is a there is a PROBLEMPROBLEM
with Queues; use Queues;procedure Client is Q1 : Queue; Q2 : Queue;
begin Add (Q1, 123); Add (Q2, 3);
Q2.Last := null;
end Client;
Q2 is in aninconsistent
state
33FirstLast
null
Q2:
51http://libre.adacore.com © AdaCore under the GNU Free Documentation License
You need PRIVACYYou need PRIVACY
• Exposing your data structures is risky
– Client code may manipulate the structures directly without using your own services
– Client code is hard to change
52http://libre.adacore.com © AdaCore under the GNU Free Documentation License
ThinkThink BIGBIG
what if what if the the QueuesQueues package package
is is used byused by 1000s1000s of other of other packagespackages
53http://libre.adacore.com © AdaCore under the GNU Free Documentation License
• If there is a bug concerning a Queue, you may have to look at 1000s of packages to find the bug
• If you change the implementation you may have to update 1000s of packages
54http://libre.adacore.com © AdaCore under the GNU Free Documentation License
• Programming in the Large
– privacy•private types
• private types & discriminants
• limited private types
55http://libre.adacore.com © AdaCore under the GNU Free Documentation License
Private typesPrivate types
package Queues is type Queue is private;
procedure Add (Q : Queue; Element : Integer); function First (Q : Queue) return Integer; function Get (Q : Queue) return Integer; function Empty (Q : Queue) return Boolean;
private type Queue is …;end Queues;
package Queues is type Queue is private;
procedure Add (Q : Queue; Element : Integer); function First (Q : Queue) return Integer; function Get (Q : Queue) return Integer; function Empty (Q : Queue) return Boolean;
private type Queue is …;end Queues;
56http://libre.adacore.com © AdaCore under the GNU Free Documentation License
In any implementation ...In any implementation ...package Queues is type Queue is private;
procedure Add (Q : Queue; Element : Integer); function First (Q : Queue) return Integer; function Get (Q : Queue) return Integer; function Empty (Q : Queue) return Boolean;
private type Queue_Element; type Element_Ptr is access Queue_Element; type Queue_Element is record Val : Integer; Next : Element_Ptr; end record;
type Queue is record First : Element_Ptr; Last : Element_Ptr; end record;end Queues;
57http://libre.adacore.com © AdaCore under the GNU Free Documentation License
… … private types are PRIVATEprivate types are PRIVATE
with Queues; use Queues;procedure Client is Q1 : Queue; Q2 : Queue;
begin Add (Q1, 123); Add (Q2, 3);
Q2.Last := null;
end Client;
Compilationerror
58http://libre.adacore.com © AdaCore under the GNU Free Documentation License
Advantages of Advantages of privateprivate types types
• Enforces the contract of a specification
• No client code can corrupt your data structures
• Can change implementation without changing client code
66http://libre.adacore.com © AdaCore under the GNU Free Documentation License
• Programming in the Large
– privacy• private types
• private types & discriminants
• limited private types
67http://libre.adacore.com © AdaCore under the GNU Free Documentation License
with Queues; use Queues;procedure Client is Q1 : Queue; Q2 : Queue;
X : Integer;
begin Add (Q1, 123); Add (Q1, 3);
Q2 := Q1;
X := Get (Q2);end Client;
Does this affect Q1 ?
68http://libre.adacore.com © AdaCore under the GNU Free Documentation License
it depends on … the it depends on … the implementation !implementation !
• If a Queue is implemented with
– a pointer then Get (Q2) MODIFIES Q1
– a record containing an array then Get (Q2) does NOT modify Q1
69http://libre.adacore.com © AdaCore under the GNU Free Documentation License
with Queues; use Queues;procedure Client is Q1 : Queue; Q2 : Queue; X : Integer;begin Add (Q1, 123);
Add (Q1, 3);
Q2 := Q1;
X := Get (Q2);X := Get (Q2);end Client;
123123Q1: 33
Q2:
123123Q1:
123123Q1: 33
Q2:
Pointer Pointer implementationimplementation
Pointer Pointer implementationimplementation
70http://libre.adacore.com © AdaCore under the GNU Free Documentation License
limited private typeslimited private types
• NO assignment :=
• NO equality comparison =
71http://libre.adacore.com © AdaCore under the GNU Free Documentation License
package Queues is type Queue is limited private;
procedure Add (Q : Queue; Element : Integer); function First (Q : Queue) return Integer; function Get (Q : Queue) return Integer; function Empty (Q : Queue) return Boolean;
private type Queue is …;end Queues;
package Queues is type Queue is limited private;
procedure Add (Q : Queue; Element : Integer); function First (Q : Queue) return Integer; function Get (Q : Queue) return Integer; function Empty (Q : Queue) return Boolean;
private type Queue is …;end Queues;
72http://libre.adacore.com © AdaCore under the GNU Free Documentation License
with Queues; use Queues;procedure Client is Q1 : Queue; Q2 : Queue;
X : Integer;
begin Add (Q1, 123); Add (Q1, 3);
Q2 := Q1;
end Client;
COMPILATIONERROR
:= forbidden
83http://libre.adacore.com © AdaCore under the GNU Free Documentation License
• Programming in the Large
– specification & implementation
– privacy
– abstract data types
– hierarchical packages
84http://libre.adacore.com © AdaCore under the GNU Free Documentation License
To add functionality ...To add functionality ...
package Queues is type Queue is private;
procedure Add (Q : Queue; Element : Integer); function First (Q : Queue) return Integer; function Get (Q : Queue) return Integer; function Empty (Q : Queue) return Boolean;
private type Queue is …;end Queues;
function Last (Q : Queue) return Integer;
function Last (Q : Queue) return Integer;
Must add it to
QueuesQueue is a private type
85http://libre.adacore.com © AdaCore under the GNU Free Documentation License
But ...But ...
• Every time you change a spec you must recompile all its clients
• Every time you change a module you must RETEST the whole module
86http://libre.adacore.com © AdaCore under the GNU Free Documentation License
Solution: use child unitsSolution: use child units
package Queues is type Queue is private;
procedure Add (Q : Queue; Element : Integer); function First (Q : Queue) return Integer; function Get (Q : Queue) return Integer; function Empty (Q : Queue) return Boolean;
private type Queue is …;end Queues;
queues.ads
function Queues . Last (Q : Queue) return Integer;queues-last.ads
Child subprogram
87http://libre.adacore.com © AdaCore under the GNU Free Documentation License
Child Units RulesChild Units Rules
• The body or private part of a child unit can see the private part of all of its parents
• The spec of a child unit does NOT
88http://libre.adacore.com © AdaCore under the GNU Free Documentation License
Using a child unitUsing a child unit
with Queues; use Queues;with Queues.Last;procedure Client is Q : Queue; X : Integer;
begin Add (Q, 123); Add (Q, 3);
X := Queues.Last (Q);end Client;
89http://libre.adacore.com © AdaCore under the GNU Free Documentation License
package Queues is type Queue is private;
procedure Add (Q : Queue; Element : Integer); function First (Q : Queue) return Integer; function Get (Q : Queue) return Integer; function Empty (Q : Queue) return Boolean;
private type Queue is …;end Queues;
queues.ads
package Queues . New_Functionality is function Last (Q : Queue) return Integer;end Queues . New_Functionality
queues-new_functionality.ads
Child package
90http://libre.adacore.com © AdaCore under the GNU Free Documentation License
with Queues; use Queues;with Queues.New_Functionality;procedure Client is Q : Queue; X : Integer;
begin Add (Q, 123); Add (Q, 3);
X := Queues.New_Functionality.Last (Q);end Client;