Program Design

Web Server Modules and Abstraction

CSCI 334 Input Queue File Access Output Buffer Stephen Freund

Logging Caching

Software Engineering Techniques Data Refinement Example  Top Down Bank Account Transactions – start with main tasks – iteratively refine  Bottom Up Deposit Withdraw Print Statement – define concepts – combine  Prototyping Print transaction – define "approximation" of whole system history – add functionality, extend data rep

Example: Stack Example: power Function  Interface  Specification  Interface type Stack – Pre/Post conditions – "behaves like a stack..." – fun power : int * int -> int val empty : Stack; fun push : int * Stack -> Stack fun pop : Stack -> int * Stack  Specification – power(m,n) returns the value mn  Implementation type Stack = int list;

 Implementation val empty = nil;

– fun power(m,n) = fun push(n, ns) = n::ns; if n > 0 then m * power(m,n-1) else 1; fun pop(nil) = (0, empty) | pop(n::ns) = (n, ns);

1 abstype Stack Using an Abstract Type abstype Stack = - abstype Stack = StackRep of int list ... with type Stack; val empty = StackRep(nil); empty = - : Stack fun push(n, StackRep(ns)) = StackRep(n::ns); push = fn: int * Stack -> Stack fun pop(StackRep(nil)) = (0,empty) pop = fn: Stack -> int * Stack | pop(StackRep(n::ns)) = (n,StackRep(ns)); - val st = push(3, empty); end; val st = - : Stack - val (top,_) = pop(st); val it = 3 : int

Stack abstype (2nd version) Expr abstype abstype Stack = top index & array - abstype Expr = StackRep of int * int array VarX | Times of Expr * Expr with with val empty = (0, Array.array(100, 0)); fun buildX() = VarX; fun buildTimes(e1,e2) = Times(e1,e2); fun push(n, StackRep(top, a)) = ( fun exprToString ... = ...; Array.update(a,top,n); fun eval ... = ...; StackRep(top + 1, a) end; ) - val e = buildTimes(buildX(), buildX()); fun pop(StackRep(top, a)) = val e = - : Expr (Array.sub(a,(top - 1)), StackRep(top - 1, a)); - exprToString e; end; val it = "x * x": string

Module File System Module  Interface INTERFACE FileSystem; CONST max_files : INTEGER = 10; – set of name and type declarations TYPE  Byte = BITS 8 FOR [0 .. 255]; Spec File = RECORD (* name, permissions, etc. *) END; – same as before... END; PROCEDURE open(name : String): File;  Implementation PROCEDURE read(File f; VAR b: ARRAY OF Byte); – code/decls to define names PROCEDURE close(File f); END FileSystem.  Examples: IMPLEMENTATION FileSystem; – modules in Modula TYPE TempFile = ...; – Ada packages PROCEDURE open(name : String): File BEGIN ... END – ML structures ... – Java packages

2 Generic Abstractions  Parameterize component by types – Ada generics, ML functors, ++ STL library  Example class Stack { private Vector elems; public boolean empty() { ... } public void push(T elem) { ... } public T pop() { ... } }

Stack stringStack; Stack intStack;

Interview with Stepanov Example (in Java Syntax...)  Question: What is the origin of STL? public Iterator iterator(Vector v) { ... }  Answer: In 1976, still back in the USSR, I got a public Iterator sort(Iterator data, Comparator comp) { ... } very serious case of food poisoning from eating raw fish. While in the hospital, in the state of public Iterator merge(Iterator a1, Iterator a2, Comparator comp) { ... } delirium, I suddenly realized that the ability to add numbers in parallel depends on the fact that addition is associative. Vector strings; OrderedVector orderedStrings; Comparator stringComp; In other words, I realized that ... algorithms are Iterator iter = merge(sort(strings, stringComp), defined on algebraic structures. iterator(orderedStrings), stringComp);

C++ STL Efficiency

N = 50,000 N = 500,000

C 1.42 18.16 (qsort) C++ 0.28 3.84 (arrays) C++ 0.27 3.80 (STL vector)

3