UMBC CMSC 331
History
• Early History : The first programmers
History of • The 1940s: Von Neumann and Zuse
• The 1950s: The First Programming Language
Programming • The 1960s: An Explosion in Programming
languages
• The 1970s: Simplicity, Abstraction, Study
Languages • The 1980s: Consolidation and New Directions
• The 1990s: Internet and web
• The 2000s: ? scripting, parallel, Web 2.0, …?
CMSC 331. Some material © 1998 by Addison Wesley Longman, Inc. 1 CMSC 331. Some material © 1998 by Addison Wesley Longman, Inc. 2
Early History: First Programmers Konrad Zuse and Plankalkul
• Jacquard loom of early 1800s Konrad Zuse began work on
Plankalkul (plan calculus), the first
– Translated card patterns into cloth designs algorithmic programming
language, with an aim of creating the
• Charles Babbage’s analytical engine theoretical preconditions for the
(1830s & 40s) formulation of problems of a general
nature.
Programs were cards with data and operations.
Steam powered! Seven years earlier, Zuse had devel-
oped and built the world's first
• Ada Lovelace – first programmer binary digital computer, the Z1. He
completed the first fully functional
“The engine can arrange and combine its program-controlled electromechan-
numerical quantities exactly as if they ical digital computer, the Z3, in
were letters or any other general 1941.
symbols; And in fact might bring out its Only the Z4 – the most sophisticated
results in algebraic notation, were of his creations -- survived World
provision made.” War II.
CMSC 331. Some material © 1998 by Addison Wesley Longman, Inc. 3 CMSC 331. Some material © 1998 by Addison Wesley Longman, Inc. 4
CMSC 331. Some material © 1998 by Addison Wesley Longman, Inc. 1
UMBC CMSC 331
The 1940s: Von Neumann and Zuse Plankalkul notation
• Konrad Zuse (Plankalkul)
– in Germany - in isolation because of the war
– defined Plankalkul (program calculus) circa 1945 but A(7) := 5 * B(6)
never implemented it.
– Wrote algorithms in the language, including a program to
play chess.
| 5 * B => A
– His work finally published in 1972.
V | 6 7 (subscripts)
– Included some advanced data type features such as
» Floating point, used twos complement and hidden bits
S | 1.n 1.n (data types)
» Arrays
» records (that could be nested)
CMSC 331. Some material © 1998 by Addison Wesley Longman, Inc. 5 CMSC 331. Some material © 1998 by Addison Wesley Longman, Inc. 6
The 1940s: Von Neumann and Zuse Machine Codes (40’s)
Von Neumann
led a team that • Initial computers were programmed in raw
built computers machine codes.
with stored • These were entirely numeric.
programs and a • What was wrong with using machine code?
central pro- Everything!
cessor • Poor readability
ENIAC was • Poor modifiability
programmed • Expression coding was tedious
with patch • Inherit deficiencies of hardware, e.g., no
cords indexing or floating point numbers
Von Neuman with ENIAC
CMSC 331. Some material © 1998 by Addison Wesley Longman, Inc. 7 CMSC 331. Some material © 1998 by Addison Wesley Longman, Inc. 8
CMSC 331. Some material © 1998 by Addison Wesley Longman, Inc. 2
UMBC CMSC 331
The 1950s: The First Pseudocodes (1949)
Programming Language
• Short Code or SHORTCODE - John Mauchly, 1949.
• Pseudocodes: interpreters for assembly language • Pseudocode interpreter for math problems, on Eckert
• Fortran: the first higher level programming and Mauchly’s BINAC and later on UNIVAC I and II.
language • Possibly the first attempt at a higher level language.
• COBOL: he first business oriented language • Expressions were coded, left to right, e.g.:
X0 = sqrt(abs(Y0))
• Algol: one of the most influential programming 00 X0 03 20 06 Y0
languages ever designed • Some operations:
• LISP: the first language outside the von Neumann 01 – 06 abs 1n (n+2)nd power
02 ) 07 + 2n (n+2)nd root
model 03 = 08 pause 4n if <= n
• APL: A Programming Language 04 / 09 ( 58 print & tab
CMSC 331. Some material © 1998 by Addison Wesley Longman, Inc. 9 CMSC 331. Some material © 1998 by Addison Wesley Longman, Inc. 10
More Pseudocodes Fortran (1954-57)
Speedcoding; 1953-4 • FORmula TRANslator
• A pseudocode interpreter for math on IBM701, IBM650.
• Developed by John Backus
• Developed at IBM under the
• Pseudo ops for arithmetic and math functions
guidance of John Backus
primarily for scientific,
• Conditional and unconditional branching
computational programming
• Autoincrement registers for array access
• Slow but still dominated by slowness of s/w math • Dramatically changed forever the
• Interpreter left only 700 words left for user program way computers used
Laning and Zierler System - 1953 • Has continued to evolve, adding new features & concepts.
• Implemented on the MIT Whirlwind computer – FORTRAN II, FORTRAN IV, FORTRAN66, FORTRAN77, FORTRAN90
• First "algebraic" compiler system
• Subscripted variables, function calls, expression translation • Always among the most efficient compilers, producing fast
• Never ported to any other machine code
CMSC 331. Some material © 1998 by Addison Wesley Longman, Inc. 11 CMSC 331. Some material © 1998 by Addison Wesley Longman, Inc. 12
CMSC 331. Some material © 1998 by Addison Wesley Longman, Inc. 3
UMBC CMSC 331
Fortran 77 Examples Fortran 0 and 1
FORTRAN 0 – 1954 (not implemented)
C Hello World in Fortran 77
C (lines must be 6 characters indented)
FORTRAN I - 1957
PROGRAM HELLOW
Designed for the new IBM 704, which had index registers and
WRITE(UNIT=*, FMT=*) 'Hello World'
floating point hardware
END
Environment of development:
Computers were small and unreliable
Applications were scientific
PROGRAM SQUARE
No programming methodology or tools
DO 15,I = 1,10
Machine efficiency was most important
WRITE(*, *) I*I
Impact of environment on design
15 CONTINUE
• No need for dynamic storage
• Need good array handling and counting loops
END
• No string handling, decimal arithmetic, or powerful input/
output (commercial stuff)
CMSC 331. Some material © 1998 by Addison Wesley Longman, Inc. 13 CMSC 331. Some material © 1998 by Addison Wesley Longman, Inc. 14
Fortran I Features Fortran II, IV and 77
• Names could have up to six characters
• Post-test counting loop (DO I=1, 100)
FORTRAN II - 1958
• Formatted I/O • Independent compilation
• User-defined subprograms • Fix the bugs
• Three-way selection statement (arithmetic IF with GOTO)
IF (ICOUNT-1) 100 200 300 FORTRAN IV - 1960-62
• Implicit data typing statements • Explicit type declarations
variables beginning with i, j, k, l, m or n were integers, • Logical selection statement
all else floating point • Subprogram names could be parameters
• No separate compilation • ANSI standard in 1966
• Programs larger than 400 lines rarely compiled correctly,
mainly due to poor reliability of the 704 FORTRAN 77 - 1978
• Character string handling
• Code was very fast
• Logical loop control statement
• Quickly became widely used • IF-THEN-ELSE statement
CMSC 331. Some material © 1998 by Addison Wesley Longman, Inc. 15 CMSC 331. Some material © 1998 by Addison Wesley Longman, Inc. 16
CMSC 331. Some material © 1998 by Addison Wesley Longman, Inc. 4
UMBC CMSC 331
Fortran 90 (1990) COBOL
Added many features of more modern • COmmon Business Oriented Language
programming languages, including
• Principal mentor: (Rear Admiral Dr.)
• Pointers Grace Murray Hopper (1906-1992)
• Recursion • Based on FLOW-MATIC which had such
features as:
• CASE statement • Names up to 12 characters, with
• Parameter type checking embedded hyphens
• A collection of array operations, DOTPRODUCT, • English names for arithmetic operators
MATMUL, TRANSPOSE, etc • Data and code were completely separate
• dynamic allocations and deallocation of arrays • Verbs were first word in every statement
• CODASYL committee (Conference on Data Systems
• a form of records (called derived types) Languages) developed a programming language by the
• Module facility (similar Ada’s package) name of COBOL
CMSC 331. Some material © 1998 by Addison Wesley Longman, Inc. 17 CMSC 331. Some material © 1998 by Addison Wesley Longman, Inc. 18
COBOL COBOL
First CODASYL Design Meeting - May 1959
Design goals:
• Must look like simple English
• Must be easy to use, even if that means it will be less
powerful
• Must broaden the base of computer users
• Must not be biased by current compiler problems
Design committee were all from computer manufacturers
and DoD branches
Design Problems: arithmetic expressions? subscripts?
Fights among manufacturers
CMSC 331. Some material © 1998 by Addison Wesley Longman, Inc. 19 CMSC 331. Some material © 1998 by Addison Wesley Longman, Inc. 20
CMSC 331. Some material © 1998 by Addison Wesley Longman, Inc. 5
UMBC CMSC 331
IDENTIFICATION DIVISION.
COBOL PROGRAM-ID. HelloWorld.
AUTHOR. Fabritius.
Cobol Example
Contributions:
- First macro facility in a high-level language ENVIRONMENT DIVISION.
- Hierarchical data structures (records) CONFIGURATION SECTION.
- Nested selection statements INPUT-OUTPUT SECTION.
- Long names (up to 30 characters), with hyphens
- Data Division DATA DIVISION.
Comments: FILE SECTION.
• First language required by DoD; would have WORKING-STORAGE SECTION.
failed without DoD LINKAGE SECTION.
• Still the most widely used business applications
language PROCEDURE DIVISION.
DISPLAY "Hello World".
STOP RUN.
CMSC 331. Some material © 1998 by Addison Wesley Longman, Inc. 21 CMSC 331. Some material © 1998 by Addison Wesley Longman, Inc. 22
BASIC (1964) BASIC Examples
• Beginner's All purpose Symbolic Instruction Code
• Designed by Kemeny & Kurtz at Dartmouth for the GE
225 with the goals: PRINT "Hello World"
• Easy to learn and use for non-science students and as
a path to Fortran and Algol
• Must be “pleasant and friendly”
• Fast turnaround for homework
• Free and private access FOR I=1 TO 10
• User time is more important than computer time PRINT I*I;
• Well suited for implementation on first PCs (e.g., Gates NEXT I
and Allen’s 4K Basic interpreter for the MITS Altair
personal computer (circa 1975)
• Current popular dialects: Visual BASIC
CMSC 331. Some material © 1998 by Addison Wesley Longman, Inc. 23 CMSC 331. Some material © 1998 by Addison Wesley Longman, Inc. 24
CMSC 331. Some material © 1998 by Addison Wesley Longman, Inc. 6
UMBC CMSC 331
LISP (1959) LISP Examples
• LISt Processing language (Designed at MIT by McCarthy)
(print "Hello World")
• AI research needed a language that:
• Process data in lists (rather than arrays) (defun fact (n)
• Symbolic computation (rather than numeric) (if (zerop n)
• One universal, recursive data type: the s-expression 1
• An s-expression is either an atom or a list of zero or more (* n (fact (1- n)))))
s-expressions
• Syntax is based on the lambda calculus (format t “factorial of 6 is: ~A~%" (fact 6))
• Pioneered functional programming
• No need for variables or assignment (defun print-squares (upto)
• Control via recursion and conditional expressions (loop for i from 1 to upto
do (format t "~A^2 = ~A~%" i (* i i))))
• Status
• Still the dominant language for AI
• COMMON LISP and Scheme are contemporary dialects
• ML, Miranda, and Haskell are related languages
CMSC 331. Some material © 1998 by Addison Wesley Longman, Inc. 25 CMSC 331. Some material © 1998 by Addison Wesley Longman, Inc. 26
Algol Algol 60 Examples
Environment of development:
1. FORTRAN had (barely) arrived for IBM 70x 'begin' --Hello World in Algol 60
2. Many other languages were being developed, all for outstring(2, 'Hello World');
specific machines 'end'
3. No portable language; all were machine dependent
4. No universal language for communicating 'begin' 'comment' Squares from 1 to 10
algorithms 'integer' I;
'for' i := 1 'step' 1 'until' 10 'do'
ACM and GAMM met for four days for design
'begin'
- Goals of the language:
1. Close to mathematical notation outinteger(2,i*i);
2. Good for describing algorithms 'end' --for
3. Must be translatable to machine code 'end' --program
CMSC 331. Some material © 1998 by Addison Wesley Longman, Inc. 27 CMSC 331. Some material © 1998 by Addison Wesley Longman, Inc. 28
CMSC 331. Some material © 1998 by Addison Wesley Longman, Inc. 7
UMBC CMSC 331
Algol 58 Features Algol 60
• Concept of type was formalized Modified ALGOL 58 at 6-day meeting in Paris adding such
• Names could have any length new features as:
• Arrays could have any number of subscripts • Block structure (local scope)
• Parameters were separated by mode (in & out) • Two parameter passing methods
• Subscripts were placed in brackets • Subprogram recursion
• Compound statements (begin ... end) • Stack-dynamic arrays
• Semicolon as a statement separator • Still no i/o and no string handling
• Assignment operator was := Successes:
• if had an else-if clause • It was the standard way to publish algorithms for over
Comments: 20 years
• Not meant to be implemented, but variations of it were • All subsequent imperative languages are based on it
(MAD, JOVIAL) • First machine-independent language
• Although IBM was initially enthusiastic, all support was • First language whose syntax was formally defined
dropped by mid-1959 (BNF)
CMSC 331. Some material © 1998 by Addison Wesley Longman, Inc. 29 CMSC 331. Some material © 1998 by Addison Wesley Longman, Inc. 30
Algol 60 (1960) APL
Failure: Never widely used, especially in U.S., • designed by K.Iverson at Harvard in late
mostly because 1950’s
1. No i/o and the character set made • A Programming Language
programs nonportable • A language for programming mathematical
2. Too flexible--hard to implement computations
– especially those using matrices
3. Entrenchment of FORTRAN
• Functional style and many whole array
4. Formal syntax description operations
5. Lack of support of IBM • Drawback is requirement of special keyboard
CMSC 331. Some material © 1998 by Addison Wesley Longman, Inc. 31 CMSC 331. Some material © 1998 by Addison Wesley Longman, Inc. 32
CMSC 331. Some material © 1998 by Addison Wesley Longman, Inc. 8
UMBC CMSC 331
The 1960s: An Explosion in
APL Examples
Programming Languages
• APL required a special character set, usually • The development of hundreds of programming
provided by an IBM Selectric type ball languages
• Here is an example that prints the squares of • PL/1 designed in 1963-4
the first 10 integers – supposed to be all purpose
– combined features of FORTRAN, COBOL and Algol60 and more!
• The iota operator takes a number and returns a – translators were slow, huge and unreliable
vector from 1 to than number – some say it was ahead of its time......
• Algol68
• SNOBOL
• Simula
• BASIC
CMSC 331. Some material © 1998 by Addison Wesley Longman, Inc. 33 CMSC 331. Some material © 1998 by Addison Wesley Longman, Inc. 34
PL/I PL/I
• Computing situation in 1964 (IBM's point of view) PL/I contributions:
Scientific computing 1. First unit-level concurrency
• IBM 1620 and 7090 computers 2. First exception handling
• FORTRAN 3. Switch-selectable recursion
• SHARE user group 4. First pointer data type
Business computing 5. First array cross sections
• IBM 1401, 7080 computers
• COBOL Comments:
• GUIDE user group • Many new features were poorly designed
• IBM’s goal: develop a single computer (IBM 360) and a • Too large and too complex
single programming language (PL/I) that would be good • Was (and still is) actually used for both scientific
for scientific and business applications. and business applications
• Eventually grew to include virtually every idea in current • Subsets (e.g. PL/C) developed which were more
practical programming languages. manageable
CMSC 331. Some material © 1998 by Addison Wesley Longman, Inc. 35 CMSC 331. Some material © 1998 by Addison Wesley Longman, Inc. 36
CMSC 331. Some material © 1998 by Addison Wesley Longman, Inc. 9
UMBC CMSC 331
Simula (1962-67) Algol 68
From the continued development of ALGOL 60, but it is not
• Designed and built by Ole-Johan Dahl and Kristen a superset of that language
Nygaard at the Norwegian Computing Centre (NCC) in
Oslo between 1962 and 1967 • Design is based on the concept of orthogonality
• Originally designed and implemented as a language for • Contributions:
discrete event simulation
• Based on ALGOL 60 • User-defined data structures
Primary Contributions: • Reference types
• Coroutines - a kind of subprogram
• Classes (data plus methods) and objects • Dynamic arrays (called flex arrays)
• Inheritance
• Dynamic binding • Comments:
=> Introduced the basic ideas that developed into object- • Had even less usage than ALGOL 60
oriented programming. • Had strong influence on subsequent languages,
especially Pascal, C, and Ada
CMSC 331. Some material © 1998 by Addison Wesley Longman, Inc. 37 CMSC 331. Some material © 1998 by Addison Wesley Longman, Inc. 38
The 1970s: Simplicity, Pascal (1971)
Abstraction, Study
• Designed by Wirth, who quit the ALGOL 68
• Algol-W - Nicklaus Wirth and C.A.R.Hoare committee (didn't like the direction of that
– reaction against 1960s work)
– simplicity
• Designed for teaching structured programming
• Pascal • Small, simple
– small, simple, efficient structures • Introduces some modest improvements, such as
– for teaching program the case statement
• C - 1972 - Dennis Ritchie • Was widely used for teaching programming ~
– aims for simplicity by reducing restrictions of the type system 1980-1995.
– allows access to underlying system
– interface with O/S - UNIX
CMSC 331. Some material © 1998 by Addison Wesley Longman, Inc. 39 CMSC 331. Some material © 1998 by Addison Wesley Longman, Inc. 40
CMSC 331. Some material © 1998 by Addison Wesley Longman, Inc. 10
UMBC CMSC 331
C (1972-) Other descendants of ALGOL
• Modula-2 (mid-1970s by Niklaus Wirth at ETH)
• Designed for systems programming at Bell • Pascal plus modules and some low-level
Labs by Dennis Richie and colleagues. features designed for systems programming
• Evolved primarily from B, but also • Modula-3 (late 1980s at Digital & Olivetti)
ALGOL 68 • Modula-2 plus classes, exception handling,
• Powerful set of operators, but poor type garbage collection, and concurrency
checking • Oberon (late 1980s by Wirth at ETH)
• Adds support for OOP to Modula-2
• Initially spread through UNIX and the
• Many Modula-2 features were deleted (e.g., for
availability of high quality, free compilers. statement, enumeration types, with statement,
noninteger array indices)
CMSC 331. Some material © 1998 by Addison Wesley Longman, Inc. 41 CMSC 331. Some material © 1998 by Addison Wesley Longman, Inc. 42
The 1980s: Consolidation Ada
and New Paradigms • In study done in 73-74 it was determined that the US
DoD was spending $3B annually on software, over
• Ada half on embedded computer systems.
– US Department of Defence • The Higher Order Language Working Group was
– European team lead by Jean Ichbiah formed and initial language requirements compiled
and refined in 75-76 and existing languages
• Functional programming evaluated.
– Scheme, ML, Haskell • In 1997, it was concluded that none were suitable,
• Logic programming though Pascal, ALGOL 68 or PL/I would be a good
starting point.
– Prolog
• Language DoD-1 was developed thru a series of
• Object-oriented programming competitive contracts.
– Smalltalk, C++, Eiffel
CMSC 331. Some material © 1998 by Addison Wesley Longman, Inc. 43 CMSC 331. Some material © 1998 by Addison Wesley Longman, Inc. 44
CMSC 331. Some material © 1998 by Addison Wesley Longman, Inc. 11
UMBC CMSC 331
Ada Ada
Contributions:
• Renamed Ada in May 1979. 1. Packages - support for data abstraction
2. Exception handling - elaborate
• Reference manual, Mil. Std. 1815 approved 10
3. Generic program units
December 1980. (Ada Bryon was born
4. Concurrency - through the tasking model
10/12/1815)
Comments:
• “mandated” for use in DoD work during late 80’s • Competitive design
and early 90’s. • Included all that was then known about software
• Ada95, a joint ISO and ANSI standard, accepted in engineering and language design
February 1995 and included many new features. • First compilers were very difficult; the first really
• The Ada Joint Program Office (AJPO) closed 1 usable compiler came nearly five years after the
October 1998 (Same day as ISO/IEC 14882:1998 language design was completed
(C++) published!) • Very difficult to mandate programming technology
CMSC 331. Some material © 1998 by Addison Wesley Longman, Inc. 45 CMSC 331. Some material © 1998 by Addison Wesley Longman, Inc. 46
Logic Programming: Prolog Functional Programming
• Developed at the University of Aix • Common Lisp: consolidation of LISP dialects
Marseille, by Comerauer and Roussel, with spured practical use, as did the development of
some help from Kowalski at the University Lisp Machines.
of Edinburgh • Scheme: a simple and pure LISP like language
used for teaching programming.
• Based on formal logic
• Logo: Used for teaching young children how to
• Non-procedural program.
• ML: (MetaLanguage) a strongly-typed functional
• Can be summarized as being an intelligent language first developed by Robin Milner in the
database system that uses an inferencing 70’s
process to infer the truth of given queries • Haskell: polymorphicly typed, lazy, purely
functional language.
CMSC 331. Some material © 1998 by Addison Wesley Longman, Inc. 47 CMSC 331. Some material © 1998 by Addison Wesley Longman, Inc. 48
CMSC 331. Some material © 1998 by Addison Wesley Longman, Inc. 12
UMBC CMSC 331
Smalltalk (1972-80) C++ (1985)
• Developed at Xerox PARC by Alan Kay and • Developed at Bell Labs by Stroustrup
colleagues (esp. Adele Goldberg) inspired by
• Evolved from C and SIMULA 67
Simula 67
• First compilation in 1972 was written on a bet to • Facilities for object-oriented programming, taken
come up with "the most powerful language in the partially from SIMULA 67, added to C
world" in "a single page of code".
• Also has exception handling
• In 1980, Smalltalk 80, a uniformly object-oriented
programming environment became available as the • A large and complex language, in part because it
first commercial release of the Smalltalk language supports both procedural and OO programming
• Pioneered the graphical user interface everyone
• Rapidly grew in popularity, along with OOP
now uses
• Saw some industrial use in late 80’s and early 90’s • ANSI standard approved in November, 1997
CMSC 331. Some material © 1998 by Addison Wesley Longman, Inc. 49 CMSC 331. Some material © 1998 by Addison Wesley Longman, Inc. 50
1990’s: the Internet and web
Eiffel
• Eiffel - a related language that supports OOP
During the 90’s, Object-oriented languages
(mostly C++) became widely used in
- (Designed by Bertrand Meyer - 1992) practical applications
- Not directly derived from any other The Internet and Web drove several
language phenomena:
- Smaller and simpler than C++, but still has – Adding concurrency and threads to existing
most of the power languages
– Increased use of scripting languages such as Perl
and Tcl/Tk
– Java as a new programming language
CMSC 331. Some material © 1998 by Addison Wesley Longman, Inc. 51 CMSC 331. Some material © 1998 by Addison Wesley Longman, Inc. 52
CMSC 331. Some material © 1998 by Addison Wesley Longman, Inc. 13
UMBC CMSC 331
Java C# (C Sharp)
• Developed at Sun in the early 1990s • Microsoft and Sun were bitter rivals in the
with original goal of a language for 90s
embedded computers • C# is Microsoft’s answer to Java
• Principals: Bill Joy, James Gosling, Mike
Sheradin, Patrick Naughton • C# is very similar to Java with (maybe)
• Original name, Oak, changed for copyright reasons some minor improvements
• Based on C++ but significantly simplified • If you know Java, learning C# should be
• Supports only OOP easy
• Has references, but not pointers • However: both languages have extensive
• Includes support for applets and a form of libraries, and mastering them is a big part of
concurrency mastering the language.
CMSC 331. Some material © 1998 by Addison Wesley Longman, Inc. 53 CMSC 331. Some material © 1998 by Addison Wesley Longman, Inc. 54
Scripting Languages The future
• Scripting languages like Perl, Ruby, • The 60’s dream was a single all purpose language (e.g.,
Javascript and PHP have become important PL/I, Algol)
• They shine at connecting diverse pre- • The 70s and 80s dream expressed by Winograd (1979)
existing components to accomplish new “Just as high-level languages allow the programmer to
tasks escape the intricacies of the machine, higher level
programming systems can provide for manipulating
• Cf. shell languages in Unix complex systems. We need to shift away from algorithms
• Typical properties include: and towards the description of the properties of the
packages that we build. Programming systems will be
– privileging rapid development over execution efficiency declarative not imperative”
– implemented with interpreters rather than compilers
• Will that dream be realised?
– strong at communication with program components in
other languages • Programming is not yet obsolete
CMSC 331. Some material © 1998 by Addison Wesley Longman, Inc. 55 CMSC 331. Some material © 1998 by Addison Wesley Longman, Inc. 56
CMSC 331. Some material © 1998 by Addison Wesley Longman, Inc. 14