Whirlwind Tour of Ada
Ada History
Versions
- Ada 83
- Original version
- Support for threads, generics (ie Java generic types)
- Partial support for OO
- Ada 95:
- Complete support of OO (but not interfaces)
- Expanded support of threads
- Support for multilanguage programming, ...
- Gnat: free compiler part of GNU gcc
- Backward/upward compatible
- Ada 05:
- Java-like interfaces (ie multiple specification inheritance)
- Object notation allowed
- Improved support for real-time and high integrity systems
- Improved standard packages
- Backward/upward compatible
Design Goals
- Program reliability and maintenance
- Program efficiency
- Programming as a human activity
- Emphasize readability over writability
- Programming in the large
- We will see examples of how the language supports these goals
Support for Design Goals
- Readability favored over writability (eg begin .. end vs {})
- Error prone notations avoided (eg = and :=)
- Strong typing (stronger than Java)
- Keep language small and consistent
- Support for large systems (ie packages)
- Support for abstract data types
- Support for multiple threads
- Validation suite: set of programs that test compiler
- Standardized before implementation
Application Areas
Hello World
-- Print a message!
-- File: hello1.adb
with ada.text_io;
procedure hello1 is
begin
ada.text_io.put_line("Hello ITEC 320 class!");
end hello1;
/////////////////////////////////////////////
// Java equivalent
class Hello{
public static void main(String[] args){
System.out.println("Hello from Java!");
}
}
Things to note:
- Context clause:
with ada.text_io;
- All packages referenced in a routine must be in the context clause
- Main routine:
procedure hello1 matches file name and where execution begins
- Use of begin/end instead of brackets
- ada.text_io.put_line: output a string
- Hello1 is user defined (Rules for identifiers are below)
- Edit, compile, run
Rules for Identifiers
- Begin with letter
- Followed by any number of letters, digits, underscores
- Underscore must be followed by a letter or digit
Edit, Compile, and Run
- Environments you can use:
- Adagide - simplest
- GPL - professional (comes free with gnat)
- Eclipse plugin
- Or you can use the command line
- Use Vim or another editor (eg notepad)
- Use gnat compiler (ie gnatmake)
- Commands to edit, compile, run:
> vim hello1.adb
> gnatmake hello1
> hello1
More information on Compile and run Hello World
Installing Gnat and an Ada Environment
Use Statement and More on Text_IO (hello2.adb)
- Another Hello World program:
with ada.text_io; use ada.text_io;
procedure hello2 is
begin
put_line("Hello ITEC 320 class!");
ada.text_io.put("Hello again!");
new_line;
put_line("Hello ITEC" & " 320 class!");
new_line(2);
put("See ");
put("you ");
put_line("later! ");
end hello2;
Things to note:
- use clause: packages in use clause don't need fully qualified names
(unless needed to disambiguate)
- put vs put_line: like print and println in java
- new_line, new_line(2): one or 2 (or any number) of newlines
- &: String concatenation
Numeric Types (average.adb)
- Let's look at some numeric types:
- Program average.adb (prettified) finds the average of three integers
(wow!)
- Things to note:
- Declaration section of program
- Numeric types
Integer and Float
- Declarations are written as variable: Type
- Assignment is
:= (= is equals)
- Explicit coercion (ie type cast): use type as function
- Strong type checking! (see below)
- Attributes: 'image and 'img operate like tostring (see below)
- Numeric IO packages for integers and floats
- Integer and float
put allow format control (see below)
- Numeric Literals (see below)
Strong Type Checking (average.adb continued)
- No implicit conversion of Integer to Float in assignment or IO,
as in Java
- Explicit conversion is required
- For assignment: both sides of assignment must be of same type
- Java will do automatic widening conversion on assignment, Ada will not.
- But subtypes have different rules
-- Ada // Java
i: Integer int i;
a: float; double a;
i := 3.0 i = 3.0;
a := 3; a = 3;
Both operands of arithmetic operators must be same type.
Java will do implicit coercion, Ada will not.
-- Ada // Java
a := i / 3.0; a = i / 3.0;
a := float(i) / 3.0; a = (double) i / 3.0;
a := float(i / 3); a = (double) (i / 3);
Must do IO with correct routine
-- Ada // Java
ada.integer_text_io.put(i); System.out.print(i);
ada.float_text_io.put(a); System.out.print(a);
Attributes and Other Types (average.adb continued)
- Example: attributes.adb and prettified
-
'img and 'image are attributes
- they are like toString
- variable'img provided by gnat, it's not standard Ada
- Most types allow 'img and 'image
- We'll see more attributes later, for example:
- Integer'value is inverse of 'image (eg Integer'value("456"))
- Integer'first - the largest integer
- Integer'last - the smallest integer
- Integer'range - the range from smallest to largest integer
- Character'val(65) - Character whose position is 65
- Character'pos('A') - position of 'A' in the set of Characters
- Boolean'val(0) - Boolean value at position 0 (ie false) in the
set of Boolean values
- Boolean'pos(true) - Position of true (ie 1)
Primitive Types (average.adb continued)
- Integer, Long_Integer
- Float
- Boolean: values are true and false
- Character (8 bit)
- Wide_Character (16 bit)
- Wide_Wide_Character (32 bit)
- String:
- Strings are arrays of characters
- Strings are fixed length
- 3 kinds of strings are available (discussed later)
Format Control (average.adb continued)
-
width, fore, aft, and
exp are keyword parameters
-
width is minimum width
-
fore is minimum number of places before the decimal
-
aft is number of places after the decimal
-
exp is minimum number of places for the exponent
Numeric Literals (average.adb continued)
- Floats must begin and end with a digit (eg ...)
- Underscores can be used (eg ...)
Operators
- Arithmetic:
+, -, *, /, mod, rem, **
- Boolean: And, Or, Not
- Parentheses required when using more than one
- Short circuit: And then, Or else
- Only evaluate second operator if necessary
If statement, For loop, Numeric input with Get (getcountpzn.adb)
- Demonstrates if statements, for loops, and the integer
get routine:
getcountpzn.adb and prettified
- Things to note:
- Type Natural is a subtype of the integers (ie 0 .. Integer'last)
- Use Natural when counting
- Natural is a subtype: it is a subset of the values in the type
Integer
- a variable of type Natural can be used anywhere a variable of type
Integer is expected (what does this sound like?)
- Constants must be initialized and can't appear on the
left of an assignment
- Assign multiple values in a single declaration
- Integer.text_io.get: See below
- For loop
- Parens not needed around condition
- For loop specifies precise range of values taken by loop variable
- Loop variable is implicitly declared
- Loops are marked with
loop ... end loop;
- End if required even if body has one statement
- If statements:
- Parens not needed around condition
- Syntax:
if ... elsif ... else ... end if
- else is optional
- any number of elsif can be used
- End if required even if body has one statement
More on Ada.Integer_text_io.get (geteofcountpzn.adb)
-
Ada.Integer_Text_io.get(v)
reads an integer from standard input and stores the value of that integer into variable
v
- Needed to read integers, as integers
-
Get reads from standard input (see below for more info on
standard input)
- A call to
Get skips white space until it finds an integer (or
an error occurs)
- Exceptions than can occur with a call to get:
- If eof is reached before a number is found, an END_ERROR exception occurs.
- If a non-numeric character is found, a DATA_ERROR exception occurs.
Standard Input
While loop and End of File test (geteofcountpzn.adb)
- Demonstrates while loop and the end of file test:
geteofcountpzn.adb and prettified
- Example showing basic structure for testing for end of file:
with ada.text_io; use ada.text_io;
with ada.integer_text_io; use ada.integer_text_io;
procedure eofloop is
i: Integer;
begin
while not ada.text_io.end_of_file loop
get(i);
put(i);
new_line;
end loop;
end eofloop;
When doing interactive I/O, end_of_file will return true when you enter
- control-D (linux and unix)
- control-Z [on a line by itself] (windows)
Things to note:
- ada.text_io.end_of_file
- Loop structure: loop ... end loop;
- How to do redirection
Arrays and Array Types (countposzeroneg.adb)
- Demonstrates Arrays and Array Types:
countposzeroneg.adb and prettified
- Things to note:
- The program defines a new type for the array
-
Int_Array is a type; theNums is an array
variable
- Arrays can be assigned using an aggregate assignment (ie the list in
parentheses is an aggregate value)
Using Procedures and Functions (With Array Parameters) (sumcountprocs.adb)
- Demonstrates breaking CountPosZeroNeg into separate routines?
- Use procedures and functions to sum and count positives, etc.:
sumcountprocs.adb
and
prettified
- Things to note:
-
Order of declarations: constants and types, procedures and functions,
variables for main routine
- Must define before use!
- Variables declared inside procedures are called local variables
- Where are the variables for sumcountprocs?
- Functions are like java methods with non-void return types
- Procedures are similar to methods with void return type
- However, procedures can have out mode parameters that return
values to the caller (see below)
Parameter Modes (sumcountprocs.adb continued)
- Parameters have modes that specify the direction the values flow
- Possible parameter modes: In, Out, and In Out
- In: values passed from caller to called
- Out: values passed from called back to caller
- In Out: values passed from caller to called, and back!
- In Mode is the default
- Using a Structure Chart helps thinking about direction of
information flow
- What is the mode of the parameter for get?
More on Parameter Modes
- What kinds of errors could we detect:
- Attempting to assign a value to an in mode parameter
- Not assigning a value to an out mode parameter
- Attempting to change an in mode parameter by calling a procedure
- In mode parameters are treated like constants in the procedure:
procedure foo1(i: in Integer) is
begin
i := 3; -- error
Out mode parameters are uninitialized on entering the procedure:
procedure foo2(o: out Integer) is
j: Integer := o + 1; -- compiles, but erroneous
Out mode parameters must be given a value
procedure foo3(o: out Integer) is
begin
null;
end foo; -- compiles but erroneous
An in mode (formal) parameter can not be passed as an out mode (actual) parameter
procedure foo4(o: out Integer) is
begin
null;
end foo4;
procedure foo5(i: in Integer) is
begin
foo4(i); -- compilation error
To avoid side effects, only procedures can use out and in out mode. Functions can only
have in parameters (more later)
Filling the array using integer_text_io.Get (sumcountprocs2.adb)
More on Exceptions
- Common Exceptions:
- Data error: numeric get reached a non-number
- End error: numeric get reached end of file
- Constraint error: operation applied to invalid value
- Example: array index out of range
- Example: assigning a negative value to a natural number
- Handling exceptions: Any begin/end block can have an exception handler
- Example:
procedure demo_exceptions is
i: natural;
begin
get(i);
-- do something with i
exception
when data_error => put_line("found non-numeric input ");
when end_error => put_line("end of file reached");
when constraint_error => put_line("integer not a natural");
end demo_exceptions;
Can insert extra begin/end when needed
Begin/End Blocks
- Begin/end blocks can be added to allow for exception handling
with ada.text_io; use ada.text_io;
with ada.integer_text_io; use ada.integer_text_io;
procedure eofloop is
i: Integer;
begin
while not ada.text_io.end_of_file loop
begin
get(i);
put(i);
new_line;
exception
when data_error => put_line("You must enter a number ");
when constraint_error => put_line("You must enter a natural number");
end
end loop;
end eofloop;
Like java try/catch blocks
Can also use a declare with a begin/end block (see below)
Declare Blocks
- Variables can be declared anywhere - with a declare/begin/end block
- Example:
procedure declare_example is
size: natural;
begin
get(size);
declare
a: array(1 .. size) of Integer;
begin
for i in a'range loop
get(a(i));
end loop;
end;
end declare_example;
Declare Blocks and Unconstrained Arrays
- Unconstrained arrays allow definition of array types whose index range is
assigned later
- Example:
with ada.text_io; with ada.integer_text_io;
use ada.text_io; use ada.integer_text_io;
procedure declare_example2 is
type My_Array_Type is array(Natural range <>) of Integer;
size: natural;
begin
get(size);
declare
a: My_Array_Type(1 .. size);
begin
for i in a'range loop
get(a(i));
end loop;
for i in a'range loop
put(i);
end loop;
end;
end declare_example2;
Unconstrained Arrays as Parameters
- Array parameters must have a named type
- This won't compile:
procedure p(a: array(1..10) of integer) is
- Unconstrained arrays allow creation of procedures that work for any size array
- Example:
with ada.text_io; with ada.integer_text_io;
use ada.text_io; use ada.integer_text_io;
procedure declare_example2 is
type My_Array_Type is array(Natural range <>) of Integer;
-- Array a can be of any size
procedure putArray(a: My_Array_Type) is
begin
for i in a'range loop
put(i);
end loop;
end putArray;
a: My_Array_Type(1 .. 10);
begin
for i in a'range loop
get(a(i));
end loop;
putArray(a);
end declare_example2;
What is a Type
- A type consists of two sets:
- Set of values
- Set of operations (that operate on those values)
- Example: Integer values and operations
- Example: Character values and operations
- Integer operations: +, -, *, /, mod, rem, 'first, 'last, IO, :=
Subtypes
- Subset of the values of a type, with same operations
- Examples:
-
subtype Natural is Integer range 1 .. Integer'last
-
subtype Positive is ...
-
subtype Test_Scores is ...
- All integer operations (eg :=, +, -, 'first, 'last, integer_text_io.put) apply
- Constraint error if invalid value assigned:
declare
i: Integer;
n1, n2: Natural
begin
get(i);
n1 := i; -- fails if ...
get(n2); -- fails if ...
n1 := n1 - n2; -- fails if ...
i := n2; -- fails if ...
end;
Where do we see subtypes in Java?
Enumerated Types
- Many times we want to represent a set of values with names
- Examples: colors, day names
- Solution: Enumerated Type - allow definition of new literals
- Example:
procedure enum_demo is
type Color is (red, blue, green);
c: color := green;
begin
if c = blue then
-- do something
end if;
end enum_demo;