49
Chair of Software Engineering Avoid a void Bertrand Meyer ©Bertrand Meyer, 2008

Chair of Software Engineering Avoid a void Bertrand Meyer ©Bertrand Meyer, 2008

  • View
    222

  • Download
    0

Embed Size (px)

Citation preview

Page 1: Chair of Software Engineering Avoid a void Bertrand Meyer ©Bertrand Meyer, 2008

Chair of Software Engineering

Avoid a void

Bertrand Meyer

©Bertrand Meyer, 2008

Page 2: Chair of Software Engineering Avoid a void Bertrand Meyer ©Bertrand Meyer, 2008

2

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?

Page 3: Chair of Software Engineering Avoid a void Bertrand Meyer ©Bertrand Meyer, 2008

3

Other problems solved by this work

A consistent approach to type casts

A better way to do “once per object”

A consistent approach to object locking in concurrent programming

Page 4: Chair of Software Engineering Avoid a void Bertrand Meyer ©Bertrand Meyer, 2008

4

The context

ECMA standard for Eiffel

Approved June 2005, 2nd edition, June 2006

ISO standard, November 2006

Mechanism described here is in EiffelStudio 6.1, Nov 2007

Page 5: Chair of Software Engineering Avoid a void Bertrand Meyer ©Bertrand Meyer, 2008

5

“If and only if” language specification

Page 6: Chair of Software Engineering Avoid a void Bertrand Meyer ©Bertrand Meyer, 2008

6

References

Useful to describe linked data structures

Can be void!

“Almaviva”name

landlord

loved_one

O1

“Figaro”O2

“Susanna”

O3

Zurich Pisa Piombino Biodola

item right item right item right item right

Page 7: Chair of Software Engineering Avoid a void Bertrand Meyer ©Bertrand Meyer, 2008

7

References are a conceptual modeling tool

Difference betweenEach car has an engineEach car has a manufacturer

(e.g. Fiat, Renault)

Page 8: Chair of Software Engineering Avoid a void Bertrand Meyer ©Bertrand Meyer, 2008

8

A success story: static type checking

We allow

x.f (args)

only if we can guarantee that at run time:The object attached to x, if it exists, has a feature for f, able to handle the args.

Basic ideas:Accept it only if type of x has a feature fAssignment x := y requires conformance (based

on inheritance)

What if x is void?

Page 9: Chair of Software Engineering Avoid a void Bertrand Meyer ©Bertrand Meyer, 2008

9

Can we extend static type checking?

Our goal (“void safety”): at compile time, allow

x.f (args)

only if we can guarantee that at run time:

x is not void.

Page 10: Chair of Software Engineering Avoid a void Bertrand Meyer ©Bertrand Meyer, 2008

10

Requirements on an acceptable solution

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)

Page 11: Chair of Software Engineering Avoid a void Bertrand Meyer ©Bertrand Meyer, 2008

11

Key influence

“Spec# stipulates the inference of non-[voidness] for local variables. This inference is performed as a dataflow analysis by the Spec# compiler.”

(Barnett, Leino, Schulte, Spec# paper)

x /= Void

Page 12: Chair of Software Engineering Avoid a void Bertrand Meyer ©Bertrand Meyer, 2008

12

Source: Patrice Chalin

44.4% of Eiffel preconditions clauses are of the form

x /= Void

Page 13: Chair of Software Engineering Avoid a void Bertrand Meyer ©Bertrand Meyer, 2008

13

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. Rule for generic parameters

Page 14: Chair of Software Engineering Avoid a void Bertrand Meyer ©Bertrand Meyer, 2008

14

Rule 1: Target Validity Rule

x.f (args) is permitted only if x is

attached

“Attached” is a static property. x is attached if either:

Its type is attached

Its type is not attached, but x itself is guaranteed attached in a specific context

Page 15: Chair of Software Engineering Avoid a void Bertrand Meyer ©Bertrand Meyer, 2008

15

An interesting pattern

Consider a variable or expression exp

Can this be guaranteed void-safe?

if exp /= Void then

exp.operationend

Answer: only if exp is a local variable! (or formal argument)Not for an attribute, or a general expression.

other_instructions(args)

(Assume exp is a variable)

not assigning to exp

Page 16: Chair of Software Engineering Avoid a void Bertrand Meyer ©Bertrand Meyer, 2008

16

Attached entity: Case #1

x is attached if used as part of a Certified Attachment Pattern (CAP).

This is a CAP for x

Example CAP for a local variable or formal argument x:

if x /= Void then… Any instructions not assigning to x …… (except possibly last instruction) …

end

Page 17: Chair of Software Engineering Avoid a void Bertrand Meyer ©Bertrand Meyer, 2008

17

Rule 1: Target Validity Rule

x.f (args) is permitted only if x is

attached

Ways to ensure that x is attached:

1. Use it in a Certified Attachment Pattern

Page 18: Chair of Software Engineering Avoid a void Bertrand Meyer ©Bertrand Meyer, 2008

18

A loop CAP

from...

untilx = Void

loop... Any instructions not assigning to x ...… (except possibly last instruction) …

end

x must again be a local variable or a formal argument!

A CAP for x

Page 19: Chair of Software Engineering Avoid a void Bertrand Meyer ©Bertrand Meyer, 2008

19

A typical loop, now safe

fromx := first_element

untilx = Void or else Result

loopResult := (x.item = sought)

x := x.right

end

Zurich Piombino Biodola

item right item right item right

first_element

Page 20: Chair of Software Engineering Avoid a void Bertrand Meyer ©Bertrand Meyer, 2008

20

The CAP catalog

About 6 CAPs specified in the ECMA standard. Above two are the most important.

Another example: x in

x /= Void implies x.some_property

Criterion: simple; easy to understand; provably and obviously correct

Need to be approved by committeeMathematical, machine-checked proofs desirable

Page 21: Chair of Software Engineering Avoid a void Bertrand Meyer ©Bertrand Meyer, 2008

21

When no CAP applies: the Object Test

Not void-safe:

if exp /= Void then

… Various instructions …

exp.operation

… Other instructions …

end

Page 22: Chair of Software Engineering Avoid a void Bertrand Meyer ©Bertrand Meyer, 2008

22

When no CAP applies: the Object Test

Previous scheme made void-safe!

if {x : T } exp then -- T is the type of exp

… Various instructions, anything OK! …

x .operation

… Other instructions …

end

Scope of x

Karine ArnoutÉric Bezault

Bezault

Page 23: Chair of Software Engineering Avoid a void Bertrand Meyer ©Bertrand Meyer, 2008

23

The Object Test

{x: T } exp

exp is an arbitrary expression x is a fresh variable, read-only (like formal argument)

It’s a boolean expression: true if value of exp is attached to object of type T or conforming

Binds x to that value over scope of expression

Page 24: Chair of Software Engineering Avoid a void Bertrand Meyer ©Bertrand Meyer, 2008

24

Object Test example

if {x : T } exp then -- T is the type of exp

… Various instructions, anything OK! …

x .operation

… Other instructions …

end

Scope of x

Page 25: Chair of Software Engineering Avoid a void Bertrand Meyer ©Bertrand Meyer, 2008

25

Scope of x

Another example of Object Test scope

from…

until not {x: T } exp loop

… Various instructions, anything OK! …

x.operation_of_T

… Other instructions …

end

Page 26: Chair of Software Engineering Avoid a void Bertrand Meyer ©Bertrand Meyer, 2008

26

Rule 1: Target Validity Rule

x.f (args) is permitted only if x is

attached

Ways to ensure that x is attached:

1. Use it in a Certified Attachment Pattern

2. Use it in the scope of an Object Test

Page 27: Chair of Software Engineering Avoid a void Bertrand Meyer ©Bertrand Meyer, 2008

27

Another example of Object Test

if {e: EMPLOYEE } database.retrieved then

… Various instructions, anything OK! …

e.print_paycheck

… Other instructions …end

Replaces “assignment attempt” of current Eiffel, and various “type narrowing”, “Run-Time Type Identification”, “downcasting” mechanisms

Page 28: Chair of Software Engineering Avoid a void Bertrand Meyer ©Bertrand Meyer, 2008

28

The remaining goal…

Minimize use of Object Test!

General but impractical solution: protect every qualified feature call by an Object Test!

Instead of

exp .operationwrite

if {x : T } exp then x .operation

end

Page 29: Chair of Software Engineering Avoid a void Bertrand Meyer ©Bertrand Meyer, 2008

29

Attached and detachable types

For any type T, a variable declared as just

x : T

cannot be void!Type T is attached

To allow void values, declare

x : ?TType ?T is detachable

Page 30: Chair of Software Engineering Avoid a void Bertrand Meyer ©Bertrand Meyer, 2008

30

Rule 1: Target Validity Rule

x.f (args) is permitted only if x is

attached

Ways to ensure that x is attached:

1. Use it in a Certified Attachment Pattern

2. Use it in the scope of an Object Test

3. Give it an attached type

Page 31: Chair of Software Engineering Avoid a void Bertrand Meyer ©Bertrand Meyer, 2008

31

The remaining problem…

How to ensure that variables declared of an attached type

x : T

meet that declaration, i.e. can never become void!

Page 32: Chair of Software Engineering Avoid a void Bertrand Meyer ©Bertrand Meyer, 2008

32

Rule 2: Conservation of attachment

Inx := y

orr (y) -- Where formal argument is x

if type of x is attached, y must be attached.

(No “traitors”, see SCOOP.)

Page 33: Chair of Software Engineering Avoid a void Bertrand Meyer ©Bertrand Meyer, 2008

33

If assignment & argument passing are OK…

… there remains initialization!

Page 34: Chair of Software Engineering Avoid a void Bertrand Meyer ©Bertrand Meyer, 2008

34

The initialization problem

In previous Eiffel:

Basic types initialized to standard values (zero, False, null character)

Other expanded types must have default_create from ANY

References initialized to Void

Page 35: Chair of Software Engineering Avoid a void Bertrand Meyer ©Bertrand Meyer, 2008

35

Initializing variables

An attribute is attached if every creation procedure sets it.

A local variable is initialized if the beginning of the routine sets it.

Scheme 1: CAP

Page 36: Chair of Software Engineering Avoid a void Bertrand Meyer ©Bertrand Meyer, 2008

36

The initialization problem

In previous Eiffel:

Basic types initialized to standard values (zero, False, null character)

Other expanded types must have default_create from ANY

References initialized to Void

Page 37: Chair of Software Engineering Avoid a void Bertrand Meyer ©Bertrand Meyer, 2008

37

Initializing variables

Scheme 1: CAPScheme 2: Properly set variables

Page 38: Chair of Software Engineering Avoid a void Bertrand Meyer ©Bertrand Meyer, 2008

38

Properly set variables

At any place where it is accessed, a variable must be properly set

Page 39: Chair of Software Engineering Avoid a void Bertrand Meyer ©Bertrand Meyer, 2008

39

Properly set variables

ep is not in a creation-reachable routine,

and x is

Page 40: Chair of Software Engineering Avoid a void Bertrand Meyer ©Bertrand Meyer, 2008

40

Initializing variables

What if an attribute is not set by creation procedures?

Scheme 1: CAPScheme 2: Properly set variables Scheme 3: Self-initializing attributes

Page 41: Chair of Software Engineering Avoid a void Bertrand Meyer ©Bertrand Meyer, 2008

41

Digression: attributes (fields/data members)

bounding_rectangle: RECTANGLE-- Smallest rectangle including whole of current

figure

Page 42: Chair of Software Engineering Avoid a void Bertrand Meyer ©Bertrand Meyer, 2008

42

Digression: attributes with contracts!

bounding_rectangle: RECTANGLE-- Smallest rectangle including whole of current

figure

requirebounded

attribute

ensureResult.height = heightResult.width = widthResult.lower_left = lower_leftResult.contains (Current)

end

Page 43: Chair of Software Engineering Avoid a void Bertrand Meyer ©Bertrand Meyer, 2008

43

Self-initializing attributes

bounding_rectangle: FIGURE-- Smallest rectangle including whole of current

figure-- (Computed only if needed)

requirebounded

attributecreate Result.set (lower_left, width, height)

ensureResult.height = heightResult.width = widthResult.lower_left = lower_leftResult.contains (Current)

end

… As before …

Page 44: Chair of Software Engineering Avoid a void Bertrand Meyer ©Bertrand Meyer, 2008

44

Another example: once per object

class STOCKS feature

db: DATABASE

history (ts: TICKER_SYMBOL): HISTORY-- List of previous valuations of ts

attributeif {h: HISTORY} db.retrieved (ts) then

Result := helse

create Result -- Produces empty list

endend

end

Page 45: Chair of Software Engineering Avoid a void Bertrand Meyer ©Bertrand Meyer, 2008

45

Initializing variables

In class C [G ], what about the initialization of

x : G ?

Scheme 1: CAPScheme 2: Properly set variablesScheme 3: Self-initializing attributesScheme 4: Variables of formal generic type

Example generic derivations:

C [INTEGER ]

C [EMPLOYEE ]

Page 46: Chair of Software Engineering Avoid a void Bertrand Meyer ©Bertrand Meyer, 2008

46

Genericity: the issue

class ARRAY [G] featureitem alias “[]” (i : INTEGER): Gput (x : G ; i : INTEGER)…

end

a: ARRAY [INTEGER]

x := a [i ] -- Means a.item (i)a [ j ] := y -- Means a.put (y, j )

a: ARRAY [SOME_TYPE]

x := a.item (i)a.put (y, j )

i

j

?

How can class ARRAY initialize the entries properly without knowing what G is?

a

(y)

Page 47: Chair of Software Engineering Avoid a void Bertrand Meyer ©Bertrand Meyer, 2008

47

Genericity

In a class C [G], if the implementation accesses an attribute

x : G

that is not guaranteeably attached (through a CAP, or self-initialization), then the class must be declared as

C [? G] -- For example: ARRAY [? G]

Then any actual parameter (T in C [T]) must be detachable

Page 48: Chair of Software Engineering Avoid a void Bertrand Meyer ©Bertrand Meyer, 2008

48

Initializing variables

Scheme 1: CAPScheme 2: Properly set variablesScheme 3: Self-initializing attributesScheme 4: Variables of formal generic type

Page 49: Chair of Software Engineering Avoid a void Bertrand Meyer ©Bertrand Meyer, 2008

49

Requirements on an acceptable solution

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

(+ for me: the “Week 6 of Einführung in die Programmierung”

criterion)