740 likes | 774 Views
Ada95: A brief History. 1975-1979: strawman-steelman requirements, Pascal is base 1981 : Green wins, becomes preliminary Ada 1983 : ANSI Standard, first validated compiler 1987 : ISO Standard 1990-1994 : Revision Process 1995 : ANSI - ISO Ada 95 Standard 1995 : First validated GNAT compiler.
E N D
Ada95: A brief History • 1975-1979: strawman-steelman requirements, Pascal is base • 1981 : Green wins, becomes preliminary Ada • 1983 : ANSI Standard, first validated compiler • 1987 : ISO Standard • 1990-1994 : Revision Process • 1995 : ANSI - ISO Ada 95 Standard • 1995 : First validated GNAT compiler ada-typesI- 1
Design principles (Why Ada?) • Software Engineering: programming in the large • Readability over writability • Rigorous standard for portability • Precise semantics • Built-in concurrency • Strong-Typing: all unsafe code is explicit ada-typesI- 2
Ada, C++ and Java • Big, capable languages • strong typing : Ada, C++, Java • Generics : Ada C++ • Concurrency : Ada Java • Packages: Ada C++ and Java • Ahead of its time in design • Out of step in implementation • Between language generations ada-typesI- 3
Key Goals • Readability : wordy but readable • strong typing : find errors when you compile, don’t debug • Programming in the large: package it and offer interfaces • Exception Handling: Expect errors, deal with them. • Data abstraction : apples are not oranges (user defined types will not be set to equal without casting) • Object orientation : Inheritance and late binding • Tasking : walk, chew gum, etc. (I.e. threads) • Generic units : similar functionality across different types ada-typesI- 4
The canonical example • with Text_Io; use Text_Io; • procedure example is -- Does not have to be called “main” • begin • Put_Line (“easier than we thought!”); • end; ada-typesI- 5
A small package interface • Package Math_Functions is -- Here we are defining the interfaces • function Sqrt (X : Float) return Float; • function Exp (Base : Float; Exponent : Float) return Float; • end Math_Functions; ada-typesI- 6
Using the package • with Math_Functions; with Gnat_IO; use Gnat_IO; • procedure Example2 is • Val : Float; • begin • get (Val); • put (“Sqrt (“); put (Val); put (“) = “); • put (Math_Functions.Sqrt (Val)); • new_line; • end; ada-typesI- 7
Dissection of this package • Package body Math_Functions is -- Separately compiled unit • Epsilon : constant := 1.0e-7; -- Declared variable • function Sqrt (X : Float) return Float is -- functions have in params and ret • Result : Float := X / 2.0; -- initialize a variable. • begin • while abs (Result * Result - X ) > Epsilon loop • Result := 0.5 * (X / Result + Result); -- X/Result = Result if done • end loop; • return Result; • end Sqrt; • ... • end Math_Functions; -- Could be many functions here. ada-typesI- 8
Summary of Package Features • Package has data and functions. • It can be accessed by writing “with” (and avoid qualifying by writing “use”). • A full program is normally a bunch of packages together with a “main” procedure (lexically a subprogram) that starts the program. • Define the interface by giving the signatures (types in and out), also known as the specification or declaration, and then define the body separately (and privately). • Functions have in parameters and a return value. • Procedures can have in, out or in out parameters. • While loop is a nice way of programming this. ada-typesI- 9
Packages and Compilation • The compiler compiles one or more compilation units (compiler is not obligated to compile more than one at a time). These start with “with” and “use” clauses and then proceed to either a package declaration, a package body, a subprogram declaration, or a subprogram body. ada-typesI- 10
A larger package interface (visible part)(p. 28 of Barnes) • Package Buffer_System is -- Here we are defining the interfaces • type Buffer is private; -- Means insides are inaccessible to other packages • procedure Load (B : out Buffer; S : in String); • procedure Get (B : in out Buffer; C: out Character) ; • -- in out because Buffer is changed by the Get. • private • Max: constant Integer: = 80 ; type Buffer is record • Data: String(1..Max); • Start: Integer:= 1; • Finish: Integer:= 0; • end record; end Buffer_System; ada-typesI- 11
Body of Buffer (repeats declarations) • Package body Buffer_System is -- Separately compiled unit • procedure Load(B: out Buffer; S: in String) is • Begin • B.Start := 1; • B.Finish := S’Length; • B.Data(B.Start .. B.Finish):= S; • end Load; • ... • end Buffer_System; -- Could be many functions here. ada-typesI- 12
Using the Buffer as a Type • My_Buffer: Buffer; -- declare a variable of type Buffer • Load(My_Buffer, Some_String); • Get(My_Buffer, A_Character); • -- Key point. Given a package, can declare variables of types • -- in the package (e.g. package is Buffer_System; declare object • -- of type Buffer). • -- Package is like a C++ library. ada-typesI- 13
Access Types (Pointer) • Typed pointers, for type safety and to minimize aliasing.Want to be sure that a pointer points to a single type (at least for now): • type Handle is access Buffer; • Ptr : Handle := new Buffer; • Ptr.all is a Buffer. – could be an argument to a copy constructor • Can write Ptr.Start, Ptr.Data, etc. ada-typesI- 14
Enumeration Types (for colors, days of weeks etc.) • Simplest Implementation: literals are mapped into successive integers • Very common abstraction: list of names, properties • Expressive of real-world domain, hides machine representation • type suit is (hearts, diamonds, spades, clubs) ; • type direction is (east, west, north, south, lost); • Order of list implies that spades > hearts, etc. ada-typesI- 15
Enumeration types and strong typing • typeFruit is (Apple, Orange, Grape, Apricot); • type Vendor is (Apple, IBM, Hewlett Packard); • My_PC : Vendor; • Dessert : Fruit; • … • My_PC := Apple; • Dessert := Apple; • Dessert := My_PC; --ERROR (caught at compile time) ada-typesI- 16
Built-in enumeration types • type Boolean is (False, True); • type Character is (…. -- full ASCII. • type Wide_Character is ( … -- Unicode, or ISO646 ada-typesI- 17
Array Types • Index is typed: • type weekday is (Mon, Tue, Wed, Thu, Fri); • type workhours is array (Weekday) of integer; -- domain is Weekday, range is • -- an int representing number of hours • Predefined array: • type String is array (Positive range <>) of Character; ada-typesI- 18
Abstraction mechanisms • Packages • Private types • Objects and Inheritance • Classes, polymorphism, dynamic dispatching • Generic units • Concurrency : tasks and protected types ada-typesI- 19
Object-oriented Programming • Type extension • Inheritance and overriding • Run-time dispatching • Polymorphism • Class-wide programming • Abstract types and subprograms ada-typesI- 20
Inheritance • Three goals: • 1. Define one type in terms of another with extensions. (like java class inheritance) • 2. Allow derived type (one with extensions) to redefine operations. • 3. Be able to determine which operation to use at runtime. ada-typesI- 21
Type Hierarchies called “class” in Ada • A class is a family of types with the same ancestor (unlike C++/Java classes which are themselves hierarchically related) • An object of the class is identified at run-time by its tag. • Dynamic dispatching uses the tag of the object to determine the operation that applies. Dynamic = runtime. (This responds to third goal above.) • A classwide operation applies uniformly to all member of the class. • Reminder: Ada type is similar to Java class • Ada class is similar to hierarchically related Java classes. ada-typesI- 22
Type Extension • Mechanism to define new types by enrichment (i.e. add fields): • type GeoThing is tagged record • X_Coord, Y_Coord : Integer; • end record; • type Circle is new GeoThing with record • Radius : Float; • end record; ada-typesI- 23
Functions in type hierarchies • function Distance(O: in GeoThing) return Float is beginreturn Sqrt(O.X_Coord ** 2 + O.Y_Coord**2); end record; • function Area(O: in GeoThing) return Float is • begin • return 0.0; -- make it 0 because a GeoThing by default is a point • end Area; ada-typesI- 24
Functions in type hierarchies • function Area(O: in Circle) return Float is • begin • return 3.14*C.Radius**2; • -- circle has a different area from generic GeoThing • end Area; • -- So, distance function will apply to GeoThing and Circle but Area must be -- redefined for Circle. • -- This implies that the function Area that is going to be called should depend -- on the type of the object. ada-typesI- 25
Use of these functions • O: GeoThing := (3.2, 2.1); -- a geothing at location 3.2, 2.1 • C: Circle:= (1.0, 0.0, 4.2); -- a circle with center 1.0, 0.0 and radius 4.2 Area(O); -- returns 0.0 Area( C ); -- returns the area of the circle having radius 4.2 -- All of these facts can be determined at compile time. So this is called -- static binding. ada-typesI- 26
Class-wide Functions • In Ada, unlike Java and C++, a class is a hierarchy of types. (Types are analogous to classes in those languages). • Suppose we want to define a function that applies to all types of a class and that does something different for different types in the class. • In contrast: the function distance applies to all types of a class but does the same thing for the different types in the class. ada-typesI- 27
Example of Class function • function SquareArea(O: in GeoThing’Class) return Float is • begin • return (Area(O))**2; -- Call the area function for the object passed. • end SquareArea; • -- Unlike the distance function this one depends on the type • -- Area function. Which version of Area to call is determined at runtime and-- the proper version is then “dispatched”. • -- Please check out pp. 30-38 of Barnes (Point, Circle, Moment examples). ada-typesI- 28
Implications of not using Class • function SquareArea(O: in GeoThing) return Float is • begin • return (Area(O))**2; -- Call the area function for GeoThings always • end SquareArea; • -- Even if you called this one with a Circle, you’d call the Area function for -- GeoThings. This would be bad. ada-typesI- 29
Advanced Considerations: overdoing inheritance It’s not always a good idea to use inheritance. Consider the following (Barnes chap 19): • type Cylinder is new Circle with • record • Height: Float;-- cyliner is circle with height; sounds plausible… • end Cylinder; • -- To see whether it is good: ask can the class wide procedures apply to • -- this new object (e.g. what is distance to a cylinder?). • -- It just doesn’t make sense. ada-typesI- 30
Advanced Considerations: has vs. isa A Cylinder isa Circle doesn’t seem right. How about a Cylinder has a Circle. • type Cylinder is tagged • record • Base: Circle; • Height: Float; • end Cylinder; • -- We express “has” by making a Circle a member of Cylinder. • -- This way we don’t get spurious inheritance. ada-typesI- 31
Generic Units (Barnes chapter 11) • The basic tool for software reuse that cuts across types whether members of the same class or not. • Parameters can be types, objects, subprograms, packages. • Akin to C++ templates. • Absent from Java so far. ada-typesI- 32
A Generic Procedure (does not depend on nature of T) • Generic • type Item is private; • procedure Exchange (X, Y : in out Item); • procedure Exchange (X, Y : in out Item) is • T: Item; • begin • T: = X; X := Y; Y := T; • end; ada-typesI- 33
Instantiating the Generic Procedure for other types • procedure Swap is new Exchange(Float); • procedure Swap is new Exchange(Integer); • procedure Swap is new Exchange(Date); • … • -- So we can use Swap on many different types ada-typesI- 34
A Generic Package (interface) • Generic • type T is private; • package Stacks is • type Stack is private; • procedure Push (Thing : T ; On : in out Stack); • … • private • type Arr is array (1 .. Max) of T; • type stack is record • Top : Integer := 0; • contents : Arr; • end record; • end Stacks; • -- Body is pretty conventional (see section 11.1 of Barnes) ada-typesI- 35
Use of Stack Package (Barnes 17.1) • declare • package mystack is new Stack(129, Float); -- stack package of a certain size and type -- mystack is now instantiated and can be used just as the Math_Functions -- package was used before. • begin • X: Float:= 3.2; • mystack.push(X); • … ada-typesI- 36
Other Topics You Should Understand for project/core exam Abstract base classes (define interfaces to functions but no bodies, e.g. p. 38) Mixin Inheritance (mix generics and inheritance e.g. p. 466) Reflection (asking the type of an object). Tasking – we will discuss later Exceptions – we will discuss later ada-typesI- 37
The Type Model • Types and Subtypes • Declarations and their scope • Objects, constants and variables • Scalar types • Array types • Record types • Access types ada-typesI- 38
Types and Subtypes • A type is a set of values and a group of operations • Types with different names are distinct and incompatible (part of strong typing): name equivalence everywhere, instead of structural equivalence. (As we saw, if colors and days of the week are represented by integers, don’t want to be able to assign Wednesday to a color.) • Subtypes of the same base type are compatible. ada-typesI- 39
Built-in subtypes • type Integer is .. -- implementation defined • subtype Positive is integer range 1 .. Integer’Last; -- useful attribute • subtype Natural is integer range 0 .. Integer’Last; • X : integer := 500; • Y : Positive := 2 * X; • Z : Natural := - Y; -- illegal, raises constraint error ada-typesI- 40
Compile-time vs. run-time • Type properties are enforced by the compiler whenever possible: • x : integer := false; • -- program rejected • x : positive := f (z); • -- if f returns a non-integer, then program rejected, else need to check value at run-time (in this sense dynamic) ada-typesI- 41
Declarations and Scope • Declarations are elaborated in order of appearance in the program. • Entities become visible at the end of their declaration (usually) • Block structure allows arbitrary nesting of declarative regions. • Declarations can appear in • subprograms • packages • blocks • ... ada-typesI- 42
Blocks • Declare • X : Integer := F (5); • Y : Integer := 2 * X; • Z : Integer := Y * Z; -- Error: premature use of Z • X : Float ;-- Error: duplicate • begin • declare • X : Float := Float (Y); -- hides outer X • begin • Put_Line (Float’Image (X)); • end; • end; ada-typesI- 43
Variables and Constants • Variable declaration: • Limit : Integer := 25; • Offset : Integer range 1 .. 20; • Constant declaration: • Sqrt2 : constant float := Sqrt (2.0); • Always : constant Boolean := True; • Never : constant Boolean := not Always; ada-typesI- 44
Variables must be constrained • Subtype is constrained: • First_Name : String (1..5) := “Ralph”; • but not necessarily static (i.e. could depend on runtime values): • Last_Name : String (1 .. X * 2); • else subtype is indefinite but initial value provides bounds: • Comment : String := “this is obvious”; -- bounds are 1 .. 15 ada-typesI- 45
Multiple Declarations • This, That : T := F (1, 2, 3); • Is equivalent to • This : T := F (1, 2, 3); • That : T := F (1, 2, 3); • F is called twice. Important if expression has side-effect: • type Ptr isaccess R; • P1, P2 : Ptr := new R; • two R’s are allocated. ada-typesI- 46
Number Declarations • Pi : constant := 3.14159265; -- type deduced from value • Half_Pi : constant := Pi / 2; -- mixed arithmetic OK • Big : constant := 2 ** 200; -- legal • One : constant := 2 * Big / (Big + Big); -- must be exact ada-typesI- 47
Scalar Types • Discrete types • Integer types • Enumeration Types • Real types • Floating-point types • Fixed_point types ada-typesI- 48
Integer Types • Several predefined types: Integer, Long_Integer, Short_Integer • Specific bounds of type must be static: • type My_Int isrange -2 ** 16 .. 2 ** 16 - 1; • type Tiny isrange 0 .. 10; • By giving explicit bounds, program is more portable: each compiler will figure out what hardware type corresponds (because integers can be 16 bits on some machines and 64 bits on others). • Modular types: • type Byte is mod 2 ** 8; ada-typesI- 49
Integer Operations • Comparison Operators: = /= < <= > >= • Addition Operators: + - • Unary operators + - • Multiplying operators * / mod rem • Highest precedence Operators: ** abs ada-typesI- 50