Eiffel in Depth Bertrand Meyer With material by Emmanuel Stapf (Eiffel Software) & members of the...

Post on 29-Mar-2015

218 views 0 download

Tags:

Transcript of Eiffel in Depth Bertrand Meyer With material by Emmanuel Stapf (Eiffel Software) & members of the...

Eiffel in Depth

Bertrand Meyer

With material by Emmanuel Stapf (Eiffel Software)

& members of the ETH Chair of Software Engineering

Chair ofSoftware Engineering

2

Plan of these slides

1 Overview 2 The

environment(s) 3 Method overview 4 Language basics 5 Dynamic model 6 Genericity &

inheritance 7 Design by

Contract™

8 External interface 9 Agents 10 Advanced design 11 Advanced

mechanisms 12 Conclusion 13 Supplements

3

Purpose of this course

To give you an in-depth understanding of a software method, language and environment: Eiffel (and EiffelStudio)

To improve your understanding of software engineering and software architecture

To give you a feel for the challenges involved in both software design and language design

4

The software of the future

Product quality Correctness Robustness Security

Process quality Fast development No semantic gap (“impedance mismatch”) between developers and other stakeholders Self-validating, self-testing Ease of change Reusability

5

- 1 -

Overview

6

Why Eiffel?

Productivity: faster time to market, fewer developers

Reliability: fewer bugs

Extendibility: be responsive to customer needs

Reuse: stand on the shoulder of giants

Efficiency: make the best use of hardware resources

Maintainability: spend your time on new developments

7

Language versions

Eiffel 1, 1986Classes, contracts, genericity, single and

multipleinheritance, garbage collection, …

Eiffel 2, 1988 (Object-Oriented Software Construction)Exceptions, constrained genericity

Eiffel 3, 1990-1992 (Eiffel: The Language)Basic types as classes, infix & prefix operators…

Eiffel 4, 1997“Precursor” and agents

Eiffel 5, ECMA Standard, 2005, revised 2006, and ISO standard, November 2006www.ecma-international.org/publications/standards/Ecma-367.htm

Attached types, conversion, assigner commands…

8

Eiffel: Method, Language, Environment

Method : Applicable throughout the lifecycle Object-oriented to the core Seamless development Based on Design by Contract™ principles

Language : Full power of object technology Simple yet powerful, numerous original features ISO standard (2006)

Environment : Integrated, provides single solution, including

analysis and modeling Lots of platforms (Unix, Windows, VMS, .NET…) Open and interoperable

99

Some typical users

Axa RosenbergInvestment management: from $2 billion to >$100 billion 2 million linesChicago Board of Trade Price reporting system Eiffel + CORBA + Solaris + Windows + …Xontech (for Boeing) Large-scale simulations of missile defenseNorthrop-Grumman

Swedish social security: accident reporting & management

(Eiffel) Price Reporting System

The Chicago Board of Trade

See: eiffel.co

m

1010

Learning Eiffel

Simple syntax, no cryptic symbols

Eiffel programmers know all of Eiffel Wide variety of user backgrounds

“If you can write a conditional,you can write a contract”

Fast learning curve Lots of good models to learn from Strong style rules

May need to “unlearn” needless tricks

11

The Eiffel method: some principles

Abstraction Information hiding Seamlessness Reversibility Design by Contract Open-Closed principle Single choice principle Single model principle Uniform access principle Command-query separation principle Option-operand separation principle Style matters ... See

next...

12

The Eiffel language

Classes

Uniform type system, covering basic types

Genericity

Inheritance, single and multiple

Conversion

Covariance

Statically typed

Built-in Design by Contract mechanisms

Agents: objects encapsulating behavior

“Once” mechanisms, replacing statics and globals

Void safety (new!)

13

Libraries

Fundamental data structures and algorithms

Portable graphics

Internet, Web

Lexical analysis, parsing

Database interfaces

14

Dogmatism and flexibility

Dogmatic where it counts:

Information hiding (e.g. no x.a := b) Overloading “One good way to do anything” Style rules

Flexible when it makes no point to harass programmers:

Give standard notations (e.g. a + b) an O-O interpretation

Syntax, e.g. semicolon

15

The Eiffel language: there is a hidden agenda

That you forget it even exists

16

- 2 -

The environment

17

EiffelStudio

Serialization

EiffelStore

EiffelStudio

Ansi C

Executable system

IL

EiffelBase

WEL

EiffelVision

EiffelNet

EiffelWeb

EiffelMath

EiffelCOM

Persistent objects

Eiffel Runtime

Databases (Rel,

OO)

C compilation

JitterEiffel compilation

User classes

General library

Win32 library

Networking

Web development

Advanced numerics

External C/C++/Java

.NET Assemblies

EiffelBuild

GUI builder

Multiplatform GUI library

Browsing, fast compiling (Melting Ice™), debugging, diagrams, metrics...

18

EiffelStudio: Melting Ice™ Technology

Fast recompilation: time depends on size of change, not size of program

Full type checking

“Freeze” once in a while

Optimized compilation: finalize.

Small program

Large program

Smallchange

Bigchange

19

Melting Ice Technology

FROZEN

MELTED

EiffelStudio Your system

Machine code(from C code)Edit, browse,

execute,debug, test…

Freeze

Melt

20

Performance

“Finalization” mode of compilation applies extensive optimizations:

Inlining Dead code removal Contract removal ...

Optimizations are compiler-applied and automatic; no need for manual hacking

Compacting garbage collection takes care of memory issues

Intended to match the most exacting demands of industry applications

21

EiffelStudio browsing and debugging

You are dealing with “development objects”:

Classes Features Run-time objects (for debugging)

To work on an object, “pick-and-drop” it into an appropriate tool

22

Openness

Eiffel can be used as “component combinator” to package elements from different sources:

Mechanisms for integrating elements in C, C++, Java, CIL (.NET)

Interfaces and libraries: SQL, XML, UML (XMI), CORBA, COM, others

Particularly sophisticated mechanisms for C/C++ interfacing

Outside of .NET, compiles down to ANSI C code, facilitates support for C and C++ easier.

On .NET, seamless integration with C#, VB .NET etc.

23

C/C++ support

Functions, macros, include files, setters, getters, constructors, destructors etc.

Inline C

From the outside into Eiffel: CECIL (C-Eiffel Common Interface Library)

24

Portability

Source-code portability across:

Windows NT, 2000, XP, Vista Windows 98, Me .NET Solaris, other commercial Unix variants Linux Mac OS X (forthcoming) BSD (Berkeley System Distribution) VMS

25

- 3 -

The method

26

The waterfall model of the lifecycle

Feasibility study

Requirements

Global design

Detailed design

Deployment

V & V

Specification

Implementation

27

Traditional lifecycle model

Rigid model:Waterfall: separate tasks,

impedance mismatchesVariants, e.g. spiral, retain

some of the problemsSeparate tools:

Programming environmentAnalysis & design tools, e.g. UML

Consequences:Hard to keep model, implementation,

documentation consistent Constantly reconciling viewsInflexible, hard to maintain systemsHard to accommodate bouts of late wisdomWastes effortsDamages quality

Feasibility study

Requirements

Global design

Detailed design

Deployment

V & V

Specification

Implementation

28

The Eiffel model

Seamless development:Single notation, tools, concepts, principles throughout Eiffel is as much for analysis & design as implementation & maintenanceContinuous, incremental developmentKeep model, implementation and documentation consistentReversibility: go back & forthSaves money: invest in single set of toolsBoosts quality

Example classes:PLANE, ACCOUNT, TRANSACTION…

STATE, COMMAND…

HASH_TABLE…

TEST_DRIVER…

TABLE…

Analysis

Design

Implemen-

tation

V&V

Generali-zation

29

Seamlessness

Seamlessness Principle

Software development should relyon a single set of notations & tools

30

Reversibility

Reversibility Principle

The software development process,notations and tools

should allow making changesat any step in the process

31

The seamless, reversible model

Example classes:PLANE, ACCOUNT, TRANSACTION…

STATE, COMMAND…

HASH_TABLE…

TEST_DRIVER…

TABLE…

Analysis

Design

Implemen-

tation

V&V

Generali-zation

32

Class invariant

Postcondition

Precondition

Specified, notimplemented

Analysis classesdeferred class VAT inherit

TANKfeature

in_valve, out_valve : VALVE

fill -- Fill the vat.

requirein_valve.openout_valve.closed

deferred

ensurein_valve.closed

out_valve.closedis_full

end

empty, is_full, is_empty, gauge, maximum,

invariantis_full = (gauge >= 0.97 * maximum)  and  (gauge <= 1.03 * maximum)

end

33

Single model

Use a single base for everything: analysis, design, implementation, documentation...

Use tools to extract the appropriate views.

Single Model Principle

All the informationabout a software system

should be in the software text

34

The seamless, reversible model

Analysis

Design

Implemen-

tation

V&V

Generali-zation

35

Generalization

Prepare for reuse:Remove built-in limitsRemove dependencies on specifics of project

Improve documentation, contracts...

Abstract Extract commonalities, revamp inheritance hierarchy

35

A D I V G

A *

B

Y *

X Z

T

U

36

The cluster model

A

D

I

V

G

Permits dynamic reconfiguration

A

D

I

V

G

A

D

I

V

G

A

D

I

V

G

A

D

I

V

G

A

D

I

V

G

Mix of sequential and concurrent engineering

37

Tool support for seamless development

Diagram Tool• System diagrams can be produced automatically from software text

• Works both ways: update diagrams or update text – other view immediately updated

No need for separate UML tool Metrics Tool Profiler Tool Documentation generation tool ...

38

EiffelStudio diagram tool

39

Text-graphics equivalence

40

Equivalence

Equivalence Principle

Textual, graphical and other viewsshould all represent the same model

41

Eiffel mechanisms

Classes, objects, ... Single and multiple inheritance Inheritance facilities: redefinition, undefinition,

renaming Genericity, constrained and unconstrained Safe covariance Disciplined exception handling, based on

principles of Design by Contract Full GC Agents (power of functional programming in O-O!) Unrestricted streaming: files, databases,

networks...

42

What is not in Eiffel

Goto Functions as arguments Pointer arithmetic Special increment syntax, e.g. x++, ++x

In-class feature overloading

43

Syntax conventions

Semicolon used as a separator (not terminator)It’s optional almost all the time. Just forget about it!

Style rules are an important part of Eiffel: Every feature should have a header comment Every class should have a note clause Layout, indentation Choice of names for classes and features

44

The class

From the module viewpoint: Set of available services (“features”) Information hiding Classes may be clients of each other

From the type viewpoint: Describes a set of run-time objects (the instances

of the class) Used to declare variables (more generally,

entities ), e.g. x : C

Possible type checking Notion of subtype

45

Information hiding

Information Hiding principle

Every module should have a publicspecification,

listing a subset of its properties

46

prepend

animate

append

An object has an interface

count stations

first last

47

prepend

animate

appendcount

first

An object has an implementation

count stations

first last

48

Information hiding

prepend

animate

appendcount stations

first last

49

Information Hiding

The designer of every module must select a subset of its properties as the official information about the module, made available to authors of client modules

Public

Private

50

Uniform access

Uniform access principle

It does not matter to the clientwhether you look up or compute

51

Uniform Access: an example

balance = list_of_deposits.total – list_of_withdrawals.total

(A1)200 100 500 1000

800 100 100

(A2)

200 300 500 1000

800 100 100

list_of_deposits

list_of_withdrawals

list_of_deposits

list_of_withdrawals

balance 1000

52

Uniform access

A call such as

your_account.balance

could use an attribute or a function

Uniform access principle

It does not matter to the clientwhether you look up or compute

53

POINT : as an abstract data type

x : POINT REAL

y : POINT REAL

: POINT REAL

: POINT REAL

Class POINT: Choose a representation (polar, cartesian)

In polar representation, and are attributes, x and y are routines.

y

x

54

POINT: as a class

class POINT feature

x, y : REAL-- Cartesian coordinates

move (a, b : REAL)-- Move by a horizontally and b vertically.

dox := x + ay := y + b

end

scale (factor : REAL)-- Scale by factor.

dox := factor * xy := factor * y

end

55

Class POINT

distance (p : POINT ): REAL-- Distance to p

doResult := sqrt ((x – p.x)^2 + (y –

p.y)^2)end

ro : REAL-- Distance to origin (0, 0)

doResult := sqrt (x ^ 2 + y ^ 2)

end

theta : REAL-- Angle to horizontal axis

do…

endend

56

Uniform access through feature call

To access a feature of a point, same notation regardless of representation.

Example:

p1.x

Cartesian representation: attribute call Polar representation: function call

No difference for clients (except possibly performance)

57

Uniform access in practice

Class COMPLEX, switching silently and on demand between cartesian and polar representation

Secret attributes:

cartesian_uptodate, polar_uptodate : BOOLEANinternal_x, internal_y, internal_ro, internal_theta :

REAL

Representation invariant:

invariantat_least_one : cartesian_uptodate or

polar_uptodate

58

Updating representation: secret routine

update_cartesianrequire

polar_ok: polar_uptodatedo

if not cartesian_uptodate theninternal_x := ro * cos (theta)internal_y := ro * sin (theta)

endensure

cart_ok: cartesian_uptodatepolar_ok: polar_uptodate

end

59

Public query

x : REAL -- Abscissa of current pointdo

if not cartesian_uptodate thenupdate_cartesian

endResult := x_internal

ensurecart_ok : cartesian_uptodate

same_as_internal : Result = x_internal

end

60

Adding two complex numbers

plus (other : COMPLEX )

-- Add other to current complex number. do

update_cartesian

x_internal := x_internal + other.xy_internal := y_internal + other.y

ensurecartesian_ok : cartesian_uptodate

end

61

Beyond information hiding

Single choice principle

If a system supports a set of choices,only one of its elements should know the list

62

Single choice: examples

Graphic system: set of figures

Editor: set of commands

Compiler: set of language constructs

Single choice principle

If a system supports a set of choices,only one of its elements should know the list

63

Without dynamic binding!

display (f : FIGURE )do

if ‘‘f is a CIRCLE’’ then ...

elseif ‘‘f is a POLYGON’’ then...

endend

and similarly for all other routines!

Tedious; must be changed whenever there’s a new figure type

64

With inheritance &associated techniques

f : FIGUREc : CIRCLEp : POLYGON

create c.make (...)create p.make (...)

if ... then f := c

else f := p

end

f.move (...)f.rotate (...)f.display (...)

-- and so on for every -- operation on f !

With:

Initialize:

and:

Then just use:

65

Memory management

Memory management principle

It is the implementation’s responsibilityto reclaim unused objects

66

What to do with unreachable objects

Reference assignmentsmay make some objects useless.

Two possible approaches: Manual “free” (C++). Automatic garbage collection

“Almaviva”namelandlor

dloved_one

aO1

“Figaro”O2

“Susanna”O3

67

The C programmer’s view

Newsgroup posting by Ian Stephenson, 1993 (as cited in Object-Oriented Software Construction, 2nd edition):

I say a big NO ! Leaving an unreferenced object around is BAD PROGRAMMING. Object pointers ARE like ordinary pointers — if you allocate an object you should be responsible for it, and free it when its finished with. (Didn't your mother always tell you to put your toys away when you'd finished with them?)

68

Arguments for automatic collection

Manual reclamation is dangerous for reliability.

Wrong “frees” are among the most difficult bugs to detect and correct.

Manual reclamation is tedious.

Modern garbage collectors have acceptable performance overhead.

GC is tunable: disabling, activation, parameterization....

69

Properties of a garbage collector (GC)

Soundness: If the GC reclaims an object, it is unreachable

Completeness : If an object is unreachable, the GC will reclaim it

Soundness is an absolute requirement. Better no GC than an unsound GC

But: safe automatic garbage collection is hard in C-based languages

70

Language style

Consistency principle

The language should offerone good way to do anything useful

71

Language style

Compatibility principle

Traditional notations should be supportedwith an O-O semantics

72

Infix and prefix operators

In

a − bthe − operator is “infix”

(written between operands)

In

− bthe − operator is “prefix”

(written before the operand)

73

The object-oriented form of call

some_target.some_feature (some_arguments)

For example:

my_figure.display

my_figure.move (3, 5)

x := a.plus (b) ???????

74

Operator features

expanded class INTEGER feature

plus alias "+" (other : INTEGER): INTEGER-- Sum with other

do ... end

times alias "*" (other : INTEGER): INTEGER -- Product by other

do ... end

minus alias "-" : INTEGER-- Unary minus

do ... end...end

Calls such as i.plus ( j ) can now be written i + j

75

Assignment commands

It is possible to define a query as

temperature: REAL assign set_temperature

Then the syntax

x.temperature := 21.5

is accepted as an abbreviation for

x.set_temperature (21.5)

Retains contracts and any other supplementary operations

Not an assignment, but a procedure call

76

Array access

Object-oriented forms:a : ARRAY [T ]a.put (x, 23)x := a.item (23)

Usual forms:a [23] := x

x := a [23]

Usual form:a [i ] := a [i ] + 1

Object-oriented form:a.put (a.item (i ) + 1, i )

77

Using the bracket alias

In class ARRAY [G ] :

item (i : INTEGER): Grequire

i >= lower and i <= countdo … end

put (x : G ; i : INTEGER): Grequire

i >= lower and i <= countdo … end

alias "[ ]" assign put

a.put (a.item (i ) + 1, i )

a.item (i ) := a.item (i ) + 1

a [i ] := a [i ] + 1

Not an assignment!

78

Bracket alias

population [“Lugano ] := 50000

table [a, b, c] := d

79

Command-query separation

Command-Query Separation Principle

A function must not changeits target object’s abstract state

80

Command-Query separation

A command (procedure) does something but does not return a result.

A query (function or attribute) returns a result but does not change the state.

81

Command-Query Separation

Asking a questionshould not change the answer!

82

Command-query separation

Command-Query Separation Principle

A function must not changeits target object’s state

This principle excludes many common schemes, such as using functions for input (e.g. C’s getint or equivalent).

83

Referential transparency

If two expressions have equal value, one may be substituted for the other in any context where that other is valid.

If a = b, then f (a) = f (b) for any f. Prohibits functions with side effects. Also:

For any integer i, normally i + i = 2 x i But even if getint () = 2, getint () + getint () is

usually not equal to 4.

84

Command-query separation

Input mechanism using EiffelBase(instead of n := getint ()):

io.read_integer

n := io.last_integer

85

A discipline of development

Reuse Principle

Design with reuse in mind

86

Typical API in a traditional library (NAG)

nonlinear_ode(equation_count : in INTEGER; epsilon : in out DOUBLE; func : procedure

(eq_count : INTEGER; a : DOUBLE; eps : DOUBLE; b : ARRAY [DOUBLE]; cm : pointer Libtype);

left_count, coupled_count : INTEGER …)

[And so on. Altogether 19 arguments, including: 4 in out values; 3 arrays, used both as input and output; 6 functions, each with 6 or 7 arguments, of

which 2 or 3 arrays!]

Ordinary differential equation

87

The EiffelMath routine

... Create e and set-up its values (other than defaults) ...

e.solve

... Answer available in e.x and e.y ...

88

The Consistency Principle

Two components: Top-down and deductive (the overall design). Bottom-up and inductive (the conventions).

Consistency Principle

All the components of a libraryshould proceed from an overall

coherent design, and followa set of systematic, explicitand uniform conventions.

89

The key to building a library

Devising a theory of the underlying domain

90

Some of the theory behind EiffelBase

CONTAINER

BOX

FINITE INFINITE

BOUNDED UNBOUNDED

FIXED RESIZABLE

COLLECTION

BAG SET

TABLE ACTIVE SUBSET

DISPENSERINDEXABLE CURSOR_STRUCTURE

SEQUENCE

TRAVERSABLE

HIERAR_CHICAL LINEAR

BILINEAR

*

* * *

*

*

*

*

* *

* * * * * *

* * * * * *

COUNTABLE*

RepresentationAccess

Iteration

91

The size of feature interfaces

More relevant than class size for assessing complexity.

Statistics from EiffelBase and associated libraries:

Number of features 4408

Percentage of queries 66%

Percentage of commands 34%

Average number of arguments to a feature 0.5

Maximum number 5

No arguments 57%

One argument 36%

Two arguments 6%

Three or more arguments 1%

92

Operands and options

Two possible kinds of argument to a feature: Operands: values on which feature will operate Options: modes that govern how feature will

operateExample (non-O-O): printing a real number print (real_value, number_of_significant_digits,

zone_length, number_of_exponent_digits, ...)The number is an operand; format properties (e.g. number of significant digits, width) are options

O-O example:

my_window.display (x_position, y_position, height, width, text, title_bar_text, color, ...)

93

Recognizing options from operands

Two criteria to recognize an option:

There is a reasonable default value.

During the evolution of a class, operands will normally remain the same, but options may be added.

94

Option-Operand separation

Option values: Defaults (specified universally, per type, per

object) To set specific values, use appropriate “setter”

procedures

Example:

my_window.set_background_color ("blue")...

my_window.display

Option-Operand Principle

Only operands should appearas arguments of a feature

95

Naming (classes, features, variables…)

Traditional advice (for ordinary application programming):

Choose meaningful variable names!

96

enter

push

add

insert

Original

Class

ARRAY

STACK

QUEUE

HASH_TABLE

entry

top

oldest

value

pop

remove_oldest

delete

Features

names for EiffelBase classes

put

put

put

put

item

item

item

item

remove

remove

remove

Final

enter

push

add

insert

Class

ARRAY

STACK

QUEUE

HASH_TABLE

remove_oldest

delete

Features

put

put

put

item

item

item

item

remove

remove

remove

entry

top

oldest

value

put

New and old names for EiffelBase classes

97

Naming rules

Achieve consistency by systematically using a set of standardized names.

Emphasize commonality over differences.

Differences will be captured by: Signatures (number and types of arguments &

result) Assertions Comments

98

Some standard namesQueries (non-boolean):

count, capacityitem

to_X, from_X

Queries (boolean) :writable, readable, extendible, prunableis_empty, is_full

-- Usual invariants:0 <= count ; count <= capacityis_empty = (count = 0) ; is_full = (count =

capacity)

if s.deletable thens.delete (v)

end

-- Some rejected names:

if s.addable thens.add (v)

end

Commands:put, extend, replace, forcewipe_out, remove, prunemake -- For creation

99

- 4 -

Design by Contract

100

Design by Contract

Contract Principle

Every software elementshould be characterized

by a precise specification

101

Design by Contract: applications

Getting the software right Analysis Design Implementation Debugging Testing Management Maintenance Documentation

102

Design by Contract: the basic idea

Every software element is intended to satisfy a certain goal, for the benefit of other software elements (and ultimately of human users)

This goal is the element’s contract

The contract of any software element should be Explicit Part of the software element itself

103

A counter-example: Ariane 5, 1996

(See: Jean-Marc Jézéquel and Bertrand Meyer: Design by Contract: The Lessons of Ariane, IEEE Computer, January 1997, also at http://www.eiffel.com)

37 seconds into flight, exception in Ada program not processed; order given to abort the mission. Ultimate cost in billions of euros

Cause: incorrect conversion of 64-bit real value (“horizontal bias” of the flight) into 16-bit integer

Systematic analysis had “proved” that the exception could not occur!

104

Ariane-5 (continued)

It was a REUSE error:

The analysis was correct – for Ariane 4 !

The assumption was documented – in a design document !

With assertions, the error would almost certainly detected by either static inspection or testing:

integer_bias (b : REAL): INTEGER

requirerepresentable (b)

do…

ensureequivalent (b, Result)

end

105

The contract view of software construction

Constructing systems as structured collections of cooperating software elements — suppliers and clients — cooperating on the basis of clear definitions of obligations and benefits

These definitions are the contracts

106

Contracts for analysis

Client

Supplier

(Satisfy precondition:)

Make sure input valve is open, output valve closed

(Satisfy postcondition:)

Fill the tank and close both valves

OBLIGATIONS

(From postcondition:)

Get filled-up tank, with both valves closed

(From precondition:)

Simpler processing thanks to assumption that valves are in the proper initial position

BENEFITSfill

107

Class invariant

Postcondition

Precondition

Specified, notimplemented

Constracts for analysis

deferred class VAT inherit

TANKfeature

in_valve, out_valve : VALVE

fill -- Fill the vat.

requirein_valve.openout_valve.closed

deferred

ensurein_valve.closed

out_valve.closedis_full

end

empty, is_full, is_empty, gauge, maximum,

invariantis_full = (gauge >= 0.97 * maximum)  and  (gauge <= 1.03 * maximum)

end

108

A class without contracts

classACCOUNT

feature -- Access

balance : INTEGER-- Balance

Minimum_balance: INTEGER = 1000-- Minimum balance

feature {NONE } -- Deposit and withdrawal

add (sum : INTEGER)-- Add sum to the balance.

dobalance := balance + sum

end

Secret features

109

A class without contracts

feature -- Deposit and withdrawal operations

deposit (sum : INTEGER)-- Deposit sum into the account.

doadd (sum)

end

withdraw (sum : INTEGER)-- Withdraw sum from the account.

doadd (– sum)

end

may_withdraw (sum : INTEGER): BOOLEAN-- Is it permitted to withdraw sum from the

account?do

Result := (balance - sum >= Minimum_balance)

endend

110

Introducing contracts

classACCOUNT

create

make

feature {NONE } -- Initializationmake (initial_amount: INTEGER)

-- Set up account with initial_amount.

require

large_enough: initial_amount >= Minimum_balance

dobalance := initial_amount

ensure

balance_set: balance = initial_amountend

111

Introducing contracts

feature -- Access

balance: INTEGER-- Balance

Minimum_balance : INTEGER = 1000-- Lowest permitted balance

feature {NONE} -- Implementation of deposit and withdrawal

add (sum : INTEGER)-- Add sum to the balance.do

balance := balance + sum ensure

increased: balance = old balance + sum end

112

Introducing contracts

feature -- Deposit and withdrawal operations

deposit (sum : INTEGER)-- Deposit sum into the account.

requirenot_too_small: sum >= 0

doadd (sum)

ensureincreased: balance = old balance +

sumend

Precondition

Postcondition

113

Introducing contracts

withdraw (sum : INTEGER)-- Withdraw sum from the account.

requirenot_too_small: sum >= 0not_too_big: sum <= balance –

Minimum_balancedo

add (–sum)

-- i.e. balance := balance – sumensure

decreased: balance = old balance - sum

endValue of balance, captured on entry to routine

114

The contract

Client

Supplier

(Satisfy precondition:)

Make sure sum is neither too small nor too big

(Satisfy postcondition:)

Update account for withdrawal of sum

OBLIGATIONS

(From postcondition:)

Get account updated with sum withdrawn

(From precondition:)

Simpler processing: may assume sum is within allowable bounds

BENEFITSwithdraw

115

The imperative and the applicative

do

balance := balance - sum

ensure

balance = old balance - sum

PRESCRIPTIVE DESCRIPTIVE

How?

Operational

Implementation

Command

Instruction

Imperative

What?

Denotational

Specification

Query

Expression

Applicative

116

Introducing contracts

may_withdraw (sum : INTEGER ): BOOLEAN-- Is it permitted to withdraw sum from

account?do

Result := (balance - sum >= Minimum_balance)

end

invariantnot_under_minimum: balance >= Minimum_balance

end

117

The class invariant

Consistency constraint applicable to all instances of a class.

Must be satisfied: After creation After execution of any feature by any client

Qualified calls only: x.f (...)

118

The correctness of a class

For every creation procedure cp :

{Precp } docp {INV and Postcp }

For every exported routine r :

{INV and Prer } dor {INV and Postr }

x.f (…)

x.g (…)

x.h (…)

create x.make (…) S1

S2

S3

S4

119

Uniform Access

balance = deposits.total – withdrawals.total

(A1)list_of_deposits

list_of_withdrawals

200 100 500 1000

800 100 100

(A2)

200 300 500 1000

800 100 100

list_of_deposits

list_of_withdrawals

balance 1000

120

What are contracts good for?

Writing correct software (analysis, design, implementation, maintenance, reengineering) Documentation (the “contract” form of a class)Effective reuseControlling inheritancePreserving the work of the best developers

Quality assurance, testing, debugging (especially in connection with the use of libraries) Exception handling

121

A contract violation is not a special case

For special cases(e.g. “if the sum is negative, report an error...”)

use standard control structures, such as if ... then ... else...

A run-time assertion violation is something else: the manifestation of

A DEFECT (“BUG”)

122

Contracts and quality assurance

Precondition violation: Bug in the client.

Postcondition violation: Bug in the supplier.

Invariant violation: Bug in the supplier.

{P } A {Q }

123

Contracts: run-time effect

Compilation options (per class, in Eiffel): No assertion checking Preconditions only Preconditions and postconditions Preconditions, postconditions, class invariants All assertions

124

Contracts for testing and debugging

Contracts express implicit assumptions behind code A bug is a discrepancy between intent and code Contracts state the intent!

In EiffelStudio: select compilation option for run-time contract monitoring at level of:

Class Cluster System

May disable monitoring when releasing softwareA revolutionary form of quality assurance

125

Lists in EiffelBase

Cursor

item

index

count1

forthback

finishstart

afterbefore

“Munich"

126

Trying to insert too far right

Cursor

(Already past last element!)

count1

after

"Munich"

127

A command and its contract

Precondition

Postcondition

128

Moving the cursor forward

Cursor

index

forth

count1

afterbefore

"Munich"

129

Two queries, and command forth

130

Where the cursor may go

Valid cursor positions

0 index1

afterbefore

"Munich"

count count + 1

131

From the invariant of class LIST

Valid cursor positions

132

Contracts and bug types

Preconditions are particularly useful to find bugs in client code:

YOUR APPLICATION

COMPONENT LIBRARY

your_list.insert (y, a + b + 1)

i <= count + 1

insert (x : G ; i : INTEGER)require

i >= 0

class LIST [G ] feature

133

Contracts and quality assurance

Use run-time assertion monitoring for quality assurance, testing, debugging.

Compilation options (reminder):

No assertion checking Preconditions only Preconditions and postconditions Preconditions, postconditions, class invariants All assertions

134

Contracts and quality assurance

Contracts enable QA activities to be based on a precise description of what they expect.

Profoundly transform the activities of testing, debugging and maintenance.

“I believe that the use of Eiffel-like module contracts is the most important non-practice in software world today. By that I mean there is no other candidate practice presently being urged upon us that has greater capacity to improve the quality of software produced. ... This sort of contract mechanism is the sine-qua-non of sensible software reuse. ”

                      Tom de Marco, IEEE Computer, 1997

135

Contracts and documentation

Contract view: Simplified form of class text, retaining interface elements only: Remove any non-exported (private) feature

For the exported (public) features: Remove body (do clause) Keep header comment if present Keep contracts: preconditions, postconditions,

invariant Remove any contract clause that refers to a secret

feature(This raises a problem; can you see it?)

136

Flat, interface

Flat view of a class: reconstructed class with all the features at the same level (immediate and inherited). Takes renaming, redefinition etc. into account.

The flat view is an inheritance-free client-equivalent form of the class.

Interface view: the contract view of the flat view. Full interface documentation.

137

Uses of the contract &interface forms

Documentation, manualsDesignCommunication between developersCommunication between developers and managers

138

Contracts and inheritance

Issues: what happens, under inheritance, to

Class invariants?

Routine preconditions and postconditions?

139

Invariants

Invariant Inheritance rule:

The invariant of a class automatically includes the invariant clauses from all its parents, “and”-ed.

Accumulated result visible in flat and interface forms.

140

Contracts and inheritance

require

ensure

rrequire

ensure

a1 : A

a1.r (…)

Correct call in C: if a1. then a1.r (...) -- Here a1. holds end

r ++

C A

D B

ClientInheritance ++ Redefinition

141

Assertion redeclaration rule

When redeclaring a routine, we may only:

Keep or weaken the precondition

Keep or strengthen the postcondition

142

A simple language rule does the trick!

Redefined version may have nothing (assertions kept by default), or

require else new_preensure then new_post

Resulting assertions are: original_precondition or new_pre

original_postcondition and new_post

Assertion redeclaration rule in Eiffel

143

Contracts as a management tool

High-level view of modules for the manager:

Follow what’s going on without reading the code

Enforce strict rules of cooperation between units of the system

Control outsourcing

144

Managerial benefits

Library users can trust documentation.They can benefit from preconditions to validate their own software.Test manager can benefit from more accurate estimate of test effort.Black-box specification for free.Designers who leave bequeath not only code but intent.Common vocabulary between all actors of the process: developers, managers, potentially customers.Component-based development possible on a solid basis.

145

Genericity and inheritance

LIST_OF_CARS

SET_OF_CARS

LINKED_LIST_OF_CARS

LIST_OF_CITIES

LIST_OF_PERSONS

Abstraction

Specialization

Type parameterization

Type parameterization

Genericity

Inheritance

146

Extending the basic notion of class

LIST_OF_CARS

SET_OF_CARS

LINKED_LIST_OF_CARS

LIST_OF_CITIES

LIST_OF_PERSONS

LINKED_LIST_OF_CITIES

SET_OF_PERSONS

Genericity

Inheritance

147

An inheritance hierarchy

center * display

*rotate *

perimeter *

perimeter+

perimeter+

perimeter+

+

diagonal

...

...

perimeter+

+

side2

* deferred

+ effective

++ redefined

perimeter+

+

side1

CLOSED_FIGURE

OPEN_FIGURE

FIGURE

SEGMENT POLYLINE

TRIANGLE

POLYGON

ELLIPSE

RECTANGLE

SQUARE

CIRCLE

side

*

**

148

Redefinition 1: polygons

class POLYGON inheritCLOSED_FIGURE

createmake

featurevertex : ARRAY [POINT]vertex_count : INTEGER perimeter : REAL

-- Perimeter lengthdo from ... until ... loop

Result := Result + vertex [i ] . distance (vertex [i + 1])

... endend

invariantvertex_count >= 3vertex_count = vertex.count

end

vertex [i ]

vertex [i + 1]

149

Redefinition 2: rectangles

class RECTANGLE inheritPOLYGON

redefine perimeter

endcreate

make

featurediagonal, side1, side2 : REAL

perimeter : REAL-- Perimeter length

do Result := 2 * (side1 + side2) endinvariant

vertex_count = 4end

side1

side2diagonal

150

Inheritance, typing &polymorphism

(POLYGON )

(RECTANGLE )

p

r

Assume: p : POLYGON ; r : RECTANGLE ; t : TRIANGLE ; x : REAL

Permitted:

x := p.perimeterx := r.perimeterx := r.diagonalp := r

NOT permitted:

x := p.diagonal -- Even just after p := r ! r := p

151

Definitions: Polymorphism

An attachment (assignment or argument passing) is polymorphic if its target variable and source expression have different types.

An entity or expression is polymorphic if it may at runtime — as a result of polymorphic attachments —become attached to objects of different types.

Polymorphism is the existence of these possibilities.

152

Dynamic binding

What is the effect of this (assuming some_test true)?

if some_test thenp := r

elsep := t

end

x := p.perimeter

Redefinition: A class may change an inherited feature, as with POLYGON redefining perimeter

Polymorphism: p may have different forms at run-time.

Dynamic binding: Effect of p.perimeter depends on run-time form of p

153

Definitions (Dynamic binding)

Dynamic binding (a semantic rule) is the property that any execution of a feature call will use the version of the feature best adapted to the type of the target object.

154

Without dynamic binding!

display (f : FIGURE )do

if ‘‘f is a CIRCLE’’ then ...

elseif ‘‘f is a POLYGON’’ then...

endend

and similarly for all other routines!

Tedious; must be changed whenever there’s a new figure type

155

With inheritance &associated techniques

f : FIGUREc : CIRCLEp : POLYGON

create c.make (...)create p.make (...)

if ... then f := c

else f := p

end

f.move (...)f.rotate (...)f.display (...)

-- and so on for every -- operation on f !

With:

Initialize:

and:

Then just use:

156

Extending the basic notion of class

LIST_OF_CARS

SET_OF_CARS

LINKED_LIST_OF_CARS

LIST_OF_CITIES

LIST_OF_PERSONS

Abstraction

Specialization

Type parameterization

Type parameterization

Genericity

Inheritance

157

Genericity

Unconstrained

LIST [G]e.g. LIST [INTEGER], LIST [PERSON]

Constrained

HASH_TABLE [G ―> HASHABLE ]

VECTOR [G ―> NUMERIC ]

158

Genericity: Ensuring type safety

How can we define consistent “container” data structures, e.g. list of accounts, list of points? Dubious use of a container data structure:

c : CITY ; p : PERSONcities : LIST ... people : LIST ... ---------------------------------------------------------people.extend ( )

cities.extend ( )

c := cities.last

c. some_city_operation

What if wrong?

p

c

159

A generic class

class LIST [G ] feature

extend (x : G ) ...

last : G ...

end

To use the class: obtain a generic derivation, e.g.

cities : LIST [CITY ]

Formal generic parameter

Actual generic parameter

160

Using generic derivations

cities : LIST [CITY ]people : LIST [PERSON]c : CITYp : PERSON...

cities.extend (c)people.extend (p)

c := cities.last

c. some_city_operation

STATIC TYPING

The compiler will reject:

people.extend (c)

cities.extend (p)

161

Static typing

Type-safe call (during execution):

A feature call x.f such that the object attached to x has a feature corresponding to f.

[Generalizes to calls with

arguments, x.f (a, b) ]

Static type checker:A program-processing tool (such as a compiler) that guarantees, for any program it accepts, that any call in any execution will be type-safe.

Statically typed language:A programming language for which it is possible to write a static type checker.

162

Using genericity

LIST [CITY ]LIST [LIST [CITY ]]…

A type is no longer exactly the same thing as a class!

(But every type remains based on a class.)

163

Genericity + inheritance 1: Constrained genericity

class VECTOR [G ] feature plus alias "+" (other : VECTOR [G]): VECTOR [G]

-- Sum of current vector and otherrequire

lower = other.lower

upper = other.upperlocal

a, b, c: Gdo

... See next ...end

... Other features ...end

164

Adding two vectors

i a b c=+

+ =u v w

1

2

165

Constrained genericity

Body of plus alias "+":

create Result.make (lower, upper)

from i := lower

until i > upper

loopa := item (i)b := other.item (i)c := a + b -- Requires “+” operation on G!

Result.put (c, i)i := i + 1

end

166

The solution

Declare class VECTOR as

class VECTOR [G –> NUMERIC ] feature

... The rest as before ...end

Class NUMERIC (from the Kernel Library) provides features plus alias "+", minus alias "-"and so on.

167

Improving the solution

Make VECTOR itself a descendant of NUMERIC,

effecting the corresponding features:

class VECTOR [G –> NUMERIC ] inheritNUMERIC

feature... Rest as before, including infix "+"...

endThen it is possible to define

v : VECTOR [INTEGER ]vv : VECTOR [VECTOR [INTEGER ]]vvv : VECTOR [VECTOR [VECTOR [INTEGER ]]]

168

Extending the basic notion of class

LIST_OF_CARS

SET_OF_CARS

LINKED_LIST_OF_CARS

LIST_OF_CITIES

LIST_OF_PERSONS

LINKED_LIST_OF_CITIES

SET_OF_PERSONS

Genericity

Inheritance

169

Genericity + inheritance 2: Polymorphic data structures

figs : LIST [FIGURE ]p1, p2 : POLYGONc1, c2 : CIRCLEe : ELLIPSE

(POLYGON) (CIRCLE) (POLYGON)(CIRCLE) (ELLIPSE)

class LIST [G ] featureextend (v : G) do

… endlast : G…

end

figs.extend (p1 ) ; figs.extend (c1 ) ; figs.extend (c2 )

figs.extend (e ) ; figs.extend (p2 )

170

Combining abstractions

Given the classes

TRAIN_CAR, RESTAURANT

how would you implement a DINER ?

171

Examples of multiple inheritance

Combining separate abstractions:

Restaurant, train car Calculator, watch Plane, asset Home, vehicle Tram, bus

172

Composite figures

173

Multiple inheritance: Composite figures

A composite figure

Simple figures

174

Defining the notion of composite figure

COMPOSITE_FIGURE

centerdisplayhiderotatemove…

countputremove…

FIGURELIST

[FIGURE ]

175

In the overall structure

COMPOSITE_FIGURE

FIGURELIST [FIGURE ]

OPEN_FIGURE

CLOSED_FIGURE

SEGMENT POLYLINE POLYGON ELLIPSE

RECTANGLE

SQUARE

CIRCLE

TRIANGLE

perimeter+

perimeter*

perimeter++

diagonal

perimeter++

perimeter++

perimeter+

176

A composite figure as a list

Cursor

item

forth

after

177

Composite figures

class COMPOSITE_FIGURE inheritFIGURE

LIST [FIGURE]feature

display-- Display each constituent figure in turn.

dofrom start until after loop

item.display

forth endend... Similarly for move, rotate etc. ...

end

Requires dynamic binding

178

Multiple inheritance: Combining abstractions

COMPARABLE NUMERIC

STRING COMPLEX

INTEGER

REAL

<, <=, >, >=, …

+, –, *, / …(total order

relation)(commutative ring)

179

Renaming

‘‘Graphical’’ features: height, width, change_height, change_width, xpos, ypos, move...‘‘Hierarchical’’ features: superwindow, subwindows, change_subwindow, add_subwindow...

class WINDOW inheritRECTANGLETREE [WINDOW]

renameparent as superwindow,children as subwindows,add_child as add_subwindow…

endfeature

...end

BUT: see style rules about

uniformity of feature names

180

- 5 -

Some newdevelopments

181

Some recent developments

Void safety

Automatic testing

Concurrency

182

Basic O-O operation…

x.f (args)

… and basic issue studied here:

(If not, call produces an exception and usually termination)

Semantics: apply the feature f, with given args if any, to the object to which x is attached

How do we guarantee that x will always be “attached” to an object?

183

Void safety: requirements

Statically, completely void safe: no exceptions

Handles genericity

Simple for programmer, no mysterious rules

Reasonably simple for compiler

Compatibility or minimum change for existing

code

(Plus for me: 1st semester teachability)

184

Components of the solution

1. Some patterns guaranteed void-safe(“Certified Attachment Patterns” or CAPS)

2. Void value permitted only for types declared as “detachable”. By default types are “attached”

3. Initialization rules ensure that any variable of an attached type has a non-void initialization value

4. Special rules for arrays

185

Automatic testing

Two tools: AutoTest: takes a set of classes and tests them

automatically (push-button, no manual test cases, no test oracles, nothing…)

CDD (Contract-Driven Development): automatically extracts test cases from execution failures

Integrated into EiffelStudio 6.3 and 6.4

186

Caveat

I am mostly talking about:

Functional testing

Unit testing

187

What is testing about?

To test a software system is to try to make it fail

Testing is none of:Ensuring software qualityAssessing software

qualityDebugging

(Terminology: failure, fault, mistake)Fiodor Chaliapineas Mephistopheles

“Ich bin der Geist, der stets verneint”

Goethe, Faust, Act I

188

1. To test a program is to try tomake it fail

2. Tests are no substitute forspecifications

3. Any failed execution must yield a test case, to remain forever remain part of the regression test base

4. Determining success or failure (oracles) must be automatic

4’: Oracles should be part of the program, as contracts5. A test suite must include both manual and automated cases6. Don’t believe your testing insights: evaluate any testing

strategy through objective criteria7. The most important criterion is number of faults found against

time: fc (t)

Seven principles of software testing

Bertrand Meyer, Seven Principles of Software Testing, IEEE Computer, August 2008

189189

“Automated testing”

What can be automated: Test suite execution Resilience Regression testing Test case generation Test result verification (oracles) Test case minimization

190190

Contracts for testing

Contracts provide the right basis: A fault is a discrepancy between intent and reality Contracts describe intent

A contract violation always signals a fault: Precondition: in client Postcondition or invariant: in routine (supplier)

In EiffelStudio: select compilation option for contract monitoring at level of class, cluster or system.

191

AutoTest: automatic test framework

Input: set of classes + testing time Generates instances, calls routines with

automaticallyselected arguments

Oracles are contracts: Direct precondition violation: skip Postcondition/invariant violation: bingo!

Value selection: Random+ (use special values such as 0, +/-1, +/-10, max and min)

Add manual tests if desired Any test (manual or automated) that fails becomes

part of the test suite

Ilinca CiupaAndreas Leitner

(SOFSEM 2007 etc.)

192

Minimization through dynamic slicing

auto_test system.ace –t 120 ACCOUNT CUSTOMER

create {STRING} v1

v1.wipe_out

v1.append_character (’c’)

v1.append_double (2.45)create {STRING} v2

v1.append_string (v2)

v2.fill (’g’, 254343)...create {ACCOUNT} v3.make (v2)v3.deposit (15)

v3.deposit (100)

v3.deposit (-8901)...

classACCOUNT

createmake

featuremake (n :

STRING)

require

n /= Void

do

name := n

balance := 0

ensure

name = n

balance = 0end

name : STRING

balance : INTEGERdeposit (v : INTEGER) do

balance := balance + v

ensure balance = old balance + v

endinvariant name /= Void balance >= 0end

193193

AutoTest strategies

Object pool Get objects through creation procedures

(constructors) Diversify through procedures

Routine arguments Basic values: heuristics for each type

Objects: get from pool

Test all routines, including inherited ones (“Fragile base class” issue)

194

Random testing: example bug found

*SET

**

+SET1

+SET2

+ +

Test:s1, s2 : SETs2 s1

*: Deferred +: Effective

Bernd Schoeller

195

195

Some AutoTest results (random strategy)

Library Total Failed Total Failed

EiffelBase (Sep 2005) 40,000 3% 2000 6%

Gobo Math 1500 1% 140 6%

TESTS ROUTINES

196

Testing results and strategy

“Smart” ideas not always better

Don’t believe your intuitionMeasure and assess

objectively

fc (t)

Class STRING

Define good assessment criteria: Number of faults found Time to find all faults

Time

Experimental law:

fc (t ) = a – b / t

197

Fault categories

Specification faults -- examples: Precondition:

Missing non-voidness precondition (will go away) Missing min-max precondition Too strong precondition

Postcondition: Missing Wrong

Implementation faults -- examples: Faulty supplier Missing implementation Case not treated Violating a routine’s precondition Infinite loop

198

Who finds what faults?

On a small EiffelBase subset,we compared:

AutoTest Manual testing (students) (3 classes, 2 with bugs

seeded) User reports from the field

AutoTest: 62% specification, 38% implementationUser reports: 36% specification, 64% implementation

I.Ciupa, A. Leitner,M.Oriol, A. Pretschner

(submitted)

199

AutoTest vs manual testers

On three classes (two with seeded bugs): Humans found 14 faults, AutoTest 9 of them AutoTest found 2 faults that humans did not (in

large class) 3 faults not found by AutoTest found by 60% of

humans (one is infinite loop) 2 faults not found by AutoTest are missing

preconditions (void, min-max)

200

AutoTest vs user reports

On 39 EiffelBase classes: AutoTest found 85 faults,

Plus 183 related to RAW_FILE,PLAIN_TEXT_FILE, DIRECTORY (total 268)

4 of these also reported by users 21 faults solely reported by users 30% of AutoTest-found bugs related to extreme values;

users never report them

AutoTest finds only 1 out of 18 (5%) of implementation faults and 3 out of 7 specification faults

AutoTest bad at over-strong preconditions, wrong operator semantics, infinite loops, missing implementations

Users never find faulty suppliers (blame on client)

201

AutoTest developments

Large-scale extensive tests, empirical assessment of criteria & strategies

Comparison with manual efforts Complete integration with EiffelStudio IDE Background, unobtrusive, continuous testing Distributed cooperative testing (“Testi@home”)

202

CDD (Contract-Driven Development)

Like Test-Driven Development, but Tests derived from spec (contracts) Not the other way around!

Record every failed execution, make it reproducible by retaining objects

Turn it into a regression test

203

Specified but unimplemented routine

204

Running the system and entering input

(erroneous

)

20

205

Postcondition violated

The violated clause:

balance > old balance

Error caught at run time as contract violation

206

This has become a test case

206

207

Correcting and recompiling

208

One fault corrected, the other not

209

Test tools: lessons

1. Testing should be automatic

2. You need built-in contracts as in Eiffel

3. Testing is one of the tools for verification

4. Testing should be continuous and unobtrusive

210

Concurrency: the SCOOP model

General-purposeMulti-threading, Web services, distribution, multiprogramming...Simplifies concurrent programmingBased on Design by Contract ideas

211

Summary

Bring every one of your development

days

to the level of your best days

212

Gustave Eiffel, 1885

Must it be assumed that because we are engineers beauty is not our concern, and that while we make our constructions robust and durable we do not also strive to make them elegant? Is it not true that the genuine conditions of strength always comply with the secret conditions of harmony?

The first principle of architectural esthetics is that the essential lines of a monument must be determined by a perfect adaptation to its purpose.

Gustave Eiffel, 1887From his response in Le Temps to a petition by members of the literary and artistic Establishment protesting his project of elevating a tower of iron in Paris