eiffel: analysis, design and programming bertrand meyer chair of software engineering
Post on 21-Dec-2015
224 views
TRANSCRIPT
![Page 1: Eiffel: Analysis, Design and Programming Bertrand Meyer Chair of Software Engineering](https://reader036.vdocuments.us/reader036/viewer/2022062320/56649d5e5503460f94a3d796/html5/thumbnails/1.jpg)
Eiffel: Analysis, Design and Programming
Bertrand Meyer
Chair ofSoftware Engineering
![Page 2: Eiffel: Analysis, Design and Programming Bertrand Meyer Chair of Software Engineering](https://reader036.vdocuments.us/reader036/viewer/2022062320/56649d5e5503460f94a3d796/html5/thumbnails/2.jpg)
2
- 6 -
Genericity
![Page 3: Eiffel: Analysis, Design and Programming Bertrand Meyer Chair of Software Engineering](https://reader036.vdocuments.us/reader036/viewer/2022062320/56649d5e5503460f94a3d796/html5/thumbnails/3.jpg)
3
What’s wrong with this code?
class LIST_OF_CARS feature
extend (v: CAR) is …remove (v: CAR) is …item: CAR is …
end
class LIST_OF_CITIES feature
extend (v: CITY) is …
remove (v: CITY) is …
item: CITY is …
end
![Page 4: Eiffel: Analysis, Design and Programming Bertrand Meyer Chair of Software Engineering](https://reader036.vdocuments.us/reader036/viewer/2022062320/56649d5e5503460f94a3d796/html5/thumbnails/4.jpg)
4
What’s wrong with this code?
class LIST_OF_CARS featureappend (other: LIST_OF_CARS)
dofrom other.start until other.after loop Current.extend (other.item)end
endend
class LIST_OF_CITIES featureappend (other : LIST_OF_CITIES)
dofrom other.start until other.after loop Current.extend (other.item)end
endend
DRY Principle: Don’t Repeat Yourself
![Page 5: Eiffel: Analysis, Design and Programming Bertrand Meyer Chair of Software Engineering](https://reader036.vdocuments.us/reader036/viewer/2022062320/56649d5e5503460f94a3d796/html5/thumbnails/5.jpg)
5
Possible approaches for containers
1. Duplicate code, manually or with help of macro processor.
2. Wait until run time; if types don’t match, trigger a run-time failure. (Smalltalk)
3. Convert (“cast”) all values to a universal type, such as “pointer to void” in C.
4. Parameterize the class, giving an explicit name G to the type of container elements. This is the Eiffel approach, now also found in Java (1.5), .NET (2.0) and others.
![Page 6: Eiffel: Analysis, Design and Programming Bertrand Meyer Chair of Software Engineering](https://reader036.vdocuments.us/reader036/viewer/2022062320/56649d5e5503460f94a3d796/html5/thumbnails/6.jpg)
6
Genericity solution to LIST_OF_...
class LIST [G] featureappend (other: LIST [G] ) do
dofrom other.start until other.after
loop Current.extend (other.item)end
endend
city_list: LIST [CITY]car_list: LIST [CAR]
![Page 7: Eiffel: Analysis, Design and Programming Bertrand Meyer Chair of Software Engineering](https://reader036.vdocuments.us/reader036/viewer/2022062320/56649d5e5503460f94a3d796/html5/thumbnails/7.jpg)
7
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
![Page 8: Eiffel: Analysis, Design and Programming Bertrand Meyer Chair of Software Engineering](https://reader036.vdocuments.us/reader036/viewer/2022062320/56649d5e5503460f94a3d796/html5/thumbnails/8.jpg)
8
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
![Page 9: Eiffel: Analysis, Design and Programming Bertrand Meyer Chair of Software Engineering](https://reader036.vdocuments.us/reader036/viewer/2022062320/56649d5e5503460f94a3d796/html5/thumbnails/9.jpg)
9
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)
![Page 10: Eiffel: Analysis, Design and Programming Bertrand Meyer Chair of Software Engineering](https://reader036.vdocuments.us/reader036/viewer/2022062320/56649d5e5503460f94a3d796/html5/thumbnails/10.jpg)
10
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.
![Page 11: Eiffel: Analysis, Design and Programming Bertrand Meyer Chair of Software Engineering](https://reader036.vdocuments.us/reader036/viewer/2022062320/56649d5e5503460f94a3d796/html5/thumbnails/11.jpg)
11
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.)
![Page 12: Eiffel: Analysis, Design and Programming Bertrand Meyer Chair of Software Engineering](https://reader036.vdocuments.us/reader036/viewer/2022062320/56649d5e5503460f94a3d796/html5/thumbnails/12.jpg)
12
Definition: Type
We use types to declare entities, as in
x : SOME_TYPE
With the mechanisms defined so far, a type is one of:
A non-generic class e.g. METRO_STATION
A generic derivation, i.e. the name of a class followed by a list of types, the actual generic parameters, in brackets (also recursive)
e.g. LIST [ARRAY [METRO_STATION ]]
LIST [LIST [CITY ]]TABLE [STRING, INTEGER]
![Page 13: Eiffel: Analysis, Design and Programming Bertrand Meyer Chair of Software Engineering](https://reader036.vdocuments.us/reader036/viewer/2022062320/56649d5e5503460f94a3d796/html5/thumbnails/13.jpg)
13
So, how many types can I possibly get?
Two answers, depending on what we are talking about:
• Static types Static types are the types that we use while writing Eiffel code to declare types for entities (arguments, locals, return values) and when creating new objects without explicitly specifying the type
• Dynamic types Dynamic types on the other hand are created at run-time. Whenever a new object is created, it gets assigned to be of some type.
![Page 14: Eiffel: Analysis, Design and Programming Bertrand Meyer Chair of Software Engineering](https://reader036.vdocuments.us/reader036/viewer/2022062320/56649d5e5503460f94a3d796/html5/thumbnails/14.jpg)
14
Static types
class EMPLOYEEfeature
name: STRINGbirthday: DATE
end
class DEPARTMENTfeature
staff: LIST [EMPLOYEE]end
bound by the program text:EMPLOYEE
STRING
DATE
DEPARTMENT
LIST[G]becomes LIST[EMPLOYEE]
![Page 15: Eiffel: Analysis, Design and Programming Bertrand Meyer Chair of Software Engineering](https://reader036.vdocuments.us/reader036/viewer/2022062320/56649d5e5503460f94a3d796/html5/thumbnails/15.jpg)
15
Object creation, static and dynamic types
class TEST_DYNAMIC _CREATIONfeature
ref_a: A ref_b: B--Let’s suppose B, with creation feature make_b,
--inherits from A, with creation feature make_a
do_somethingdo
create ref_a.make_a-- All that matters is the static type A
create {B} ref_a.make_b-- This is ok, because of the dynamic
type endend
![Page 16: Eiffel: Analysis, Design and Programming Bertrand Meyer Chair of Software Engineering](https://reader036.vdocuments.us/reader036/viewer/2022062320/56649d5e5503460f94a3d796/html5/thumbnails/16.jpg)
16
Dynamic types: another example
class SET[G] feature powerset: SET[SET[G]] is do create Result
-- More computation… end
i_th_power (i: INTEGER): SET[ANY] require i >= 0 local n: INTEGER do Result := Current from n := 1 until n > i loop Result := Result.powerset n := n + 1
end endend __
Dynamic types from i_th_power :
SET[ANY]
SET[SET[ANY]]
SET[SET[SET[ANY]]]
…
From http://www.eiffelroom.com/article/fun_with_generics
![Page 17: Eiffel: Analysis, Design and Programming Bertrand Meyer Chair of Software Engineering](https://reader036.vdocuments.us/reader036/viewer/2022062320/56649d5e5503460f94a3d796/html5/thumbnails/17.jpg)
17
Genericity: summary 1
Type extension mechanism
Reconciles flexibility with type safety
Enables us to have parameterized classes
Useful for container data structures: lists, arrays, trees, …
“Type” now a bit more general than “class”
![Page 18: Eiffel: Analysis, Design and Programming Bertrand Meyer Chair of Software Engineering](https://reader036.vdocuments.us/reader036/viewer/2022062320/56649d5e5503460f94a3d796/html5/thumbnails/18.jpg)
18
Extending the basic notion of class
LIST_OF_CARS
BAG_OF_CARS
LINKED_LIST_OF_CARS
LIST_OF_CITIES
LIST_OF_PERSONS
Abstraction
Specialization
Type parameterization
Type parameterization
Genericity
Inheritance
![Page 19: Eiffel: Analysis, Design and Programming Bertrand Meyer Chair of Software Engineering](https://reader036.vdocuments.us/reader036/viewer/2022062320/56649d5e5503460f94a3d796/html5/thumbnails/19.jpg)
19
The static and the dynamic
For a feature call x.f :
Static typing:There is at least one feature f applicable to x
Dynamic binding:If more than one possible feature,execution will select the right feature
![Page 20: Eiffel: Analysis, Design and Programming Bertrand Meyer Chair of Software Engineering](https://reader036.vdocuments.us/reader036/viewer/2022062320/56649d5e5503460f94a3d796/html5/thumbnails/20.jpg)
20
The static and the dynamic
deferred class ANIMAL featuretalk is
-- Talk, or as least make sound.deferredend
end
class CAT inherit ANIMAL featuretalk is do io.put_string(“Miao”) end
end
class HUMAN inherit ANIMAL featuretalk is do io.put_string(“Hello”) end
end
CAT HUMAN
ANIMAL
![Page 21: Eiffel: Analysis, Design and Programming Bertrand Meyer Chair of Software Engineering](https://reader036.vdocuments.us/reader036/viewer/2022062320/56649d5e5503460f94a3d796/html5/thumbnails/21.jpg)
21
The static and the dynamic
a: ANIMALc: CATh: HUMAN
a := ca.talk
a := ha.talk
CAT HUMAN
ANIMAL
When compiling, type checker checks if there is at least one feature named talk in type ANIMAL, which is the declared type of a.
At run-time, execution will select the right feature to invoke, which will be talk from CAT here.
![Page 22: Eiffel: Analysis, Design and Programming Bertrand Meyer Chair of Software Engineering](https://reader036.vdocuments.us/reader036/viewer/2022062320/56649d5e5503460f94a3d796/html5/thumbnails/22.jpg)
22
More Genericity
Unconstrained
LIST [G]e.g. LIST [INTEGER], LIST [PERSON]
Constrained
HASH_TABLE [G, H ―> HASHABLE ]
VECTOR [G ―> NUMERIC ]
![Page 23: Eiffel: Analysis, Design and Programming Bertrand Meyer Chair of Software Engineering](https://reader036.vdocuments.us/reader036/viewer/2022062320/56649d5e5503460f94a3d796/html5/thumbnails/23.jpg)
23
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
![Page 24: Eiffel: Analysis, Design and Programming Bertrand Meyer Chair of Software Engineering](https://reader036.vdocuments.us/reader036/viewer/2022062320/56649d5e5503460f94a3d796/html5/thumbnails/24.jpg)
24
Adding two vectors
i a b c=+
+ =u v w
1
2
![Page 25: Eiffel: Analysis, Design and Programming Bertrand Meyer Chair of Software Engineering](https://reader036.vdocuments.us/reader036/viewer/2022062320/56649d5e5503460f94a3d796/html5/thumbnails/25.jpg)
25
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
![Page 26: Eiffel: Analysis, Design and Programming Bertrand Meyer Chair of Software Engineering](https://reader036.vdocuments.us/reader036/viewer/2022062320/56649d5e5503460f94a3d796/html5/thumbnails/26.jpg)
26
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.
![Page 27: Eiffel: Analysis, Design and Programming Bertrand Meyer Chair of Software Engineering](https://reader036.vdocuments.us/reader036/viewer/2022062320/56649d5e5503460f94a3d796/html5/thumbnails/27.jpg)
27
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 ]]]
![Page 28: Eiffel: Analysis, Design and Programming Bertrand Meyer Chair of Software Engineering](https://reader036.vdocuments.us/reader036/viewer/2022062320/56649d5e5503460f94a3d796/html5/thumbnails/28.jpg)
28
Enforcing a type: the problem
fl : LINKED_LIST [FIGURE]
fl.store ("FILE_NAME")
...-- Two years later:
fl := retrieved ("FILE_NAME") – See nextx := fl.last -- [1]print (x.diagonal ) -- [2]
What’s wrong with this?
If x is declared of type RECTANGLE, [1] is invalid.If x is declared of type FIGURE, [2] is invalid.
![Page 29: Eiffel: Analysis, Design and Programming Bertrand Meyer Chair of Software Engineering](https://reader036.vdocuments.us/reader036/viewer/2022062320/56649d5e5503460f94a3d796/html5/thumbnails/29.jpg)
29
Object-Test Local
Enforcing a type: the Object Test
if {r : RECTANGLE } fl.last then
print (r.diagonal)
… Do anything else with r, guaranteed
… to be non void and of dynamic type RECTANGLE
elseprint ("Too bad.")
end
Expression to be tested
SCOPE of the Object-Test Local
![Page 30: Eiffel: Analysis, Design and Programming Bertrand Meyer Chair of Software Engineering](https://reader036.vdocuments.us/reader036/viewer/2022062320/56649d5e5503460f94a3d796/html5/thumbnails/30.jpg)
30
Assignment attempt: an older mechanism
x ?= y
with
x : A
Semantics: If y is attached to an object whose type conforms
to A, perform normal reference assignment.
Otherwise, make x void.
![Page 31: Eiffel: Analysis, Design and Programming Bertrand Meyer Chair of Software Engineering](https://reader036.vdocuments.us/reader036/viewer/2022062320/56649d5e5503460f94a3d796/html5/thumbnails/31.jpg)
31
Assignment attempt example
f : FIGUREr : RECTANGLE...
fl.retrieve ("FILE_NAME")
f := fl.last
r ?= f
if r /= Void then
print (r.diagonal)else
print ("Too bad.")end
![Page 32: Eiffel: Analysis, Design and Programming Bertrand Meyer Chair of Software Engineering](https://reader036.vdocuments.us/reader036/viewer/2022062320/56649d5e5503460f94a3d796/html5/thumbnails/32.jpg)
32
More examples on constrained generics
deferred class FIGURE featuredraw is
-- Draw Current figuredeferredend
end
class CIRCLE inherit FIGUREfeature
draw do -- Draw circle.end
end
LINE, RECTANGLE, …
![Page 33: Eiffel: Analysis, Design and Programming Bertrand Meyer Chair of Software Engineering](https://reader036.vdocuments.us/reader036/viewer/2022062320/56649d5e5503460f94a3d796/html5/thumbnails/33.jpg)
33
What about a composite figure?
class COMPOSITE_FIGUREinherit
feature
end
FIGURE
LINKED_LIST [G]
[G -> FIGURE]
draw
do
-- To be finished.
end
![Page 34: Eiffel: Analysis, Design and Programming Bertrand Meyer Chair of Software Engineering](https://reader036.vdocuments.us/reader036/viewer/2022062320/56649d5e5503460f94a3d796/html5/thumbnails/34.jpg)
34
Composite figure
class COMPOSITE_FIGURE [G -> FIGURE] inheritFIGURELINKED_LIST [G]
featuredraw is
dofrom
startuntil
afterloop
item.drawforth
endend
end
![Page 35: Eiffel: Analysis, Design and Programming Bertrand Meyer Chair of Software Engineering](https://reader036.vdocuments.us/reader036/viewer/2022062320/56649d5e5503460f94a3d796/html5/thumbnails/35.jpg)
35
Using FIGURE classes
f : FIGUREc1, c2 : CIRCLEl : LINEcc: COMPOSITE_FIGURE [ CIRCLE ]cf: COMPOSITE_FIGURE [ FIGURE ]
cc.extend (c1)cc.extend (c2)cc.draw
cf.extend (c2)cf.extend (l)cf.draw
![Page 36: Eiffel: Analysis, Design and Programming Bertrand Meyer Chair of Software Engineering](https://reader036.vdocuments.us/reader036/viewer/2022062320/56649d5e5503460f94a3d796/html5/thumbnails/36.jpg)
36
Are we really type safe?
animal_list: LINKED_LIST [ANIMAL]sheep_list: LINKED_LIST [SHEEP]sheep: SHEEP
sheep_list.extend (sheep)animal_list := sheep_list
SHEEP WOLF
ANIMAL
wolf: WOLF
animal_list.extend (wolf)
![Page 37: Eiffel: Analysis, Design and Programming Bertrand Meyer Chair of Software Engineering](https://reader036.vdocuments.us/reader036/viewer/2022062320/56649d5e5503460f94a3d796/html5/thumbnails/37.jpg)
37
CAT calls
CAT stands for Changing Availability or Type
A routine is a CAT if some redefinition changes its export status or the type of any of its arguments
A call is a catcall if some redefinition of the routine would make it invalid because of a change of export status or argument type.
![Page 38: Eiffel: Analysis, Design and Programming Bertrand Meyer Chair of Software Engineering](https://reader036.vdocuments.us/reader036/viewer/2022062320/56649d5e5503460f94a3d796/html5/thumbnails/38.jpg)
38
Catcall cases
• Covariant redefinition• Non-generic case• Generic case
• Descendant hiding
![Page 39: Eiffel: Analysis, Design and Programming Bertrand Meyer Chair of Software Engineering](https://reader036.vdocuments.us/reader036/viewer/2022062320/56649d5e5503460f94a3d796/html5/thumbnails/39.jpg)
39
Covariant redefinition – Nongeneric case
class ANIMAL feature
eat (a_food: FOOD) is deferred … endend
class WOLFinherit ANIMAL redefine eat endfeature
eat (a_meat: MEAT) is do … endend
MEAT GRASS
FOOD
WOLF
ANIMAL
![Page 40: Eiffel: Analysis, Design and Programming Bertrand Meyer Chair of Software Engineering](https://reader036.vdocuments.us/reader036/viewer/2022062320/56649d5e5503460f94a3d796/html5/thumbnails/40.jpg)
40
Covariant redefinition – Nongeneric case
animal: ANIMALwolf: WOLFfood: FOODgrass: GRASS
create wolfcreate grassanimal := wolffood := grassanimal.eat (grass)
MEAT GRASS
FOOD
WOLF
ANIMAL
![Page 41: Eiffel: Analysis, Design and Programming Bertrand Meyer Chair of Software Engineering](https://reader036.vdocuments.us/reader036/viewer/2022062320/56649d5e5503460f94a3d796/html5/thumbnails/41.jpg)
41
Descendant hiding
class RECTANGLE inherit
POLYGON export{NONE} add_vertex endend
feature…
invariantvertex_count = 4
end
RECTANGLE
POLYGON
What will happen?
r: RECTANGLE
p: POLYGON
create r
p := r
p.add_vertex (…)
![Page 42: Eiffel: Analysis, Design and Programming Bertrand Meyer Chair of Software Engineering](https://reader036.vdocuments.us/reader036/viewer/2022062320/56649d5e5503460f94a3d796/html5/thumbnails/42.jpg)
42
Covariant redefinition – Generic case
animal_list: LINKED_LIST [ANIMAL]sheep_list: LINKED_LIST [SHEEP]sheep: SHEEP
sheep_list.extend (sheep)animal_list := sheep_list
SHEEP WOLF
ANIMAL
wolf: WOLF
animal_list.extend (wolf)
![Page 43: Eiffel: Analysis, Design and Programming Bertrand Meyer Chair of Software Engineering](https://reader036.vdocuments.us/reader036/viewer/2022062320/56649d5e5503460f94a3d796/html5/thumbnails/43.jpg)
43
Covariant redefinition – Generic case
class LINKED_LIST [ANY]feature
extend (v: ANY) do … endend
class LINKED_LIST [SHEEP]feature
extend (v: SHEEP) do … endend
class LINKED_LIST [WOLF]feature
extend (v: WOLF) do … endend