eiffel in depth bertrand meyer with material by emmanuel stapf (eiffel software) & members...

212
Eiffel in Depth Bertrand Meyer With material by Emmanuel Stapf (Eiffel Software) & members of the ETH Chair of Software Engineering Chair of Software Engineering

Upload: marina

Post on 25-Feb-2016

27 views

Category:

Documents


1 download

DESCRIPTION

Eiffel in Depth Bertrand Meyer With material by Emmanuel Stapf (Eiffel Software) & members of the ETH Chair of Software Engineering. Chair of Software Engineering. Plan of these slides. 1Overview 2The environment(s) 3 Method overview 4 Language basics 5 Dynamic model - PowerPoint PPT Presentation

TRANSCRIPT

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 courseTo 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 versionsEiffel 1, 1986

Classes, contracts, genericity, single and multiple

inheritance, garbage collection, …Eiffel 2, 1988 (Object-Oriented Software Construction)

Exceptions, constrained genericityEiffel 3, 1990-1992 (Eiffel: The Language)

Basic types as classes, infix & prefix operators…Eiffel 4, 1997

“Precursor” and agentsEiffel 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, EnvironmentMethod :

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 flexibilityDogmatic 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

EiffelBuildGUI 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 Big

change

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 debuggingYou 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++ supportFunctions, macros, include files, setters, getters, constructors, destructors etc.

Inline C

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

24

PortabilitySource-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 lifecycleFeasibility

studyRequirements

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-

tationV&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 modelExample classes:PLANE, ACCOUNT, TRANSACTION…

STATE, COMMAND…

HASH_TABLE…

TEST_DRIVER…

TABLE…

Analysis

Design

Implemen-

tationV&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.require

in_valve.openout_valve.closed

deferredensure

in_valve.closedout_valve.closedis_full

endempty, is_full, is_empty, gauge, maximum,

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

end

33

Single modelUse 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-

tationV&V

Generali-zation

35

GeneralizationPrepare 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 GA *

B

Y *

X Z

T

U

36

The cluster model

AD

I

V

G

Permits dynamic reconfiguration

AD

I

V

G

AD

I

V

G

AD

I

V

G

AD

I

V

G

AD

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 conventionsSemicolon 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

animateappend

An object has an interface

count stations

first last

47

prepend

animateappend

count

first

An object has an implementation

count stations

first last

48

Information hiding

prepend

animateappend

count 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 examplebalance = 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_depositslist_of_withdrawals

list_of_depositslist_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 typex : 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 classclass POINT feature

x, y : REAL-- Cartesian coordinates

move (a, b : REAL)-- Move by a horizontally and b vertically.do x := 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)do

Result := sqrt (x ^ 2 + y ^ 2)end

theta : REAL -- Angle to horizontal axisdo

…end

end

56

Uniform access through feature callTo 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 practiceClass 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_uptodatesame_as_internal : Result = x_internal

end

60

Adding two complex numbers

plus (other : COMPLEX ) -- Add other to current complex number. do

update_cartesianx_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: examplesGraphic 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 )

doif ‘‘f is a CIRCLE’’ then

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

...end

end

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 objectsReference 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 viewNewsgroup 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 collectionManual 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 operatorsIn

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 featuresexpanded class INTEGER feature

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

do ... endtimes alias "*" (other : INTEGER): INTEGER

-- Product by otherdo ... end

minus alias "-" : INTEGER-- Unary minus

do ... end...end

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

75

Assignment commandsIt is possible to define a query as

temperature: REAL assign set_temperature

Then the syntaxx.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 ] + 1Not 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 separationA 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 transparencyIf 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 separationInput 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 libraryDevising 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 interfacesMore relevant than class size for assessing complexity. Statistics from EiffelBase and associated libraries:

Number of features 4408Percentage of queries 66%Percentage of commands 34%Average number of arguments to a feature 0.5Maximum number 5No arguments 57%One argument 36%Two arguments 6%Three or more arguments 1%

92

Operands and optionsTwo 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 operandsTwo 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 PrincipleOnly operands should appear

as 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 rulesAchieve 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 ideaEvery 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 contractThe 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 eurosCause: incorrect conversion of 64-bit real value (“horizontal bias” of the flight) into 16-bit integerSystematic 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): INTEGERrequire

representable (b)do

…ensure

equivalent (b, Result) end

105

The contract view of software constructionConstructing 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 analysisdeferred class VAT inherit

TANKfeature

in_valve, out_valve : VALVE

fill -- Fill the vat.require

in_valve.openout_valve.closed

deferredensure

in_valve.closedout_valve.closedis_full

endempty, is_full, is_empty, gauge, maximum,

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

end

108

A class without contractsclass

ACCOUNTfeature -- 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 operationsdeposit (sum : INTEGER)

-- Deposit sum into the account.do

add (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 contractsclass

ACCOUNT create

make

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

-- Set up account with initial_amount.require

large_enough: initial_amount >= Minimum_balance

dobalance := initial_amount

ensurebalance_set: balance = initial_amount

end

111

Introducing contractsfeature -- 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 contractsfeature -- 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 contractswithdraw (sum : INTEGER)

-- Withdraw sum from the account.require

not_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

dobalance := balance - sum

ensurebalance = old balance - sum

PRESCRIPTIVE DESCRIPTIVEHow?OperationalImplementationCommandInstructionImperative

What?DenotationalSpecificationQueryExpressionApplicative

116

Introducing contractsmay_withdraw (sum : INTEGER ): BOOLEAN

-- Is it permitted to withdraw sum from account?

doResult := (balance - sum >=

Minimum_balance)end

invariantnot_under_minimum: balance >= Minimum_balance

end

117

The class invariantConsistency 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_depositslist_of_withdrawals

200 100 500 1000

800 100 100

(A2)200 300 500 1000

800 100 100

list_of_depositslist_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 caseFor 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 assurancePrecondition violation: Bug in the client.Postcondition violation: Bug in the supplier.Invariant violation: Bug in the supplier.

{P } A {Q }

123

Contracts: run-time effectCompilation options (per class, in Eiffel):

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

124

Contracts for testing and debuggingContracts 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 typesPreconditions 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 assuranceUse 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 assuranceContracts 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, interfaceFlat 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 formsDocumentation, manualsDesignCommunication between developersCommunication between developers and managers

138

Contracts and inheritanceIssues: what happens, under inheritance, to

Class invariants?

Routine preconditions and postconditions?

139

InvariantsInvariant 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

Client Inheritance ++ Redefinition

141

Assertion redeclaration ruleWhen 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 toolHigh-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 benefitsLibrary 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

SQUARECIRCLE

side

*

**

148

Redefinition 1: polygonsclass POLYGON inherit

CLOSED_FIGUREcreate

makefeature

vertex : 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: rectanglesclass RECTANGLE inherit

POLYGONredefine

perimeter end

createmake

featurediagonal, side1, side2 : REALperimeter : REAL

-- Perimeter lengthdo Result := 2 * (side1 + side2) end

invariant

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 then

p := relse

p := tendx := p.perimeter

Redefinition: A class may change an inherited feature, as with POLYGON redefining perimeterPolymorphism: 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 )

doif ‘‘f is a CIRCLE’’ then

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

...end

end

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

UnconstrainedLIST [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?

pc

159

A generic class

class LIST [G ] featureextend (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 derivationscities : LIST [CITY ]people : LIST [PERSON]c : CITYp : PERSON...

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

c := cities.lastc. some_city_operation

STATIC TYPINGThe 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 genericityLIST [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.lowerupper = other.upper

locala, b, c: G

do... See next ...

end... Other features ...

end

164

Adding two vectors

i a b c=+

+ =u v w

12

165

Constrained genericity

Body of plus alias "+":

create Result.make (lower, upper)from

i := lower until

i > upper loop

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

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

end

166

The solutionDeclare 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 abstractionsGiven the classes

TRAIN_CAR, RESTAURANT

how would you implement a DINER ?

171

Examples of multiple inheritanceCombining 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

FIGURE LIST [FIGURE ]

OPEN_FIGURE

CLOSED_FIGURE

SEGMENT POLYLINE POLYGON ELLIPSE

RECTANGLE

SQUARE

CIRCLETRIANGLE

perimeter+

perimeter*

perimeter++

diagonal

perimeter++

perimeter++

perimeter+

176

A composite figure as a list

Cursor

item

forth

after

177

Composite figures

class COMPOSITE_FIGURE inheritFIGURELIST [FIGURE]

featuredisplay

-- Display each constituent figure in turn.do

from 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 developmentsVoid 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 solution1. 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 testingTwo 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

CaveatI 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 automatic4’: Oracles should be part of the program, as contracts

5. 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 testingContracts 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 slicingauto_test system.ace –t 120 ACCOUNT CUSTOMER

create {STRING} v1v1.wipe_outv1.append_character (’c’)v1.append_double (2.45)create {STRING} v2v1.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 : STRINGbalance : 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

betterDon’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 categoriesSpecification 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 testersOn 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 reportsOn 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: lessons1. 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 modelGeneral-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