abstract data types and modules

77
Abstract Data Types Abstract Data Types and Modules and Modules

Upload: gyula

Post on 11-Jan-2016

31 views

Category:

Documents


0 download

DESCRIPTION

Abstract Data Types and Modules. Builtin Data Types. Builtin data types are designed to insulate the user of a language from the implementation of the data type, which is machine dependent - PowerPoint PPT Presentation

TRANSCRIPT

Page 1: Abstract Data Types and Modules

Abstract Data Types and Abstract Data Types and ModulesModules

Page 2: Abstract Data Types and Modules

2

Builtin Data Types

• Builtin data types are designed to insulate the user of a language from the implementation of the data type, which is machine dependent

• These data types can be manipulated by a set of builtin operations, whose implementation details are also hidden from the user. The semantics of these operations are completely specified in the language definition

Page 3: Abstract Data Types and Modules

3

User-Defined Data Types• User-defined data types are built up from d

ata structures created using the builtin data types and type constructors. Their data structures are visible to the user

• User-defined data types do not come with any operations other than the accessing operations of the data structures themselves. The functions defined to manipulate a data structure are not directly associated with its data type. The implementation details of these functions are also visible to the user

Page 4: Abstract Data Types and Modules

4

Abstract Data Types - Specification

• Abstract data types (ADT) provide a method for defining a data type and at the same time operations on that type. The operations should be directly associated with the type

• The definitions should not depend on any implementation details

• The definitions of the operations should include a specification of their semantics

Page 5: Abstract Data Types and Modules

5

Abstract Data Types - Implementation

• A method for collecting the implementation details of the type and its operations in one place

• A method for restricting access to these implementation details by programs that use the data type

Page 6: Abstract Data Types and Modules

6

Abstract Data Types• Modifiability is enhanced by interfaces that

are implementation independent, since changes can be made to an implementation without affecting its use by the rest of the program

• Security is enhanced by protecting the implementation details from arbitrary modification by other part of the program

• Reusability is enhanced by standard interfaces, since the code can be reused by different programs

Page 7: Abstract Data Types and Modules

7

Abstract Data Types

• Encapsulation refers to the collection of all definitions related to a data type in one location and restricting the use of the type to the operations defined at that location

• Information hiding refers to the separation of implementation from these definitions and the suppression of these details in the use of the data type

Page 8: Abstract Data Types and Modules

8

Algebraic Specification

• Syntactic specification includes the name of the type and the names of the operations, including a specification of their parameters and returned values. Function notation of mathematics is often used

• Semantics specification includes the properties that the operations must possess. In mathematics, the properties of functions are often described by equations or axioms

Page 9: Abstract Data Types and Modules

9

An Example – Complex Numbers

type complex imports realoperations: +: complex complex complex -: complex complex complex *: complex complex complex /: complex complex complex -: complex complex makecomplex: real real complex realpart: complex real imaginarypart: complex real

Page 10: Abstract Data Types and Modules

10

An Example – Complex Numbers

variables: x, y, z: complex; r, s: realaxioms: realpart(makecomplex(r, s)) = r imaginarypart(makecomplex(r, s)) = s realpart(x+y) = realpart(x) + realpart(y) imaginarypart(x+y) = imaginarypart(x) + imaginarypart(y) realpart(x-y) = realpart(x) - realpart(y) imaginarypart(x-y) = imaginarypart(x) - imaginarypart(y) …

Page 11: Abstract Data Types and Modules

11

An Example – Queue

type queue(element) imports booleanoperations: createq: queue enqueue: queue element queue dequeue: queue queue frontq: queue element emptyq: queue boolean

parameterized

constant

Page 12: Abstract Data Types and Modules

12

An Example – Queue

variables: q: queue; x: elementaxioms: emptyq(createq) = true emptyq(enqueue(q, x)) = false frontq(createq) = error frontq(enqueue(q, x)) = if emptyq(q) then x else frontq(q) dequeue(createq) = error dequeue(enqueue(q, x)) = if emptyq(q) then q else enqueue(dequeue(q), x)

error axiom

Page 13: Abstract Data Types and Modules

13

Constructors and Inspectors

• An operation that creates a new object of the data type being defined is called a constructor. Operations createq and enqueue are constructors

• An operation that retrieves previously constructed values is called an inspector. Operations dequeue, frontq, and emptyq are inspectors

Page 14: Abstract Data Types and Modules

14

Predicates and Selectors

• Inspectors that return Boolean values are called predicates. Inspector emptyq is a predicate

• Inspectors that return non-Boolean values are called selectors. Inspectors dequeue and frontq are selectors

Page 15: Abstract Data Types and Modules

15

Finding Axiom Set

• In general, one needs one axiom for each combination of an inspector with a constructor

emptyq(createq) emptyq(enqueue(q, x)) frontq(createq) frontq(enqueue(q, x)) dequeue(createq) = error dequeue(enqueue(q, x))

Page 16: Abstract Data Types and Modules

16

An Example – Stack

type stack(element) imports booleanoperations: createstk: stack push: stack element stack pop: stack stack top: stack element emptystk: stack boolean

Page 17: Abstract Data Types and Modules

17

An Example – Stack

variables: s: stack; x: elementaxioms: emptystk(createstk) = true emptystk(push(s, x)) = false top(createstk) = error top(push(s, x)) = x pop(createstk) = error pop(push(s, x)) = s

Page 18: Abstract Data Types and Modules

18

Abstract Data Type Mechanisms

• A mechanism must have a way of separating the specification and implementation of an ADT

• A mechanism must also guarantee that any code outside the ADT definition cannot use details of the implementation, but can operate on a value of the defined type only through the provided operations

Page 19: Abstract Data Types and Modules

19

ML Example - Queue

abstype ‘element Queue = Q of ‘element listwith val createq = Q [ ]; fun enqueue (Q lis, elem) = Q (lis @ [elem]); fun dequeue (Q lis) = Q (tl lis); fun frontq (Q lis) = hd lis; fun emptyq (Q [ ]) = true | emptyq (Q (h::t)) = false;end;

Page 20: Abstract Data Types and Modules

20

ML Example - Queue

type ‘a Queueval createq = - : ‘a Queuefun enqueue = fn : ‘a Queue * ‘a -> ‘a Queuefun dequeue = fn : ‘a Queue -> ‘a Queuefun frontq = fn : ‘a Queue -> ‘afun emptyq = fn : ‘a Queue -> bool

Page 21: Abstract Data Types and Modules

21

ML Example - Queue

- val q = enqueue(createq, 3);val q = - : int Queue- val q2 = enqueue(q, 4);val q2 = - : int Queue- frontq q2;val it = 3 : int- val q3 = dequeue q2;val q3 = - : int Queue- frontq q3;val it = 4 : int

Page 22: Abstract Data Types and Modules

22

ML Example – Complex Numbers

abstype Complex = C of real * realwith val makecomplex (x, y) = C (x, y); fun realpart (C (r, i)) = r; fun imaginarypart (C (r, i)) = i; fun +: (C (r1, i1), C (r2, i2)) = C (r1+r2, i1+i2); infix 6 +: ; (* other operations *)end;

Page 23: Abstract Data Types and Modules

23

ML Example – Complex Numbers

- val z = makecomplex(1.0, 2.0);val z = - : Complex- val w = makecomplex(2.0, ~1.0);val w = - : Complex- val x = z +: w;val x = - : Complex- realpart x;val it = 3.0 : real- imaginarypart x;val it = 1.0 : real

Page 24: Abstract Data Types and Modules

24

Modules

• An ADT mechanism may not fit a package of related functions that do not associate directly with a data type

• A mathematical function package consisting of the standard functions such as sine, cosine, exponential, and logarithmic functions is an example

• A module mechanism is used in such cases

Page 25: Abstract Data Types and Modules

25

Modules

• A module is a program unit with a public interface and a private implementation; all services that are available from a module are described in its public interface and are exported to other modules, and all services that are needed by a module must be imported from other modules

• As providers of services, modules can export any mix of data types, procedures, variables, and constants

Page 26: Abstract Data Types and Modules

26

Modules• Because modules have explicit (public)

interfaces and separate (private) implementations, they are ideal mechanisms to provide separate compilation and library facilities within a software development environment

• The interface for each module is kept in textual form and is needed at the compile time, while the implementation may only be provided as object code and is only needed at the link time

Page 27: Abstract Data Types and Modules

27

Modules

• Modules are an essential tool in program decomposition and complexity control

• Modules provide additional scope features that make the task of name control more manageable

• Module mechanism can document the dependencies of a module on other modules by requiring explicit import lists whenever code from other modules is used

Page 28: Abstract Data Types and Modules

28

Separate Compilation in C

queue.h(interface)

q_user.h(client)

queue.c(implementation)

Page 29: Abstract Data Types and Modules

29

queue.h

#ifndef QUEUE_H#define QUEUE_H

struct Queuerep;typedef struct Queuerep * Queue;

Queue createq(void);Queue enqueue(Queue q, void* elem);void* frontq(Queue q);Queue dequeue(Queue q);int emptyq(Queue q);

#endif

Page 30: Abstract Data Types and Modules

30

queue.c#include "queue.h"#include <stdlib.h>

struct Queuerep { void* data; Queue next; };

Queue createq(void) { return 0; }

Queue enqueue(Queue q, void* elem){ Queue temp = malloc(sizeof(struct Queuerep)); temp->data = elem; if (q) { temp->next = q->next; q->next = temp; q = temp; } else { q = temp; q->next = temp; } return q;}

Page 31: Abstract Data Types and Modules

31

queue.c

void* frontq(Queue q) { return q->next->data; }

Queue dequeue(Queue q){ Queue temp; if (q == q->next) { temp = q; q = 0; } else { temp = q->next; q->next = q->next->next; } free(temp); return q;}

int emptyq(Queue q) { return q == 0; }

Page 32: Abstract Data Types and Modules

32

q_user.c#include <stdlib.h>#include <stdio.h>#include "queue.h"

main(){ int *x = malloc(sizeof(int)); int *y = malloc(sizeof(int)); int *z; Queue q = createq(); *x = 2; *y = 3; q = enqueue(q,x); q = enqueue(q,y); z = (int*) frontq(q); printf("%d\n",*z); /* prints 2 */ q = dequeue(q); z = (int*) frontq(q); printf("%d\n",*z); /* prints 3 */ return 0;}

User can directly copy declarations in queue.h here

User can directly copy the definition of Queuerep here

Page 33: Abstract Data Types and Modules

33

C++ Namespaces - queue.h#ifndef QUEUE_H#define QUEUE_H

namespace MyQueue{ struct Queuerep; typedef Queuerep * Queue; Queue createq(); Queue enqueue(Queue q, void* elem); void* frontq(Queue q); Queue dequeue(Queue q); bool emptyq(Queue q);}

#endif

Page 34: Abstract Data Types and Modules

34

queue.cpp

namespace MyQueue {

struct Queuerep { void* data; Queue next; };

Queue createq(void) { return 0; }

Queue enqueue(Queue q, void* elem){ Queue temp = new Queuerep; temp->data = elem; if (q) { temp->next = q->next; q->next = temp; q = temp; } else { q = temp; q->next = temp; } return q;}

Page 35: Abstract Data Types and Modules

35

queue.cpp

void* frontq(Queue q) { return q->next->data; }

Queue dequeue(Queue q){ Queue temp; if (q == q->next) { temp = q; q = 0; } else { temp = q->next; q->next = q->next->next; } delete temp; return q;}

bool emptyq(Queue q) { return q == 0; }

} // end namespace MyQueue

Page 36: Abstract Data Types and Modules

36

q_user.cpp

#include <iostream>#include "queue2.h"using std::endl;using namespace MyQueue;main(){ int *x = new int; int *y = new int; int *z; Queue q = MyQueue::createq(); *x = 2; *y = 3; q = enqueue(q,x); q = enqueue(q,y); z = (int*) frontq(q); // explicit qualification needed for cout std::cout << *z << endl; // prints 2 q = dequeue(q); z = (int*) frontq(q); std::cout << *z << endl; // prints 3}

Page 37: Abstract Data Types and Modules

37

Java Packages• Packages are constructed as groups of rel

ated classes• Each separately compiled file is allowed to

have only one public class, and this class can be placed in a package by writing a package declaration at the beginning of the file

package myqueue;• Names can be dereferenced using

import myqueue.Queue;import myqueue.*;

Page 38: Abstract Data Types and Modules

38

Ada Packages

• An Ada package is divided into a package specification and a package body

• A package specification is the public interface to the package

Page 39: Abstract Data Types and Modules

39

An Example – Complex Numbers

package ComplexNumbers istype Complex is private;function "+"(x,y: in Complex) return Complex;function "-"(x,y: in Complex) return Complex;function "*"(x,y: in Complex) return Complex;function "/"(x,y: in Complex) return Complex;function "-"(z: in Complex) return Complex;function makeComplex (x,y: in Float) return Complex;function realPart (z: in Complex) return Float;function imaginaryPart (z: in Complex) return Float;private type ComplexRecord; type Complex is access ComplexRecord;end ComplexNumbers;

Page 40: Abstract Data Types and Modules

40

An Example – Complex Numbers

package body ComplexNumbers is

type ComplexRecord is record re, im: Float;end record;

function "+"(x,y: in Complex) return Complex is t: Complex;begin t := new ComplexRecord; t.re := x.re + y.re; t.im := x.im + y.im; return t;end "+";-- more operations here

Page 41: Abstract Data Types and Modules

41

An Example – Complex Numbers

function makeComplex (x,y: in Float) return Complex isbegin return new ComplexRecord'(re => x , im => y);end makeComplex;

function realPart (z: in Complex) return Float isbegin return z.re;end realPart;

function imaginaryPart (z: in Complex) return Float isbegin return z.im;end imaginaryPart;

end ComplexNumbers;

Page 42: Abstract Data Types and Modules

42

An Example – Complex Numbers

with ComplexNumbers;use ComplexNumbers;

procedure ComplexUser is z,w: ComplexNumbers.Complex;

begin z := ComplexNumbers.makeComplex(1.0,-1.0); w := ComplexNumbers."+"(z,z); w := z + z;end ComplexUser;

Page 43: Abstract Data Types and Modules

43

An Example – Queues

generic type T is private;package Queues is type Queue is private; function createq return Queue; function enqueue(q:Queue;elem:T) return Queue; function frontq(q:Queue) return T; function dequeue(q:Queue) return Queue; function emptyq(q:Queue) return Boolean;private type Queuerep; type Queue is access Queuerep;end Queues;

Page 44: Abstract Data Types and Modules

44

An Example – Queuespackage body Queues is type Queuerep is record data: T; next: Queue; end record;

function createq return Queue is begin return null; end createq;

function enqueue(q:Queue;elem:T) return Queue is temp: Queue; begin temp := new Queuerep; temp.data := elem; if (q /= null) then temp.next := q.next; q.next := temp; else temp.next := temp; end if; return temp; end enqueue;

Page 45: Abstract Data Types and Modules

45

An Example – Queues

function frontq(q:Queue) return T is begin return q.next.data; end frontq;

function dequeue(q:Queue) return Queue is begin if q = q.next then return null; else q.next := q.next.next; return q.next; end if; end dequeue;

function emptyq(q:Queue) return Boolean is begin return q = null; end emptyq;

end Queues;

Page 46: Abstract Data Types and Modules

46

An Example – Queueswith Queues;procedure Quser ispackage IntQueues is new Queues(Integer);use IntQueues;package FloatQueues is new Queues(Float);use FloatQueues;fq: FloatQueues.Queue := createq;iq: IntQueues.Queue := createq;begin fq := enqueue(fq,3.1); fq := enqueue(fq,2.3); iq := enqueue(iq,3); iq := enqueue(iq,2); put(frontq(iq)); new_line; fq := dequeue(fq); put(frontq(fq)); new_line;end Quser;

Page 47: Abstract Data Types and Modules

47

Modules in ML

• ML module facility consists of three mechanisms: signatures, structures, and functors

• A signature is an interface definition

• A structure is an implementation of a signature

• Functors are functions from structures to structures

Page 48: Abstract Data Types and Modules

48

An Example - Queue

signature QUEUE = sig type 'a Queue val createq: 'a Queue val enqueue: 'a Queue * 'a -> 'a Queue val frontq: 'a Queue -> 'a val dequeue: 'a Queue -> 'a Queue val emptyq: 'a Queue -> bool end;

Page 49: Abstract Data Types and Modules

49

An Example - Queue

structure Queue1: QUEUE = struct datatype 'a Queue = Q of 'a list val createq = Q [ ]; fun enqueue(Q lis, elem) = Q (lis @ [elem]); fun frontq (Q lis) = hd lis; fun dequeue (Q lis) = Q (tl lis); fun emptyq (Q [ ]) = true | emptyq (Q (h::t)) = false; end;

Page 50: Abstract Data Types and Modules

50

An Example - Queue

- val q = Queue1.enqueue(Queue1.createq,3);val q = Q [3] : int Queue1.Queue- Queue1.frontq q;val it = 3 : int- val q1 = Queue1.dequeue q;val q1 = Q [ ] : int Queue1.Queue- Queue1.emptyq q1;val it = true : bool

Page 51: Abstract Data Types and Modules

51

An Example - Queue

- open Queue1;opening Queue1 datatype 'a Queue = Q of ‘a list val createq: 'a Queue val enqueue: 'a Queue * 'a -> 'a Queue val frontq: 'a Queue -> 'a val dequeue: 'a Queue -> 'a Queue val emptyq: 'a Queue -> bool

Page 52: Abstract Data Types and Modules

52

An Example - Queue

- val q = enqueue(createq,3);val q = Q [3] : int Queue- frontq q;val it = 3 : int- val q1 = dequeue q;val q1 = Q [ ] : int Queue- emptyq q1;val it = true : bool

Page 53: Abstract Data Types and Modules

53

An Example – Queue2

structure Queue2: QUEUE = struct datatype 'a Queue = Createq | Enqueue of 'a Queue * 'a ; val createq = Createq; fun enqueue(q,elem) = Enqueue (q,elem); fun frontq (Enqueue(Createq,elem)) = elem | frontq (Enqueue(q,elem)) = frontq q; fun dequeue (Enqueue(Createq,elem)) = Createq | dequeue (Enqueue(q,elem)) = Enqueue(dequeue q, elem); fun emptyq Createq = true | emptyq _ = false; end;

Page 54: Abstract Data Types and Modules

54

An Example – Queue2

- open Queue2;opening Queue2 datatype 'a Queue = Createq | Enqueue of 'a Queue * 'a ; val createq: 'a Queue val enqueue: 'a Queue * 'a -> 'a Queue val frontq: 'a Queue -> 'a val dequeue: 'a Queue -> 'a Queue val emptyq: 'a Queue -> bool

Page 55: Abstract Data Types and Modules

55

An Example – Queue2

- val q = enqueue(createq,3);val q = Enqueue (Createq, 3) : int Queue- frontq q;val it = 3 : int- val q1 = dequeue q;val q1 = Createq : int Queue- emptyq q1;val it = true : bool

Page 56: Abstract Data Types and Modules

56

Problems• Modules are not types

• Modules are static entities

• Modules that export types do not adequately control operations on variables of such types

• Modules do not always adequately represent how they depend on imported types

• Modules include no specification of the semantics of the provided operations

Page 57: Abstract Data Types and Modules

57

Modules Are Not Types• ML contains both an abstract data type me

chanism and a module mechanism to emphasize this distinction

• An abstype is a type, but the implementation of an abstype cannot be separated from its specification, and clients implicitly depend on the implementation

• The module mechanism is more general, and it allows the clean separation of specification from implementation, but a type must be exported

Page 58: Abstract Data Types and Modules

58

ML Example - Queue

abstype ‘element Queue = Q of ‘element listwith val createq = Q [ ]; fun enqueue (Q lis, elem) = Q (lis @ [elem]); fun dequeue (Q lis) = Q (tl lis); fun frontq (Q lis) = hd lis; fun emptyq (Q [ ]) = true | emptyq (Q (h::t)) = false;end;

Page 59: Abstract Data Types and Modules

59

ML Example - Queue

type ‘a Queueval createq = - : ‘a Queuefun enqueue = fn : ‘a Queue * ‘a -> ‘a Queuefun dequeue = fn : ‘a Queue -> ‘a Queuefun frontq = fn : ‘a Queue -> ‘afun emptyq = fn : ‘a Queue -> bool

Page 60: Abstract Data Types and Modules

60

Modules Are Static Entities

• A possibility for implementing an abstract data type is to simply not reveal a type at all, thus avoiding all possibility of clients depending in any way on implementation details, as well as preventing clients from any misuse of a type

Page 61: Abstract Data Types and Modules

61

Ada Example - Queue

generic type T is private;package Queues is procedure enqueue(elem:T); function frontq return T; procedure dequeue; function emptyq return Boolean;end Queues;

Page 62: Abstract Data Types and Modules

62

Ada Example - Queuepackage body Queues is type Queuerep; type Queue is access Queuerep; type Queuerep is record data: T; next: Queue; end record; q: Queue;

procedure enqueue(elem:T) is temp: Queue; begin temp := new Queuerep; temp.data := elem; if (q /= null) then temp.next := q.next; q.next := temp; else temp.next := temp; end if; q := temp; end enqueue;

Page 63: Abstract Data Types and Modules

63

Ada Example - Queue function frontq return T is begin return q.next.data; end frontq;

procedure dequeue is begin if q = q.next then q := null; else q.next := q.next.next; q := q.next; end if; end dequeue;

function return Boolean is begin return q = null; end emptyq;

begin q := null;end Queues;

Page 64: Abstract Data Types and Modules

64

Ada Example - Queue

with Queues;procedure Quser ispackage Queue1 is new Queues(Integer);package Queue2 is new Queues(Integer);begin Queue1.enqueue(3); Queue1.enqueue(4); Queue2.enqueue(1); Queue2.enqueue(2); put(Queue1.frontq); new_line; Queue2.dequeue; put(Queue2.frontq); new_line;end Quser;

Page 65: Abstract Data Types and Modules

65

Modules Not Adequately Control Operations

• Variables of abstract data types are pointers that had to be allocated and initialized by calling procedures like createq and makeComplex. But the module cannot guarantee that these procedures are called before the variables are used

• Since variables are pointers, copies can be made and deallocation performed outside the control of the module

Page 66: Abstract Data Types and Modules

66

Ada Example

z := makeComplex(1.0, 0.0);x := makeComplex(-1.0, 0.0);x := z;

x := makeComplex(1.0, 0.0);y := makeComplex(1.0, 0.0);(* now a test of x = y return false *)

Page 67: Abstract Data Types and Modules

67

Ada Examplepackage ComplexNumbers istype Complex is limited private;function "+"(x,y: in Complex) return Complex; …function makeComplex (x,y: in Float) return Complex;function realPart (z: in Complex) return Float;function imaginaryPart (z: in Complex) return Float;function equal(x, y: in Complex) return Boolean;procedure assign(x: out Complex; y: in Complex);private type ComplexRec; type Complex is access ComplexRec;end ComplexNumbers;

Page 68: Abstract Data Types and Modules

68

ML Example

signature QUEUE = sig eqtype ’’a Queue val createq: ’’a Queue val enqueue: ’’a Queue * ’’a -> ’’a Queue val frontq: ’’a Queue -> ’’a val dequeue: ’’a Queue -> ’’a Queue val emptyq: ’’a Queue -> bool end;

Page 69: Abstract Data Types and Modules

69

Modules Not Adequately Represent How They Depend on Imported Types

• Aside from assignment and equality testing, modules often depend on the existence of certain operations on type parameters and may also call functions whose existence is not made explicit in the module specification

Page 70: Abstract Data Types and Modules

70

C++ Example

template <typename T>T min(T x, T y);

template <typename T>T min(T x, T y){ return x < y ? x : y }

Page 71: Abstract Data Types and Modules

71

Ada Example

generic type Element is private; with function lessThan (x, y: Element)

return Boolean;package OrderedList is …end Queues;

package IntOrderedList is new OrderedList(Integer, “<“);

Page 72: Abstract Data Types and Modules

72

ML Examplesignature ORDER = sig type Elem val lt: Elem * Elem -> bool end;

signature ORDERED_LIST = sig type Elem type OList val create: OList val insert: OList * Elem -> OList val lookup: OList * Elem -> bool end;

Page 73: Abstract Data Types and Modules

73

ML Examplefunctor OListFUN (structure Order: ORDER): ORDERED_LIST = struct type Elem = Order.Elem; type OList = Order.Elem list; val create = []; fun insert ([], x) = [x] | insert (h::t, x) = if Order.lt(x,h) then x::h::t else h:: insert (t, x); fun lookup ([], x) = false | lookup (h::t, x) = if Order.lt(x,h) then false else if Order.lt(h,x) then lookup (t,x) else true; end;

Page 74: Abstract Data Types and Modules

74

ML Example

structure IntOrder: ORDER = struct type Elem = int; val lt = (op <); end;

structure IntOList = OListFUN(structure Order = IntOrder);

Page 75: Abstract Data Types and Modules

75

ML Example

- open IntOList;opening IntOList type Elem = IntOrder.Elem type OList = IntOrder.Elem list val create: OList val insert: OList * Elem -> OList val lookup: OList * Elem -> bool

- val ol = insert(create,2);val ol = [2] : OList- val ol2 = insert(ol,3);val ol2 = [2, 3] : OList- lookup (ol2,3);val it = true : bool- lookup (ol,3);val it = false : bool

Page 76: Abstract Data Types and Modules

76

Modules Include No Specification of the Semantics of Operations

• One example of a language that does allow the specification of semantics is Eiffel, an object-oriented language

Page 77: Abstract Data Types and Modules

77

Eiffel Example

frontq(enqueue(q, x)) = if emptyq(q) then x else frontq(q) emptyq(enqueue(q, x)) = false

enqueue (x: element) isrequire not fullensure if old empty then front = x else front = old front; not emptyend;

precondition

postcondition