In the Name of God Modularity And Data Abstraction Ada Programming Language Chapter 7 1 The software crisis & reliable programming 1970 Software Crisis software cost increase without bound Dijkstra difficulty of producing a program program length2 But this proportion must become linear 2 Parnas’s Principle Control of complexity of a large program Modularization Modules are independent of each other in debug, understand & maintain. Parna’s principle : There should be one module for each difficult design decision in the program. If the decision changed, the corresponding module will be changed. Information Hiding 3 Abstract Data Types Data structure representation design decision A common stack implementation : array or linked list set implementation : array of values or bit string Any manipulation must be through procedures. Users must do abstract operations on the DS. Modules provides this abstract operations. Abstract Data Types Abstract operation : push & pop on the stack DS Concrete operation : pointer operations 4 Experimental Abstract Type Languages 1973 : Languages that support data types and modules. Alphard, CLU, Mesa, Euclid, Modula Many of them has the construct of a class, first included in Simula67. These experiences were important for the development of Ada. 5 DoD Saw the Need for a New Language 1970 : the need for a new PL for military services in embedded (or mission critical) computer applications. Embedded : the computer is integrated with some larger system. Nonembedded : i.e. scientific & data processing applications. DoD spent a lot of money for embedded applications, but because of multiple PLs much of them has the portability & reuse problem HOLWG group was created. Higher Order Language Working Group 6 A Series of specifications HOWLG published a series of specifications, each more detailed & specific than the previous 1975 1975 1976 1978 1979 Strawman Woodenman Tinman Ironman Steelman 7 Information Hiding, Verification, concurrency General requirements on the language design More specific requirements Readability Simplicity Module facility to support information hiding Concurrent programming Verification of program correctness Concrete requirements Character set Commenting conventions 8 Several competing designs winner : Ada 26 existing languages was studied, none is usable At first,16 proposals The winner named Ada Augusta Ada, A mathematician and Charles Babbage’s first programmer A tradition of naming PLs after mathematicians Become an ISO standard in 1987 9 No Subset or Superset Portability purpose :No subset or superset Register the ‘Ada’ name as trademark. No subset & superset can legally named Ada How to understand which compiler implements the spec? Validation Procedure, comprising over 2500 tests, attempts to ensure no more & no less than the standard language 10 Ada Has Been Revised 1983 : 1st version, Ada83 1988 : new version, Ada95 1990 report : 41 requirement & 22 new topics. 1995 : resulting revision & includes ideas from 5th generation OO PLs. 11 Ada95 A language that specify all the specification was very detailed. Ada95 1. 2. 1. core languages 2. six special need annexes must be implemented Optional extensions for particular application areas (system programming, information systems, real-time systems, numerical programming, distributed systems, safety & security) 12 Design: Structural Organization Syntax quite similar to Pascal’s Keywords in lowercase Others mixed (lower & upper) Declarations Ada’s constructs Expressions Statements Types 13 Ada’s constructs Expressions & statements similar to Pascal Types also similar but more flexible & less problem Declarations object are very different type subprogram package task 14 package Tables is type Table is array (Integer range < > ) of float; procedure BinSearch (T: Table; Sought: Float; Location: out Integer; Found: out Boolean) is subtype Index is Integer range T’First .. T’Last; Lower: Index := T’First; Upper: Index := T’Last; Middle: Index := (T’First+ T’Last)/2; begin loop if T (Middle)=Sought then location:=middle; Found:=true; return; elsif Upper<Lower then Found:=false; return; elsif T (Middle)>Sought then Upper := Middle-1; else Lower:=Middle+1; end if; Middle:=(Lower+ Upper)/2; end loop; end BinSearch; end Tables; 15 Declarations Object same as Pascal’s constant & variable declarations. Subprogram same as Pascal’s function & procedure declarations & also operator overloading. Package & Tasks most important facilities declare modules. Tasks can execute concurrently. Basic blocks of Ada programs. 16 modules Communication through interfaces. specification body (definition) Implements information hiding principle 17 Ada Compiler 1. Syntactic analyzer (parser) More complicated than Pascal Some have syntax-directed editor Generates parse tree 2. Semantic analyzer Type checking Process generic declarations & overloaded operators More complex than Pascal’s Generates program tree 3. 4. Optimizer Code generator 18 Design: Data structure & typing The numeric types are generalized. Integer type : like Pascal, plus range constraint. type coordinate is range -100 .. 100 Real Floating point Type coefficient is digits 10 range -1.0e10 .. 1.0e10 Fixed point If the computer has single or double precision the compiler selects between them. 19 Numeric Types… Float Short_Float Long_Float Programmers are encouraged to use digit constraint rather than the above types to be more machine independent. Preservation of information principle Floating-point arithmetic : Maximum precision & then rounded. 20 Floating point Approximate Arith. with a relative error bound Fixed point Absolute error bound It fell into disuse after introducing Floating points. The rule of early computers. Still in use for commercial programming More complicated arithmetic Ada must support it, because in some embedded systems peripheral devices (i.e. ADC) 21 use this method. Fixed point Numbers type Dollars is delta 0.01 range 0.00 .. 1_000_000.00 Absolute error bound Values of Dollars are multiples of 0.01 16.75=1675*0.01 2=200*0.01 Min Number of bits: log 12(10000000) 0.01 26.6 27 Bits If delta a power of 2 : left or right shift Compiler sometimes do this itself 22 Data Structure & Typing Constructors Are Based on Pascal’s Similar to Pascal’s Name equivalence is used. 2 reasons Repeating a type definition means logical difference. Structural equivalence isn’t well defined. 2 new concepts : subtype & derived type 23 Subtypes Constraints defines the subtype of the base type. Arithmetic operations are allowed. Compatible with its base type & other subtypes of its base type (with runtime constraint check) Subtype Index is Integer range 1 .. 100 keyword 24 Derived Types Type percent is new Integer range 0 .. 100 It inherits all of the functions (user defined or built-in) from base type. We can define abstractly-different derived type. Conversion can be done explicitly between base/derived. 25 Constraints replace subranges 1. 2. 3. 4. Replacement of Pascal subrange constructor constraint Range constraint Accuracy constraint Discriminant constraint Index constraint 26 1.Range constraint Integer range 1..100 The same implementation as Pascal’s Runtime expressions are allowed 27 Accuracy constraint Float digits 10 range -1e6 .. 1e6 28 Discriminant constraint Person (Male) is a type [person is a variant record of Male , Female] A runtime check is necessary in the assignment of a Person to a Person (Male) 29 Index constraint 2 problems of Pascal’s arrays Static indexes Passing arrays with different sizes to a function (i.e. sum) These problems are solved Type Vector is array (integer range < >) of float Data: Vector (1..100) Days : Vector (1 .. 365) Function sum (V : vector) return Float is … 30 Index constraint The compiler must pass actual bounds of the array as Hidden parameter V’First , V’Last , V’Range Name of the array For I in V’Range loop Total := Total + V(I) End loop; 31 Enumerations can be overloaded Pascal doesn’t allow overlap of the elements of the enumeration types. Type primary is ( Red, Blue, Green ) Type StopLight ( Red, Yellow, Green ) the Red identifier overloaded to 2meaning Ada uses context to determine which Red is meant In many situations programmers are required to specify. Primary (Red), StopLight (Red) 32 Why we need overloaded enumerations? Convenience 1. In natural languages, one word has several meanings. Ada character set : enumeration type 2. Characters may be repeated in different enumerations 33 Ada character set : enumeration type Type Discode is (‘A’,’B’,’C’,’D’,’E’,’F’,’G’, ’H’,’I’,’J’,’K’,’L’,’M’,’N’,’O’,’P’,’Q’,’R’,’S’, ’T’,’U’,’V’,’W’,’X’,’Y’,’Z’,’0’,’1’,’2’,’3’,’4’, ’5’,’6’,’7’,’8’,’9’,’+’,’-’,’.’) 34 7:4 Design: Name Structures The primitives are those of Pascal Constant Variable Type Procedure Function Task Package 35 Variable declaration One of the simplest declaration is the variable declaration It allows initialization Eliminates a common error: using an uninitialized variable It causes a program to be more readable The initial value is not restricted to be a constant. It can be an expression 36 Constant declaration It is more general than a Pascal constant Its value can be computed during the execution of the program This facility aids program maintenance Example: Feet_Per_Mile: constant Integer := 5280; PI: constant := 3.14159_26535_89793 37 Ada 83 allows the type to be omitted if it is a numeric type, and if the expression on the right involve only: Literals Names of numeric literals Calls of the predefined function ABS Parenthesized literal expression Predefined arithmetic operation 38 This feature is included to allow constants of type universal integer and universal real to be named These types Have the maximum possible precision Are not normally accessible to programmers This kind of declaration permits the programmer to name a type- and precision independent numerical constant 39 Specifications and definitions Information hiding was supported by the ability to divide declarations into two parts: Interface Implementation Since subprograms form most of the interface to a package subprogram specification is very important 40 Global Variables Considered Harmful Problems with block structure: Side effects: Result from hidden access to a variable Indiscriminate access: The problem of indiscriminate access is the inability to prevent access to a variable 41 Vulnerability: Means a program segment can not preserve access to a variable No overlapping definitions: The need for this arises from attempts to modularize large systems We can not control share access to variables 42 Side Effects Example: Integer procedure Max (x,y); integer x, y; begin count := count + 1; Max := if x>y then x else y; end It makes it very difficult to determine the effects of a procedure from the form of a call of the procedure 43 Indiscriminate Access Example: begin integer array s[1:100]; integer top; procedure Push(x); integer x; begin top := top + 1; s[top] := x; end; top := 0; … uses of Push … end 44 Vulnerability Under certain circumstances it is impossible to preserve access to a variable The basic problem is that new declarations can be interposed between the definition and use of a variable 45 Example: Begin integer x; …… many lines of code …… begin real x; …… many lines of code …… x := x + 1; ……………………………………… end; end; 46 No Overlapping Definitions Example: begin array DA[…]; array DB[…]; procedure p1; procedure p2; procedure p3; procedure p4; … end ….; ….; ….; ….; 47 Attributes of an Alternative The default should not be to extend the scope of a variable to inner blocks The right to access a name should be by the mutual consent of the creator and accessor of the name Access right to a structure and its substructures should be decoupled. 48 It should be possible to distinguish different types of access Declaration of definition ,name access,and allocation should be decoupled 49 Two Important Principles of Information Hiding One must provide the intended user with all the information needed to use the module correctly and nothing more One must provide the implementer with all the information needed to complete the module and nothing more 50 Packages and Info hiding Package is primary Ada construct for implementing information hiding. Can conceive of an Ada package as the implementation of an ADT. Two parts Interface specification Body 51 Package Interface Spec Contract with user Addresses Rule 1 of Parnas’s Principles One must provide the intended user with all the information needed to use the module correctly and nothing more. package Complex_Type is ...specification of public names ... end Complex_Type 52 Package Interface Spec package Complex_Type is type Complex is private; I: constant Complex; function “+” (X,Y : Complex) return Complex; function “-” (X,Y : Complex) return Complex; function “*” (X,Y : Complex) return Complex; function “/” (X,Y : Complex) return Complex; function Re (X : Complex) return Float; function Im (X : Complex) return Float; private type Complex is record Re, Im : Float := 0.0; end record; I : constant Complex := (0.0, 1.0); end Complex_Type 53 Package Body Known only to implementor Contains the information for Rule 2 of Parnas’s Principles One must provide the implementor with all the information needed to complete the module and nothing more. 54 Package Body package body Complex_Type is function “+” (X,Y : Complex) return Complex is begin return (X.Re + Y.Re, X.Im + Y.Im); end; function “*” (X,Y : Complex) return Complex is RP: constant Float := X.Re*Y.Re – X.Im*Y.Im; IP: constant Float := X.Re*Y.Im + X.Im*Y.Re; begin return (RP, IP); end; function Re (X : Complex) return Float is begin return X.Re; end;; function Im (X : Complex) return Float is begin return X.Im; end; function “+” (X : Float; Y : Complex) return Complex is begin return (X + Y.Re, Y.Im); end; ----- other definitions to complete the package ---- end Complex_Type 55 The Mutual Consent Problem Implementor can control access to names by their placement. User needs to be able to control access to names visible to him Packages solve this problems, too “use” declaration 56 The Mutual Consent Problem declare use Complex_type; X,Y : Complex; Z : Complex := 1.5 + 2.5*I; begin X := 2.5 + 3.5*I; Y := X + Z; Z := Re(Z) + Im(X)*I; if X = Y the X := Y + X; else X := Y*Z; end if; end; 57 Packages for Shared Data package Communication is In_Ptr, Out_Ptr : Integer range 0..99 := 0; Buffer : array (0..99) of Character := (0..99 => ‘ ‘); end communication; 58 Packages for Shared Data with Communication; use communication procedure P is begin ... Buffer(In_Ptr) := Next; In_Ptr := (In_Ptr + 1) mod 100; ... end P; with Communication; use Communication; procedure Q is begin ... C := Buffer(Out_Ptr); ... end Q; 59 Data Structure Management package Stack1 is procedure Push (X : in Integer); procedure Pop (X : out Integer); function Empty return Boolean; function Full return Boolean; Stack_Error : exception; end Stack1; 60 Package Body package body stack1 is ST : array(1..100) of Integer; Top : Integer range 0..100 := 0; procedure Push (X : in Integer) is begin if Full then raise Stack_Error; else Top := Top +1; ST (Top) := X; end if; end Push; procedure Push (X : out Integer) is begin … end Pop; function Empty return Boolean is begin return Top = 0; end; function Full return Boolean is begin return Top =100; end; end stack1; 61 Data Structure Management declare use Stack1; I, N : Integer; begin ... Push(I); Pop(N); ... if Empty then Push(N); end if; ... end; 62 Data Structure Management Dot notation: Stack1.Push(I); Stack1.Pop(N); if Stack1.Empty then Stack1.Push(N); end if; But there’s a problem: What if you need more than one stack? 63 Generic Packages Permit the definition of multiple data structures of the same type without copying all the code 64 Generic Packages generic package Stack is procedure Push (X : in Integer); procedure Pop (X : out Integer); function Empty return Boolean; function Full return Boolean; Stack_Error : exception; end Stack; 65 Using Generic Packages Works as if it’s a new type, which it really is if you look at the declaration package Stack1 is new Stack; package Stack2 is new Stack; Stack1.push(x); Stack2.pop(y); Static instantiation 66 Parameterized Packages What if you wanted different size stacks? Out definition is fixed at 100 entries 67 Parameterized Packages generic Length : Natural := 100; package Stack is procedure Push (X : in Integer); procedure Pop (X : out Integer); function Empty return Boolean; function Full return Boolean; Stack_Error : exception; end Stack; 68 Parameterized Packages package Stack1 is new Stack(100); package Stack2 is new Stack(64); Now we can have as many stacks as we like, in whatever size we like. But what if you need a stack of characters instead of a stack of integers? 69 Type Parameters generic Length : Natural := 100; type Element is private; package Stack is procedure Push (X : in Element); procedure Pop (X : out Element); function Empty return Boolean; function Full return Boolean; Stack_Error : exception; end Stack; 70 Type Parameters package Stack1 is new Stack(100, Integer); package Stack2 is new Stack(64, character); Now we can have as many stacks as we like, in whatever size and with whatever type we like. What else could you ever ask for? 71 Compiling Generic Packages Relative easy if there are no parameters Still relatively simple for simple parameterization Type parameters more complicated Calculating space for the array Need different code for different types Must generate code for each parameterized set of types! But still want to eliminate duplicate code 72 Internal vs. External Representation Internal Representation Stack1.Pop(n) Number of instances limited by the number of generic instantiations Precursor of classes as seen in Simula and Smalltalk External Representation Complex type Can treat type as a bona fide data value Number of instances can be determined dynamically 73 Overloaded Procedures Identification of what the operator really does requires understanding the context of the operator in question Worse in nested function calls Z := F (G (X, Y)); Solve by propagating type information up & down an expression tree in several passes. 74