SlideShare une entreprise Scribd logo
1  sur  67
Télécharger pour lire hors ligne
The Expression Problem
Prof. Dr. Ralf Lämmel
Universität Koblenz-Landau
Software Languages Team
(C) 2010-2013 Ralf Lämmel
Elevator speech
Suppose you have some data variants (say
“apples” and “oranges”) and you have some
operations on such data (say “drink” and
“squeeze”), how would you go about the design of
data and operations so that you can hopefully add
new data variants and new operations later on?
21
(C) 2010-2013 Ralf Lämmel
Expression problem:
Why the name?
• Consider such data:
– Expressions as in programming languages:
– Literals
– Addition
– …
• Consider such operations:
– Pretty print expressions
– Evaluate expressions
– …
• Consider such extension scenarios:
– Add another expression form
• Cases for all existing operations must be added.
– Add another operation
• Cases for all existing expression forms must be added.
22
The name goes back to Phil Wadler who
defined the expression problem in an
email sent to mailing lists and individuals
in November 1998.
(C) 2010-2013 Ralf Lämmel
Expression problem:
What problem?
• In basic OO programming:
– It is easy to add new data variants.
– It is hard to add new operations.
23
(C) 2010-2013 Ralf Lämmel
Data extensibility based on simple inheritance
• class Expr:The base class of all expression forms
• Virtual methods:
• method prettyPrint: operation for pretty-printing
• method evaluate: operation for expression evaluation
• Subclasses:
• class Lit:The expression form of "literals"
• class Add:The expression form of "addition"
• ... Data extensibility
24
(C) 2010-2013 Ralf Lämmel
/**
* The base class of all expression forms
*/
public abstract class Expr {
	
	 /*
	 * Operation for pretty printing
	 */
	 public abstract String prettyPrint();
	
	 /*
	 * Operation for expression evaluation
	 */
	 public abstract int evaluate();
}
Beware
of code bloat!
25
The class rooting all
data variants
(C) 2010-2013 Ralf Lämmel
/**
* The expression form of "literals" (i.e., constants)
*/
public class Lit extends Expr {
	 private int info;
	 public int getInfo() { return info; }
	 public void setInfo(int info) { this.info = info; }
	
	 public String prettyPrint() {
	 	 return Integer.toString(getInfo());
	 }
	
	 public int evaluate() {
	 	 return getInfo();
	 }
}
Beware
of code bloat!
26
A class for a data variant
(C) 2010-2013 Ralf Lämmel
/**
* The expression form of "addition"
*/
public class Add extends Expr {
	
	 private Expr left, right;
	 public Expr getLeft() { return left; }
	 public void setLeft(Expr left) { this.left = left; }	
	 public Expr getRight() { return right; }
	 public void setRight(Expr right) { this.right = right; }
	
	 public String prettyPrint() { ... }
	
	 public int evaluate() {
	 	 return getLeft().evaluate() + getRight().evaluate();
	 }
}
That is, another data
variant but with the
same operations.
Beware
of code bloat!
27
(C) 2010-2013 Ralf Lämmel
/**
* The expression form of "negation"
*/
public class Neg extends Expr {
	
	 private Expr expr;
	 public Expr getExpr() { return expr; }
	 public void setExpr(Expr expr) { this.expr = expr; }
	
	 public String prettyPrint() {
	 	 return "-(" + getExpr().prettyPrint() + ")";
	 }
	
	 public int evaluate() {
	 	 return - getExpr().evaluate();
	 }
}
That is, yet another data
variant but, again, with
the same operations.
Beware
of code bloat!
28
(C) 2010-2013 Ralf Lämmel
Expression problem:
What problem?
• In basic OO programming:
– It is easy to add new data variants.
– It is hard to add new operations.
• In OO programming with instance-of / cast:
– It is easy to add new operations.
– It is easy to add new data variants.
29
But
beware of
programming
errors
(C) 2010-2013 Ralf Lämmel
Full (?) extensibility based on
instance-of tests and type casts
• We use instanceof tests and casts to dispatch functionality on data.
• We use a specific exception and try-catch blocks to extend operations.
• We encapsulate operations in objects so that extensions are self-aware.
• This is approach is weakly typed.
• In particular, there is no guarantee that we have covered all cases.
30
(C) 2010-2013 Ralf Lämmel
public abstract class Expr { }
public class Lit extends Expr {	
	 private int info;
	 public int getInfo() { return info; }
	 public void setInfo(int info) { this.info = info; }
}
public class Add extends Expr {
	 private Expr left, right;
	 public Expr getLeft() { return left; }
	 public void setLeft(Expr left) { this.left = left; }	
	 public Expr getRight() { return right; }
	 public void setRight(Expr right) { this.right = right; }	
}
Domain classes are
nothing but data
capsules.
31
(C) 2010-2013 Ralf Lämmel
public class EvaluatorBase {
	 public int evaluate(Expr e) {
	 	 if (e instanceof Lit) {
	 	 	 Lit l = (Lit)e;
	 	 	 return l.getInfo();
	 	 }
	 	 if (e instanceof Add) {
	 	 	 Add a = (Add)e;
	 	 	 return evaluate(a.getLeft()) + evaluate(a.getRight());
	 	 }	 	
	 	 throw new FallThrouhException();
	 }
}
We simulate pattern
matching by instanceof
and cast.
We anticipate failure of
such operations as a
means to compose
them.
32
(C) 2010-2013 Ralf Lämmel
public class EvaluatorExtension
extends EvaluatorBase {
	 public int evaluate(Expr e) {
	 	 try {
	 	 	 return super.evaluate(e);
	 	 }
	 	 catch (FallThrouhException x) {
	 	 	 if (e instanceof Neg) {
	 	 	 	 Neg n = (Neg)e;
	 	 	 	 return -evaluate(n.getExpr());
	 	 	 }	 	
	 	 	 throw new FallThrouhException();	
	 	 }
	 }
} Recursive calls are
properly dispatched
through “this” to the
extended operation.
An extended operation
first attempts the basic
implementation.
33
(C) 2010-2013 Ralf Lämmel
Expression problem:
What problem?
• In basic OO programming:
– It is easy to add new data variants.
– It is hard to add new operations.
• In OO programming with visitors:
– It is easy to add new operations.
– It is hard to add new data variants.
• In OO programming with instance-of / cast:
– It is easy to add new operations.
– It is easy to add new data variants.
34
Forthcoming!
(C) 2010-2013 Ralf Lämmel
Operation extensibility based on visitors
PREVIEW
• class Expr:The base class of all expression forms
• Subclasses as before.
• Virtual methods:
• Accept a visitor (“apply an operation”)
• Visitors:
• class PrettyPrinter: operation for pretty-printing
• class Evaluator: operation for expression evaluation
• ... Operation extensibility
35
The Visitor Pattern
(C) 2010-2013 Prof. Dr. Ralf Lämmel, Universität Koblenz-Landau (where applicable)
A book recommendation
(C) 2010-2013 Prof. Dr. Ralf Lämmel, Universität Koblenz-Landau (where applicable)
Elevator speech
Q: How can we add functionality to a
given (perhaps even closed) class
hierarchy such that behavior can vary
across concrete classes?
A: Represent an operation to be
performed on the elements of an
object structure in a class separate
from the given classes.
(C) 2010-2013 Prof. Dr. Ralf Lämmel, Universität Koblenz-Landau (where applicable)
Adding an operation to lists
interface List {}
class Nil implements List {}
class Cons implements List {
int head;
List tail;
}
Now suppose we need functionality
to compute the sum of a list.
(C) 2010-2013 Prof. Dr. Ralf Lämmel, Universität Koblenz-Landau (where applicable)
1st attempt:
instance-of and type cast
List l = ...;
int sum = 0; // contains the sum after the loop
boolean proceed = true;
while (proceed) {
if (l instanceof Nil)
proceed = false;
else if (l instanceof Cons) {
sum = sum + ((Cons) l).head; // Type cast!
l = ((Cons) l).tail; // Type cast!
}
}
What are the
problems here?
(C) 2010-2013 Prof. Dr. Ralf Lämmel, Universität Koblenz-Landau (where applicable)
1st attempt:
instance-of and type cast
Casts are evil!
Requirement:
static type checking
http://en.wikipedia.org/wiki/File:Codex_Gigas_devil.jpg
(C) 2010-2013 Prof. Dr. Ralf Lämmel, Universität Koblenz-Landau (where applicable)
2nd attempt:
virtual methods
What are the
problems here?
interface List {
int sum();
}
class Nil implements List {
public int sum() { return 0; }
}
class Cons implements List {
int head;
List tail;
public int sum() {
return head + tail.sum();
}
}
(C) 2010-2013 Prof. Dr. Ralf Lämmel, Universität Koblenz-Landau (where applicable)
2nd attempt:
virtual methods
Patching is evil!
Requirement:
operation extensibility
http://en.wikipedia.org/wiki/File:Codex_Gigas_devil.jpg
(C) 2010-2013 Prof. Dr. Ralf Lämmel, Universität Koblenz-Landau (where applicable)
3rd attempt:
the visitor pattern
Part I:
An interface for operations
interface Visitor {
void visitNil(Nil x);
void visitCons(Cons x);
}
(C) 2010-2013 Prof. Dr. Ralf Lämmel, Universität Koblenz-Landau (where applicable)
3rd attempt:
the visitor pattern
Part II:
Classes that accept visitorsinterface List {
void accept(Visitor v);
}
class Nil implements List {
public void accept(Visitor v) {
v.visitNil(this); }
}
class Cons implements List {
int head;
List tail;
public void accept(Visitor v) {
v.visitCons(this);
}
}
(C) 2010-2013 Prof. Dr. Ralf Lämmel, Universität Koblenz-Landau (where applicable)
3rd attempt:
the visitor pattern
Part III:
A concrete visitor
class SumVisitor implements Visitor {
int sum = 0;
public void visitNil(Nil x) {}
public void visitCons(Cons x){
sum = sum + x.head;
x.tail.accept(this);
}
}
(C) 2010-2013 Prof. Dr. Ralf Lämmel, Universität Koblenz-Landau (where applicable)
3rd attempt:
the visitor pattern
Demo
SumVisitor sv = new SumVisitor();
l.accept(sv);
System.out.println(sv.sum);
(C) 2010-2013 Prof. Dr. Ralf Lämmel, Universität Koblenz-Landau (where applicable)
Summary so far
Frequent
type casts?
Frequent
recompilation?
Instanceof and type casts Yes No
Dedicated methods No Yes
The Visitor pattern No No
What if we need a new class?
(C) 2010-2013 Prof. Dr. Ralf Lämmel, Universität Koblenz-Landau (where applicable)
Summary so far
• Class hierarchy implements virtual accept.
• A Visitor object has a visit method for each class.
• Double dispatch:
• accept method takes a specific Visitor object.
• accept redirects to class-specific visit method.
Two levels of polymorphism
(C) 2010-2013 Prof. Dr. Ralf Lämmel, Universität Koblenz-Landau (where applicable)
The Visitor pattern:
generic solution
http://en.wikipedia.org/wiki/File:VisitorClassDiagram.svg
(C) 2010-2013 Prof. Dr. Ralf Lämmel, Universität Koblenz-Landau (where applicable)
Applicability
An object structure contains different classes of
objects with different interfaces and operations on
these objects depend on their concrete classes.
Many unrelated operations need to be performed
on the objects and you want to keep related
operations together.
The classes defining the object structure rarely
change, but you want to define new operations
over the structure. (If the object structure classes
change often, it is better to define the operations
in those classes.)
(C) 2010-2013 Ralf Lämmel
Operation extensibility based on visitors
• class Expr:The base class of all expression forms
• Subclasses as before.
• Virtual methods:
• Accept a visitor (“apply an operation”)
• Visitors:
• class PrettyPrinter: operation for pretty-printing
• class Evaluator: operation for expression evaluation
• ... Operation extensibility
52
(C) 2010-2013 Ralf Lämmel
/**
* The base class of all expression forms
*/
public abstract class Expr {
	
	 /*
	 * Accept a visitor (i.e., apply an operation)
	 */
	 public abstract <R> R accept(Visitor<R> v);
}
Domain operations are
no longer hosted in
domain classes.
53
(C) 2010-2013 Ralf Lämmel54
Intermezzo:
visitor types
• Returning visitors
• Visit methods have a return type.
• Void visitors
• Visit methods are void.
In principle, void visitors are sufficient because one can always
(and often has to) aggregate the result through state which is
ultimately to be returned through a designated getter.
(C) 2010-2013 Ralf Lämmel
/**
* A concrete visitor describe a concrete operation on expressions.
* There is one visit method per type in the class hierarchy.
*/
public abstract class Visitor<R> {
	
	 public abstract R visit(Lit x);
	 public abstract R visit(Add x);
	 public abstract R visit(Neg x);
}
Requires folklore
knowledge on design
patterns.
55
(C) 2010-2013 Ralf Lämmel
/**
* The expression form of "literals" (i.e., constants)
*/
public class Lit extends Expr {
	
	 private int info;
	 public int getInfo() { return info; }
	 public void setInfo(int info) { this.info = info; }
	
	 public <R> R accept(Visitor<R> v) {
	 	 return v.visit(this);
	 }
}
One visitor-enabled
data variant.
56
(C) 2010-2013 Ralf Lämmel
/**
* The expression form of "addition"
*/
public class Add extends Expr {
	
	 private Expr left, right;
	 public Expr getLeft() { return left; }
	 public void setLeft(Expr left) { this.left = left; }	
	 public Expr getRight() { return right; }
	 public void setRight(Expr right) { this.right = right; }
	
	 public <R> R accept(Visitor<R> v) {
	 	 return v.visit(this);
	 }
}
Another visitor-enabled
data variant.
Beware
of code bloat!
57
(C) 2010-2013 Ralf Lämmel
/**
* The expression form of "negation"
*/
public class Neg extends Expr {
	
	 private Expr expr;
	 public Expr getExpr() { return expr; }
	 public void setExpr(Expr expr) { this.expr = expr; }
	 public <R> R accept(Visitor<R> v) {
	 	 return v.visit(this);
	 }
}
Beware
of code bloat!
Yet another
visitor-enabled
data variant.
58
(C) 2010-2013 Ralf Lämmel
/**
* Operation for pretty printing
*/
public class PrettyPrinter extends Visitor<String> {
	 public String visit(Lit x) {
	 	 	 return Integer.toString(x.getInfo());
	 }
	 public String visit(Add x) {
	 	 	 return x.getLeft().accept(this)
	 	 	 + " + "
	 	 	 + x.getRight().accept(this);
	 }
	 public String visit(Neg x) {
	 	 return "- (" + x.getExpr().accept(this) + ")";
	 }
}
Beware
of code bloat!
An operation
represented as a
concrete visitor.
59
(C) 2010-2013 Ralf Lämmel
Beware
of code bloat!
Another operation
represented as a
concrete visitor.
/**
* Operation for expression evaluation
*/
public class Evaluator extends Visitor<Integer> {
	 public Integer visit(Lit x) {
	 	 return x.getInfo();
	 }
	 public Integer visit(Add x) {
	 	 return x.getLeft().accept(this) + x.getRight().accept(this);
	 }
	 public Integer visit(Neg x) {
	 	 return - x.getExpr().accept(this);
	 }
}
60
(C) 2010-2013 Prof. Dr. Ralf Lämmel, Universität Koblenz-Landau (where applicable)
101implementations
javaComposition
javaStatic
javaInheritance
javaVisitor
(C) 2010-2013 Prof. Dr. Ralf Lämmel, Universität Koblenz-Landau (where applicable)
Summary
Try to modularize (say, separate concerns).
Try to understand extensibility requirements.
Avoid modularity exorcism.
Take refactoring and testing very seriously.
Please don’t print the slides,
or print resource-friendly.
Everything beyond
this point is “for your
information” only.
The Expression Problem
Cont’d
(C) 2010-2013 Ralf Lämmel
The notion of extensibility
• The initial system I:
• Provides operations o1, …, om.
• Handles data variants d1, …, dn.
• Consider any number of extensions e1, …, ek:
– ei could be a data extension:
• Introduce a new data variant.
• Provide cases for all existing operations.
– ei could be an operation extension:
• Introduce a new operation.
• Provide cases for all existing data variants.
– Any extension can be factored into such primitive ones.
• The fully extended system ek ( … (e1 (I)))
65
(C) 2010-2013 Ralf Lämmel
More on extensibility
• Code-level extensibility:
– Extensions can be modeled as code units.
– Existing code units are never edited or cloned.
• Separate compilation:
– The extensions are compiled separately.
• Statically type-checked extensibility:
– The extension are statically type-checked separately.
66
(C) 2010-2013 Ralf Lämmel
Beyond Java
• Functions and pattern matching à la SML, Haskell
• Multi-file predicates in Prolog
• Partial classes in C#
• ...
67
(C) 2010-2013 Ralf Lämmel
A C# approach to extensibility
• Use the partial class mechanism of C#
• A class can be “declared” many times.
• The list of members is accumulated.
68
(C) 2010-2013 Ralf Lämmel
The data slice
69
public abstract partial class Expr { }
public partial class Lit : Expr {
public int info;
}
public partial class Add : Expr {
public Expr left, right;
}
(C) 2010-2013 Ralf Lämmel
The evaluation slice
70
public abstract partial class Expr {
public abstract int Evaluate();
}
public partial class Lit {
public override int Evaluate() {
return info;
}
}
public partial class Add {
public override int Evaluate(){
return left.Evaluate()
+ right.Evaluate();
}
}
(C) 2010-2013 Ralf Lämmel
The evaluation slice
71
public abstract partial class Expr {
public abstract string PrettyPrint();
}
public partial class Lit {
public override string PrettyPrint() {
return info.ToString();
}
}
public partial class Add
{
public override string PrettyPrint() {
return left.PrettyPrint()
+ " + "
+ right.PrettyPrint();
}
}
(C) 2010-2013 Ralf Lämmel
A data extension
72
public partial class Neg : Expr {
public Expr expr;
}
public partial class Neg {
public override string PrettyPrint() {
return "- (" + expr.PrettyPrint() + ")";
}
}
public partial class Neg {
public override int Evaluate() {
return -expr.Evaluate();
}
}
(C) 2010-2013 Ralf Lämmel
Discussion of the C# approach
• Code extensibility only
• All extension need to be compiled together.
• Slices are not even checked independently.
73
(C) 2010-2013 Ralf Lämmel
A Haskell approach to operation extensibility
• data type Expr:The union of all expression forms
• Public constructors:
• Lit:The expression form of "literals"
• Add:The expression form of "addition"
• Functions defined by pattern matching on Expr:
• function prettyPrint: operation for pretty-printing
• function evaluate: operation for expression evaluation
• ... Operation extensibility
74
(C) 2010-2013 Ralf Lämmel
Algebraic data types
of Haskell are closed!
module Data where
-- A data type of expression forms
data Exp = Lit Int | Add Exp Exp
75
Algebraic data
type
Constructor Constructor
component
Constructor
2 constructor
components
(C) 2010-2013 Ralf Lämmel
module PrettyPrinter where
import Data
-- Operation for pretty printing
prettyPrint :: Exp -> IO ()
prettyPrint (Lit i) = putStr (show i)
prettyPrint (Add l r) = do prettyPrint l; putStr " + "; prettyPrint r
A new module can be
designated to each
new operation.
76
Operation defined by
case discrimination
Argument
type
Result type
“side effect”
(C) 2010-2013 Ralf Lämmel
Another operation;
another module.
module Evaluator where
import Data
-- Operation for expression evaluation
evaluate :: Exp -> Int
evaluate (Lit i) = i
evaluate (Add l r) = evaluate l + evaluate r
77
(C) 2010-2013 Ralf Lämmel
Discussion of the Haskell approach
• Lack of encapsulation?
• Only operation extensibility
78
(C) 2010-2013 Ralf Lämmel
A Prolog approach to extensibility
• Define operations as predicates.
• Model data variants through functors.
• Achieve extensibility through “multi-file” predicates.
79
(C) 2010-2013 Ralf Lämmel
The initial program
80
:- multifile prettyPrint/2.
prettyPrint(lit(I),S)
:-
string_to_atom(S,I).
prettyPrint(add(L,R),S)
:-
prettyPrint(L,S1),
prettyPrint(R,S2),
format(string(S),"~s + ~s", [S1,S2]).
(C) 2010-2013 Ralf Lämmel
A data extension
81
:- multifile prettyPrint/2.
:- multifile evaluate/2.
prettyPrint(neg(E),S)
:-
prettyPrint(E,S1),
format(string(S),"- (~s)",[S1]).
evaluate(neg(E),I)
:-
evaluate(E,I1),
I is - I1.
(C) 2010-2013 Ralf Lämmel
An operation extension
82
:- multifile evaluate/2.
evaluate(lit(I),I).
evaluate(add(L,R),I)
:-
evaluate(L,I1),
evaluate(R,I2),
I is I1 + I2.
(C) 2010-2013 Ralf Lämmel
Program composition
83
:- [ 'InitialProgram.pro'
, 'OperationExtension.pro'
, 'DataExtension.pro'
].
(C) 2010-2013 Ralf Lämmel
Discussion of the Prolog approach
• Full extensibility
• No descriptive overhead
• Lack of static typing
• Performance penalty
84
(C) 2010-2013 Ralf Lämmel
Solutions of the expression problem
• Open classes in more dynamic languages (Smalltalk, etc.)
• Extensible predicates in Prolog (code-level extensibility only)
• Java, C# & Co.
• Clever encodings (Torgersen, ECOOP 2004)
• AOP-like Open classes (introductions)
• .NET-like partial classes (code-level extensibility only)
• Expanders (Warth et al., OOPSLA 2006)
• JavaGI (Wehr et al., ECOOP 2007)
• ...
85
(C) 2010-2013 Prof. Dr. Ralf Lämmel, Universität Koblenz-Landau (where applicable)
Summary on extensibility
Wanted
Data extensibility and
Operation extensibility and
Soft or strong static type checking and
Separate compilation/deployment and
Unanticipated extension and
Configurability and Composability and
Efficiency (“No distributed fat”)

Contenu connexe

Tendances (7)

Fundamentals of Software Engineering
Fundamentals of Software Engineering Fundamentals of Software Engineering
Fundamentals of Software Engineering
 
Introduction to matlab
Introduction to matlabIntroduction to matlab
Introduction to matlab
 
Matlab intro
Matlab introMatlab intro
Matlab intro
 
Introduction to Matlab
Introduction to MatlabIntroduction to Matlab
Introduction to Matlab
 
Matlab ppt
Matlab pptMatlab ppt
Matlab ppt
 
Matlab
MatlabMatlab
Matlab
 
Matlab OOP
Matlab OOPMatlab OOP
Matlab OOP
 

Similaire à The Expression Problem (as part of the the PTT lecture)

Aspect-oriented programming with AspectJ (as part of the the PTT lecture)
Aspect-oriented programming with AspectJ (as part of the the PTT lecture)Aspect-oriented programming with AspectJ (as part of the the PTT lecture)
Aspect-oriented programming with AspectJ (as part of the the PTT lecture)Ralf Laemmel
 
Functional OO programming (as part of the the PTT lecture)
Functional OO programming (as part of the the PTT lecture)Functional OO programming (as part of the the PTT lecture)
Functional OO programming (as part of the the PTT lecture)Ralf Laemmel
 
Database programming including O/R mapping (as part of the the PTT lecture)
Database programming including O/R mapping (as part of the the PTT lecture)Database programming including O/R mapping (as part of the the PTT lecture)
Database programming including O/R mapping (as part of the the PTT lecture)Ralf Laemmel
 
Language processing patterns
Language processing patternsLanguage processing patterns
Language processing patternsRalf Laemmel
 
Selected design patterns (as part of the the PTT lecture)
Selected design patterns (as part of the the PTT lecture)Selected design patterns (as part of the the PTT lecture)
Selected design patterns (as part of the the PTT lecture)Ralf Laemmel
 
Open Problems in Automatically Refactoring Legacy Java Software to use New Fe...
Open Problems in Automatically Refactoring Legacy Java Software to use New Fe...Open Problems in Automatically Refactoring Legacy Java Software to use New Fe...
Open Problems in Automatically Refactoring Legacy Java Software to use New Fe...Raffi Khatchadourian
 
Solid Principles
Solid PrinciplesSolid Principles
Solid PrinciplesHitheshh
 
The Expression Problem - Part 2
The Expression Problem - Part 2The Expression Problem - Part 2
The Expression Problem - Part 2Philip Schwarz
 
Metaprograms and metadata (as part of the the PTT lecture)
Metaprograms and metadata (as part of the the PTT lecture)Metaprograms and metadata (as part of the the PTT lecture)
Metaprograms and metadata (as part of the the PTT lecture)Ralf Laemmel
 
Functional Programming You Already Know - Kevlin Henney - Codemotion Rome 2015
Functional Programming You Already Know - Kevlin Henney - Codemotion Rome 2015Functional Programming You Already Know - Kevlin Henney - Codemotion Rome 2015
Functional Programming You Already Know - Kevlin Henney - Codemotion Rome 2015Codemotion
 
Object Oriented Principle&rsquo;s
Object Oriented Principle&rsquo;sObject Oriented Principle&rsquo;s
Object Oriented Principle&rsquo;svivek p s
 
Choose'10: Ralf Laemmel - Dealing Confortably with the Confusion of Tongues
Choose'10: Ralf Laemmel - Dealing Confortably with the Confusion of TonguesChoose'10: Ralf Laemmel - Dealing Confortably with the Confusion of Tongues
Choose'10: Ralf Laemmel - Dealing Confortably with the Confusion of TonguesCHOOSE
 
Software Frameworks
Software FrameworksSoftware Frameworks
Software Frameworksadil raja
 
Twins: Object Oriented Programming and Functional Programming
Twins: Object Oriented Programming and Functional ProgrammingTwins: Object Oriented Programming and Functional Programming
Twins: Object Oriented Programming and Functional ProgrammingRichardWarburton
 
Introduction to new features in java 8
Introduction to new features in java 8Introduction to new features in java 8
Introduction to new features in java 8Raffi Khatchadourian
 
20.4 Java interfaces and abstraction
20.4 Java interfaces and abstraction20.4 Java interfaces and abstraction
20.4 Java interfaces and abstractionIntro C# Book
 

Similaire à The Expression Problem (as part of the the PTT lecture) (20)

Aspect-oriented programming with AspectJ (as part of the the PTT lecture)
Aspect-oriented programming with AspectJ (as part of the the PTT lecture)Aspect-oriented programming with AspectJ (as part of the the PTT lecture)
Aspect-oriented programming with AspectJ (as part of the the PTT lecture)
 
Functional OO programming (as part of the the PTT lecture)
Functional OO programming (as part of the the PTT lecture)Functional OO programming (as part of the the PTT lecture)
Functional OO programming (as part of the the PTT lecture)
 
Database programming including O/R mapping (as part of the the PTT lecture)
Database programming including O/R mapping (as part of the the PTT lecture)Database programming including O/R mapping (as part of the the PTT lecture)
Database programming including O/R mapping (as part of the the PTT lecture)
 
Getting started with R
Getting started with RGetting started with R
Getting started with R
 
Language processing patterns
Language processing patternsLanguage processing patterns
Language processing patterns
 
Selected design patterns (as part of the the PTT lecture)
Selected design patterns (as part of the the PTT lecture)Selected design patterns (as part of the the PTT lecture)
Selected design patterns (as part of the the PTT lecture)
 
Open Problems in Automatically Refactoring Legacy Java Software to use New Fe...
Open Problems in Automatically Refactoring Legacy Java Software to use New Fe...Open Problems in Automatically Refactoring Legacy Java Software to use New Fe...
Open Problems in Automatically Refactoring Legacy Java Software to use New Fe...
 
Solid Principles
Solid PrinciplesSolid Principles
Solid Principles
 
The Expression Problem - Part 2
The Expression Problem - Part 2The Expression Problem - Part 2
The Expression Problem - Part 2
 
Introduction to r
Introduction to rIntroduction to r
Introduction to r
 
Metaprograms and metadata (as part of the the PTT lecture)
Metaprograms and metadata (as part of the the PTT lecture)Metaprograms and metadata (as part of the the PTT lecture)
Metaprograms and metadata (as part of the the PTT lecture)
 
Functional Programming You Already Know - Kevlin Henney - Codemotion Rome 2015
Functional Programming You Already Know - Kevlin Henney - Codemotion Rome 2015Functional Programming You Already Know - Kevlin Henney - Codemotion Rome 2015
Functional Programming You Already Know - Kevlin Henney - Codemotion Rome 2015
 
Object Oriented Principle&rsquo;s
Object Oriented Principle&rsquo;sObject Oriented Principle&rsquo;s
Object Oriented Principle&rsquo;s
 
Choose'10: Ralf Laemmel - Dealing Confortably with the Confusion of Tongues
Choose'10: Ralf Laemmel - Dealing Confortably with the Confusion of TonguesChoose'10: Ralf Laemmel - Dealing Confortably with the Confusion of Tongues
Choose'10: Ralf Laemmel - Dealing Confortably with the Confusion of Tongues
 
Software Frameworks
Software FrameworksSoftware Frameworks
Software Frameworks
 
Twins: Object Oriented Programming and Functional Programming
Twins: Object Oriented Programming and Functional ProgrammingTwins: Object Oriented Programming and Functional Programming
Twins: Object Oriented Programming and Functional Programming
 
PLP-L1-Intro.ppt
PLP-L1-Intro.pptPLP-L1-Intro.ppt
PLP-L1-Intro.ppt
 
Introduction to new features in java 8
Introduction to new features in java 8Introduction to new features in java 8
Introduction to new features in java 8
 
Introduction to new features in java 8
Introduction to new features in java 8Introduction to new features in java 8
Introduction to new features in java 8
 
20.4 Java interfaces and abstraction
20.4 Java interfaces and abstraction20.4 Java interfaces and abstraction
20.4 Java interfaces and abstraction
 

Plus de Ralf Laemmel

Keynote at-icpc-2020
Keynote at-icpc-2020Keynote at-icpc-2020
Keynote at-icpc-2020Ralf Laemmel
 
Functional data structures
Functional data structuresFunctional data structures
Functional data structuresRalf Laemmel
 
Modeling software systems at a macroscopic scale
Modeling software systems  at a macroscopic scaleModeling software systems  at a macroscopic scale
Modeling software systems at a macroscopic scaleRalf Laemmel
 
An introduction on language processing
An introduction on language processingAn introduction on language processing
An introduction on language processingRalf Laemmel
 
Surfacing ‘101’ in a Linked Data manner as presented at SATToSE 2013
Surfacing ‘101’ in a Linked Data manner as presented at SATToSE 2013Surfacing ‘101’ in a Linked Data manner as presented at SATToSE 2013
Surfacing ‘101’ in a Linked Data manner as presented at SATToSE 2013Ralf Laemmel
 
Remote method invocation (as part of the the PTT lecture)
Remote method invocation (as part of the the PTT lecture)Remote method invocation (as part of the the PTT lecture)
Remote method invocation (as part of the the PTT lecture)Ralf Laemmel
 
Multithreaded programming (as part of the the PTT lecture)
Multithreaded programming (as part of the the PTT lecture)Multithreaded programming (as part of the the PTT lecture)
Multithreaded programming (as part of the the PTT lecture)Ralf Laemmel
 
Generative programming (mostly parser generation)
Generative programming (mostly parser generation)Generative programming (mostly parser generation)
Generative programming (mostly parser generation)Ralf Laemmel
 

Plus de Ralf Laemmel (9)

Keynote at-icpc-2020
Keynote at-icpc-2020Keynote at-icpc-2020
Keynote at-icpc-2020
 
Functional data structures
Functional data structuresFunctional data structures
Functional data structures
 
Modeling software systems at a macroscopic scale
Modeling software systems  at a macroscopic scaleModeling software systems  at a macroscopic scale
Modeling software systems at a macroscopic scale
 
An introduction on language processing
An introduction on language processingAn introduction on language processing
An introduction on language processing
 
Surfacing ‘101’ in a Linked Data manner as presented at SATToSE 2013
Surfacing ‘101’ in a Linked Data manner as presented at SATToSE 2013Surfacing ‘101’ in a Linked Data manner as presented at SATToSE 2013
Surfacing ‘101’ in a Linked Data manner as presented at SATToSE 2013
 
Remote method invocation (as part of the the PTT lecture)
Remote method invocation (as part of the the PTT lecture)Remote method invocation (as part of the the PTT lecture)
Remote method invocation (as part of the the PTT lecture)
 
Multithreaded programming (as part of the the PTT lecture)
Multithreaded programming (as part of the the PTT lecture)Multithreaded programming (as part of the the PTT lecture)
Multithreaded programming (as part of the the PTT lecture)
 
Generative programming (mostly parser generation)
Generative programming (mostly parser generation)Generative programming (mostly parser generation)
Generative programming (mostly parser generation)
 
XML data binding
XML data bindingXML data binding
XML data binding
 

Dernier

IaC & GitOps in a Nutshell - a FridayInANuthshell Episode.pdf
IaC & GitOps in a Nutshell - a FridayInANuthshell Episode.pdfIaC & GitOps in a Nutshell - a FridayInANuthshell Episode.pdf
IaC & GitOps in a Nutshell - a FridayInANuthshell Episode.pdfDaniel Santiago Silva Capera
 
UiPath Studio Web workshop series - Day 6
UiPath Studio Web workshop series - Day 6UiPath Studio Web workshop series - Day 6
UiPath Studio Web workshop series - Day 6DianaGray10
 
Secure your environment with UiPath and CyberArk technologies - Session 1
Secure your environment with UiPath and CyberArk technologies - Session 1Secure your environment with UiPath and CyberArk technologies - Session 1
Secure your environment with UiPath and CyberArk technologies - Session 1DianaGray10
 
Machine Learning Model Validation (Aijun Zhang 2024).pdf
Machine Learning Model Validation (Aijun Zhang 2024).pdfMachine Learning Model Validation (Aijun Zhang 2024).pdf
Machine Learning Model Validation (Aijun Zhang 2024).pdfAijun Zhang
 
Linked Data in Production: Moving Beyond Ontologies
Linked Data in Production: Moving Beyond OntologiesLinked Data in Production: Moving Beyond Ontologies
Linked Data in Production: Moving Beyond OntologiesDavid Newbury
 
Cloud Revolution: Exploring the New Wave of Serverless Spatial Data
Cloud Revolution: Exploring the New Wave of Serverless Spatial DataCloud Revolution: Exploring the New Wave of Serverless Spatial Data
Cloud Revolution: Exploring the New Wave of Serverless Spatial DataSafe Software
 
Artificial Intelligence & SEO Trends for 2024
Artificial Intelligence & SEO Trends for 2024Artificial Intelligence & SEO Trends for 2024
Artificial Intelligence & SEO Trends for 2024D Cloud Solutions
 
Digital magic. A small project for controlling smart light bulbs.
Digital magic. A small project for controlling smart light bulbs.Digital magic. A small project for controlling smart light bulbs.
Digital magic. A small project for controlling smart light bulbs.francesco barbera
 
UiPath Solutions Management Preview - Northern CA Chapter - March 22.pdf
UiPath Solutions Management Preview - Northern CA Chapter - March 22.pdfUiPath Solutions Management Preview - Northern CA Chapter - March 22.pdf
UiPath Solutions Management Preview - Northern CA Chapter - March 22.pdfDianaGray10
 
UWB Technology for Enhanced Indoor and Outdoor Positioning in Physiological M...
UWB Technology for Enhanced Indoor and Outdoor Positioning in Physiological M...UWB Technology for Enhanced Indoor and Outdoor Positioning in Physiological M...
UWB Technology for Enhanced Indoor and Outdoor Positioning in Physiological M...UbiTrack UK
 
COMPUTER 10 Lesson 8 - Building a Website
COMPUTER 10 Lesson 8 - Building a WebsiteCOMPUTER 10 Lesson 8 - Building a Website
COMPUTER 10 Lesson 8 - Building a Websitedgelyza
 
Anypoint Code Builder , Google Pub sub connector and MuleSoft RPA
Anypoint Code Builder , Google Pub sub connector and MuleSoft RPAAnypoint Code Builder , Google Pub sub connector and MuleSoft RPA
Anypoint Code Builder , Google Pub sub connector and MuleSoft RPAshyamraj55
 
KubeConEU24-Monitoring Kubernetes and Cloud Spend with OpenCost
KubeConEU24-Monitoring Kubernetes and Cloud Spend with OpenCostKubeConEU24-Monitoring Kubernetes and Cloud Spend with OpenCost
KubeConEU24-Monitoring Kubernetes and Cloud Spend with OpenCostMatt Ray
 
Salesforce Miami User Group Event - 1st Quarter 2024
Salesforce Miami User Group Event - 1st Quarter 2024Salesforce Miami User Group Event - 1st Quarter 2024
Salesforce Miami User Group Event - 1st Quarter 2024SkyPlanner
 
OpenShift Commons Paris - Choose Your Own Observability Adventure
OpenShift Commons Paris - Choose Your Own Observability AdventureOpenShift Commons Paris - Choose Your Own Observability Adventure
OpenShift Commons Paris - Choose Your Own Observability AdventureEric D. Schabell
 
NIST Cybersecurity Framework (CSF) 2.0 Workshop
NIST Cybersecurity Framework (CSF) 2.0 WorkshopNIST Cybersecurity Framework (CSF) 2.0 Workshop
NIST Cybersecurity Framework (CSF) 2.0 WorkshopBachir Benyammi
 
UiPath Studio Web workshop series - Day 8
UiPath Studio Web workshop series - Day 8UiPath Studio Web workshop series - Day 8
UiPath Studio Web workshop series - Day 8DianaGray10
 
Designing A Time bound resource download URL
Designing A Time bound resource download URLDesigning A Time bound resource download URL
Designing A Time bound resource download URLRuncy Oommen
 
Cybersecurity Workshop #1.pptx
Cybersecurity Workshop #1.pptxCybersecurity Workshop #1.pptx
Cybersecurity Workshop #1.pptxGDSC PJATK
 
Connector Corner: Extending LLM automation use cases with UiPath GenAI connec...
Connector Corner: Extending LLM automation use cases with UiPath GenAI connec...Connector Corner: Extending LLM automation use cases with UiPath GenAI connec...
Connector Corner: Extending LLM automation use cases with UiPath GenAI connec...DianaGray10
 

Dernier (20)

IaC & GitOps in a Nutshell - a FridayInANuthshell Episode.pdf
IaC & GitOps in a Nutshell - a FridayInANuthshell Episode.pdfIaC & GitOps in a Nutshell - a FridayInANuthshell Episode.pdf
IaC & GitOps in a Nutshell - a FridayInANuthshell Episode.pdf
 
UiPath Studio Web workshop series - Day 6
UiPath Studio Web workshop series - Day 6UiPath Studio Web workshop series - Day 6
UiPath Studio Web workshop series - Day 6
 
Secure your environment with UiPath and CyberArk technologies - Session 1
Secure your environment with UiPath and CyberArk technologies - Session 1Secure your environment with UiPath and CyberArk technologies - Session 1
Secure your environment with UiPath and CyberArk technologies - Session 1
 
Machine Learning Model Validation (Aijun Zhang 2024).pdf
Machine Learning Model Validation (Aijun Zhang 2024).pdfMachine Learning Model Validation (Aijun Zhang 2024).pdf
Machine Learning Model Validation (Aijun Zhang 2024).pdf
 
Linked Data in Production: Moving Beyond Ontologies
Linked Data in Production: Moving Beyond OntologiesLinked Data in Production: Moving Beyond Ontologies
Linked Data in Production: Moving Beyond Ontologies
 
Cloud Revolution: Exploring the New Wave of Serverless Spatial Data
Cloud Revolution: Exploring the New Wave of Serverless Spatial DataCloud Revolution: Exploring the New Wave of Serverless Spatial Data
Cloud Revolution: Exploring the New Wave of Serverless Spatial Data
 
Artificial Intelligence & SEO Trends for 2024
Artificial Intelligence & SEO Trends for 2024Artificial Intelligence & SEO Trends for 2024
Artificial Intelligence & SEO Trends for 2024
 
Digital magic. A small project for controlling smart light bulbs.
Digital magic. A small project for controlling smart light bulbs.Digital magic. A small project for controlling smart light bulbs.
Digital magic. A small project for controlling smart light bulbs.
 
UiPath Solutions Management Preview - Northern CA Chapter - March 22.pdf
UiPath Solutions Management Preview - Northern CA Chapter - March 22.pdfUiPath Solutions Management Preview - Northern CA Chapter - March 22.pdf
UiPath Solutions Management Preview - Northern CA Chapter - March 22.pdf
 
UWB Technology for Enhanced Indoor and Outdoor Positioning in Physiological M...
UWB Technology for Enhanced Indoor and Outdoor Positioning in Physiological M...UWB Technology for Enhanced Indoor and Outdoor Positioning in Physiological M...
UWB Technology for Enhanced Indoor and Outdoor Positioning in Physiological M...
 
COMPUTER 10 Lesson 8 - Building a Website
COMPUTER 10 Lesson 8 - Building a WebsiteCOMPUTER 10 Lesson 8 - Building a Website
COMPUTER 10 Lesson 8 - Building a Website
 
Anypoint Code Builder , Google Pub sub connector and MuleSoft RPA
Anypoint Code Builder , Google Pub sub connector and MuleSoft RPAAnypoint Code Builder , Google Pub sub connector and MuleSoft RPA
Anypoint Code Builder , Google Pub sub connector and MuleSoft RPA
 
KubeConEU24-Monitoring Kubernetes and Cloud Spend with OpenCost
KubeConEU24-Monitoring Kubernetes and Cloud Spend with OpenCostKubeConEU24-Monitoring Kubernetes and Cloud Spend with OpenCost
KubeConEU24-Monitoring Kubernetes and Cloud Spend with OpenCost
 
Salesforce Miami User Group Event - 1st Quarter 2024
Salesforce Miami User Group Event - 1st Quarter 2024Salesforce Miami User Group Event - 1st Quarter 2024
Salesforce Miami User Group Event - 1st Quarter 2024
 
OpenShift Commons Paris - Choose Your Own Observability Adventure
OpenShift Commons Paris - Choose Your Own Observability AdventureOpenShift Commons Paris - Choose Your Own Observability Adventure
OpenShift Commons Paris - Choose Your Own Observability Adventure
 
NIST Cybersecurity Framework (CSF) 2.0 Workshop
NIST Cybersecurity Framework (CSF) 2.0 WorkshopNIST Cybersecurity Framework (CSF) 2.0 Workshop
NIST Cybersecurity Framework (CSF) 2.0 Workshop
 
UiPath Studio Web workshop series - Day 8
UiPath Studio Web workshop series - Day 8UiPath Studio Web workshop series - Day 8
UiPath Studio Web workshop series - Day 8
 
Designing A Time bound resource download URL
Designing A Time bound resource download URLDesigning A Time bound resource download URL
Designing A Time bound resource download URL
 
Cybersecurity Workshop #1.pptx
Cybersecurity Workshop #1.pptxCybersecurity Workshop #1.pptx
Cybersecurity Workshop #1.pptx
 
Connector Corner: Extending LLM automation use cases with UiPath GenAI connec...
Connector Corner: Extending LLM automation use cases with UiPath GenAI connec...Connector Corner: Extending LLM automation use cases with UiPath GenAI connec...
Connector Corner: Extending LLM automation use cases with UiPath GenAI connec...
 

The Expression Problem (as part of the the PTT lecture)

  • 1. The Expression Problem Prof. Dr. Ralf Lämmel Universität Koblenz-Landau Software Languages Team
  • 2. (C) 2010-2013 Ralf Lämmel Elevator speech Suppose you have some data variants (say “apples” and “oranges”) and you have some operations on such data (say “drink” and “squeeze”), how would you go about the design of data and operations so that you can hopefully add new data variants and new operations later on? 21
  • 3. (C) 2010-2013 Ralf Lämmel Expression problem: Why the name? • Consider such data: – Expressions as in programming languages: – Literals – Addition – … • Consider such operations: – Pretty print expressions – Evaluate expressions – … • Consider such extension scenarios: – Add another expression form • Cases for all existing operations must be added. – Add another operation • Cases for all existing expression forms must be added. 22 The name goes back to Phil Wadler who defined the expression problem in an email sent to mailing lists and individuals in November 1998.
  • 4. (C) 2010-2013 Ralf Lämmel Expression problem: What problem? • In basic OO programming: – It is easy to add new data variants. – It is hard to add new operations. 23
  • 5. (C) 2010-2013 Ralf Lämmel Data extensibility based on simple inheritance • class Expr:The base class of all expression forms • Virtual methods: • method prettyPrint: operation for pretty-printing • method evaluate: operation for expression evaluation • Subclasses: • class Lit:The expression form of "literals" • class Add:The expression form of "addition" • ... Data extensibility 24
  • 6. (C) 2010-2013 Ralf Lämmel /** * The base class of all expression forms */ public abstract class Expr { /* * Operation for pretty printing */ public abstract String prettyPrint(); /* * Operation for expression evaluation */ public abstract int evaluate(); } Beware of code bloat! 25 The class rooting all data variants
  • 7. (C) 2010-2013 Ralf Lämmel /** * The expression form of "literals" (i.e., constants) */ public class Lit extends Expr { private int info; public int getInfo() { return info; } public void setInfo(int info) { this.info = info; } public String prettyPrint() { return Integer.toString(getInfo()); } public int evaluate() { return getInfo(); } } Beware of code bloat! 26 A class for a data variant
  • 8. (C) 2010-2013 Ralf Lämmel /** * The expression form of "addition" */ public class Add extends Expr { private Expr left, right; public Expr getLeft() { return left; } public void setLeft(Expr left) { this.left = left; } public Expr getRight() { return right; } public void setRight(Expr right) { this.right = right; } public String prettyPrint() { ... } public int evaluate() { return getLeft().evaluate() + getRight().evaluate(); } } That is, another data variant but with the same operations. Beware of code bloat! 27
  • 9. (C) 2010-2013 Ralf Lämmel /** * The expression form of "negation" */ public class Neg extends Expr { private Expr expr; public Expr getExpr() { return expr; } public void setExpr(Expr expr) { this.expr = expr; } public String prettyPrint() { return "-(" + getExpr().prettyPrint() + ")"; } public int evaluate() { return - getExpr().evaluate(); } } That is, yet another data variant but, again, with the same operations. Beware of code bloat! 28
  • 10. (C) 2010-2013 Ralf Lämmel Expression problem: What problem? • In basic OO programming: – It is easy to add new data variants. – It is hard to add new operations. • In OO programming with instance-of / cast: – It is easy to add new operations. – It is easy to add new data variants. 29 But beware of programming errors
  • 11. (C) 2010-2013 Ralf Lämmel Full (?) extensibility based on instance-of tests and type casts • We use instanceof tests and casts to dispatch functionality on data. • We use a specific exception and try-catch blocks to extend operations. • We encapsulate operations in objects so that extensions are self-aware. • This is approach is weakly typed. • In particular, there is no guarantee that we have covered all cases. 30
  • 12. (C) 2010-2013 Ralf Lämmel public abstract class Expr { } public class Lit extends Expr { private int info; public int getInfo() { return info; } public void setInfo(int info) { this.info = info; } } public class Add extends Expr { private Expr left, right; public Expr getLeft() { return left; } public void setLeft(Expr left) { this.left = left; } public Expr getRight() { return right; } public void setRight(Expr right) { this.right = right; } } Domain classes are nothing but data capsules. 31
  • 13. (C) 2010-2013 Ralf Lämmel public class EvaluatorBase { public int evaluate(Expr e) { if (e instanceof Lit) { Lit l = (Lit)e; return l.getInfo(); } if (e instanceof Add) { Add a = (Add)e; return evaluate(a.getLeft()) + evaluate(a.getRight()); } throw new FallThrouhException(); } } We simulate pattern matching by instanceof and cast. We anticipate failure of such operations as a means to compose them. 32
  • 14. (C) 2010-2013 Ralf Lämmel public class EvaluatorExtension extends EvaluatorBase { public int evaluate(Expr e) { try { return super.evaluate(e); } catch (FallThrouhException x) { if (e instanceof Neg) { Neg n = (Neg)e; return -evaluate(n.getExpr()); } throw new FallThrouhException(); } } } Recursive calls are properly dispatched through “this” to the extended operation. An extended operation first attempts the basic implementation. 33
  • 15. (C) 2010-2013 Ralf Lämmel Expression problem: What problem? • In basic OO programming: – It is easy to add new data variants. – It is hard to add new operations. • In OO programming with visitors: – It is easy to add new operations. – It is hard to add new data variants. • In OO programming with instance-of / cast: – It is easy to add new operations. – It is easy to add new data variants. 34 Forthcoming!
  • 16. (C) 2010-2013 Ralf Lämmel Operation extensibility based on visitors PREVIEW • class Expr:The base class of all expression forms • Subclasses as before. • Virtual methods: • Accept a visitor (“apply an operation”) • Visitors: • class PrettyPrinter: operation for pretty-printing • class Evaluator: operation for expression evaluation • ... Operation extensibility 35
  • 18. (C) 2010-2013 Prof. Dr. Ralf Lämmel, Universität Koblenz-Landau (where applicable) A book recommendation
  • 19. (C) 2010-2013 Prof. Dr. Ralf Lämmel, Universität Koblenz-Landau (where applicable) Elevator speech Q: How can we add functionality to a given (perhaps even closed) class hierarchy such that behavior can vary across concrete classes? A: Represent an operation to be performed on the elements of an object structure in a class separate from the given classes.
  • 20. (C) 2010-2013 Prof. Dr. Ralf Lämmel, Universität Koblenz-Landau (where applicable) Adding an operation to lists interface List {} class Nil implements List {} class Cons implements List { int head; List tail; } Now suppose we need functionality to compute the sum of a list.
  • 21. (C) 2010-2013 Prof. Dr. Ralf Lämmel, Universität Koblenz-Landau (where applicable) 1st attempt: instance-of and type cast List l = ...; int sum = 0; // contains the sum after the loop boolean proceed = true; while (proceed) { if (l instanceof Nil) proceed = false; else if (l instanceof Cons) { sum = sum + ((Cons) l).head; // Type cast! l = ((Cons) l).tail; // Type cast! } } What are the problems here?
  • 22. (C) 2010-2013 Prof. Dr. Ralf Lämmel, Universität Koblenz-Landau (where applicable) 1st attempt: instance-of and type cast Casts are evil! Requirement: static type checking http://en.wikipedia.org/wiki/File:Codex_Gigas_devil.jpg
  • 23. (C) 2010-2013 Prof. Dr. Ralf Lämmel, Universität Koblenz-Landau (where applicable) 2nd attempt: virtual methods What are the problems here? interface List { int sum(); } class Nil implements List { public int sum() { return 0; } } class Cons implements List { int head; List tail; public int sum() { return head + tail.sum(); } }
  • 24. (C) 2010-2013 Prof. Dr. Ralf Lämmel, Universität Koblenz-Landau (where applicable) 2nd attempt: virtual methods Patching is evil! Requirement: operation extensibility http://en.wikipedia.org/wiki/File:Codex_Gigas_devil.jpg
  • 25. (C) 2010-2013 Prof. Dr. Ralf Lämmel, Universität Koblenz-Landau (where applicable) 3rd attempt: the visitor pattern Part I: An interface for operations interface Visitor { void visitNil(Nil x); void visitCons(Cons x); }
  • 26. (C) 2010-2013 Prof. Dr. Ralf Lämmel, Universität Koblenz-Landau (where applicable) 3rd attempt: the visitor pattern Part II: Classes that accept visitorsinterface List { void accept(Visitor v); } class Nil implements List { public void accept(Visitor v) { v.visitNil(this); } } class Cons implements List { int head; List tail; public void accept(Visitor v) { v.visitCons(this); } }
  • 27. (C) 2010-2013 Prof. Dr. Ralf Lämmel, Universität Koblenz-Landau (where applicable) 3rd attempt: the visitor pattern Part III: A concrete visitor class SumVisitor implements Visitor { int sum = 0; public void visitNil(Nil x) {} public void visitCons(Cons x){ sum = sum + x.head; x.tail.accept(this); } }
  • 28. (C) 2010-2013 Prof. Dr. Ralf Lämmel, Universität Koblenz-Landau (where applicable) 3rd attempt: the visitor pattern Demo SumVisitor sv = new SumVisitor(); l.accept(sv); System.out.println(sv.sum);
  • 29. (C) 2010-2013 Prof. Dr. Ralf Lämmel, Universität Koblenz-Landau (where applicable) Summary so far Frequent type casts? Frequent recompilation? Instanceof and type casts Yes No Dedicated methods No Yes The Visitor pattern No No What if we need a new class?
  • 30. (C) 2010-2013 Prof. Dr. Ralf Lämmel, Universität Koblenz-Landau (where applicable) Summary so far • Class hierarchy implements virtual accept. • A Visitor object has a visit method for each class. • Double dispatch: • accept method takes a specific Visitor object. • accept redirects to class-specific visit method. Two levels of polymorphism
  • 31. (C) 2010-2013 Prof. Dr. Ralf Lämmel, Universität Koblenz-Landau (where applicable) The Visitor pattern: generic solution http://en.wikipedia.org/wiki/File:VisitorClassDiagram.svg
  • 32. (C) 2010-2013 Prof. Dr. Ralf Lämmel, Universität Koblenz-Landau (where applicable) Applicability An object structure contains different classes of objects with different interfaces and operations on these objects depend on their concrete classes. Many unrelated operations need to be performed on the objects and you want to keep related operations together. The classes defining the object structure rarely change, but you want to define new operations over the structure. (If the object structure classes change often, it is better to define the operations in those classes.)
  • 33. (C) 2010-2013 Ralf Lämmel Operation extensibility based on visitors • class Expr:The base class of all expression forms • Subclasses as before. • Virtual methods: • Accept a visitor (“apply an operation”) • Visitors: • class PrettyPrinter: operation for pretty-printing • class Evaluator: operation for expression evaluation • ... Operation extensibility 52
  • 34. (C) 2010-2013 Ralf Lämmel /** * The base class of all expression forms */ public abstract class Expr { /* * Accept a visitor (i.e., apply an operation) */ public abstract <R> R accept(Visitor<R> v); } Domain operations are no longer hosted in domain classes. 53
  • 35. (C) 2010-2013 Ralf Lämmel54 Intermezzo: visitor types • Returning visitors • Visit methods have a return type. • Void visitors • Visit methods are void. In principle, void visitors are sufficient because one can always (and often has to) aggregate the result through state which is ultimately to be returned through a designated getter.
  • 36. (C) 2010-2013 Ralf Lämmel /** * A concrete visitor describe a concrete operation on expressions. * There is one visit method per type in the class hierarchy. */ public abstract class Visitor<R> { public abstract R visit(Lit x); public abstract R visit(Add x); public abstract R visit(Neg x); } Requires folklore knowledge on design patterns. 55
  • 37. (C) 2010-2013 Ralf Lämmel /** * The expression form of "literals" (i.e., constants) */ public class Lit extends Expr { private int info; public int getInfo() { return info; } public void setInfo(int info) { this.info = info; } public <R> R accept(Visitor<R> v) { return v.visit(this); } } One visitor-enabled data variant. 56
  • 38. (C) 2010-2013 Ralf Lämmel /** * The expression form of "addition" */ public class Add extends Expr { private Expr left, right; public Expr getLeft() { return left; } public void setLeft(Expr left) { this.left = left; } public Expr getRight() { return right; } public void setRight(Expr right) { this.right = right; } public <R> R accept(Visitor<R> v) { return v.visit(this); } } Another visitor-enabled data variant. Beware of code bloat! 57
  • 39. (C) 2010-2013 Ralf Lämmel /** * The expression form of "negation" */ public class Neg extends Expr { private Expr expr; public Expr getExpr() { return expr; } public void setExpr(Expr expr) { this.expr = expr; } public <R> R accept(Visitor<R> v) { return v.visit(this); } } Beware of code bloat! Yet another visitor-enabled data variant. 58
  • 40. (C) 2010-2013 Ralf Lämmel /** * Operation for pretty printing */ public class PrettyPrinter extends Visitor<String> { public String visit(Lit x) { return Integer.toString(x.getInfo()); } public String visit(Add x) { return x.getLeft().accept(this) + " + " + x.getRight().accept(this); } public String visit(Neg x) { return "- (" + x.getExpr().accept(this) + ")"; } } Beware of code bloat! An operation represented as a concrete visitor. 59
  • 41. (C) 2010-2013 Ralf Lämmel Beware of code bloat! Another operation represented as a concrete visitor. /** * Operation for expression evaluation */ public class Evaluator extends Visitor<Integer> { public Integer visit(Lit x) { return x.getInfo(); } public Integer visit(Add x) { return x.getLeft().accept(this) + x.getRight().accept(this); } public Integer visit(Neg x) { return - x.getExpr().accept(this); } } 60
  • 42. (C) 2010-2013 Prof. Dr. Ralf Lämmel, Universität Koblenz-Landau (where applicable) 101implementations javaComposition javaStatic javaInheritance javaVisitor
  • 43. (C) 2010-2013 Prof. Dr. Ralf Lämmel, Universität Koblenz-Landau (where applicable) Summary Try to modularize (say, separate concerns). Try to understand extensibility requirements. Avoid modularity exorcism. Take refactoring and testing very seriously. Please don’t print the slides, or print resource-friendly.
  • 44. Everything beyond this point is “for your information” only.
  • 46. (C) 2010-2013 Ralf Lämmel The notion of extensibility • The initial system I: • Provides operations o1, …, om. • Handles data variants d1, …, dn. • Consider any number of extensions e1, …, ek: – ei could be a data extension: • Introduce a new data variant. • Provide cases for all existing operations. – ei could be an operation extension: • Introduce a new operation. • Provide cases for all existing data variants. – Any extension can be factored into such primitive ones. • The fully extended system ek ( … (e1 (I))) 65
  • 47. (C) 2010-2013 Ralf Lämmel More on extensibility • Code-level extensibility: – Extensions can be modeled as code units. – Existing code units are never edited or cloned. • Separate compilation: – The extensions are compiled separately. • Statically type-checked extensibility: – The extension are statically type-checked separately. 66
  • 48. (C) 2010-2013 Ralf Lämmel Beyond Java • Functions and pattern matching à la SML, Haskell • Multi-file predicates in Prolog • Partial classes in C# • ... 67
  • 49. (C) 2010-2013 Ralf Lämmel A C# approach to extensibility • Use the partial class mechanism of C# • A class can be “declared” many times. • The list of members is accumulated. 68
  • 50. (C) 2010-2013 Ralf Lämmel The data slice 69 public abstract partial class Expr { } public partial class Lit : Expr { public int info; } public partial class Add : Expr { public Expr left, right; }
  • 51. (C) 2010-2013 Ralf Lämmel The evaluation slice 70 public abstract partial class Expr { public abstract int Evaluate(); } public partial class Lit { public override int Evaluate() { return info; } } public partial class Add { public override int Evaluate(){ return left.Evaluate() + right.Evaluate(); } }
  • 52. (C) 2010-2013 Ralf Lämmel The evaluation slice 71 public abstract partial class Expr { public abstract string PrettyPrint(); } public partial class Lit { public override string PrettyPrint() { return info.ToString(); } } public partial class Add { public override string PrettyPrint() { return left.PrettyPrint() + " + " + right.PrettyPrint(); } }
  • 53. (C) 2010-2013 Ralf Lämmel A data extension 72 public partial class Neg : Expr { public Expr expr; } public partial class Neg { public override string PrettyPrint() { return "- (" + expr.PrettyPrint() + ")"; } } public partial class Neg { public override int Evaluate() { return -expr.Evaluate(); } }
  • 54. (C) 2010-2013 Ralf Lämmel Discussion of the C# approach • Code extensibility only • All extension need to be compiled together. • Slices are not even checked independently. 73
  • 55. (C) 2010-2013 Ralf Lämmel A Haskell approach to operation extensibility • data type Expr:The union of all expression forms • Public constructors: • Lit:The expression form of "literals" • Add:The expression form of "addition" • Functions defined by pattern matching on Expr: • function prettyPrint: operation for pretty-printing • function evaluate: operation for expression evaluation • ... Operation extensibility 74
  • 56. (C) 2010-2013 Ralf Lämmel Algebraic data types of Haskell are closed! module Data where -- A data type of expression forms data Exp = Lit Int | Add Exp Exp 75 Algebraic data type Constructor Constructor component Constructor 2 constructor components
  • 57. (C) 2010-2013 Ralf Lämmel module PrettyPrinter where import Data -- Operation for pretty printing prettyPrint :: Exp -> IO () prettyPrint (Lit i) = putStr (show i) prettyPrint (Add l r) = do prettyPrint l; putStr " + "; prettyPrint r A new module can be designated to each new operation. 76 Operation defined by case discrimination Argument type Result type “side effect”
  • 58. (C) 2010-2013 Ralf Lämmel Another operation; another module. module Evaluator where import Data -- Operation for expression evaluation evaluate :: Exp -> Int evaluate (Lit i) = i evaluate (Add l r) = evaluate l + evaluate r 77
  • 59. (C) 2010-2013 Ralf Lämmel Discussion of the Haskell approach • Lack of encapsulation? • Only operation extensibility 78
  • 60. (C) 2010-2013 Ralf Lämmel A Prolog approach to extensibility • Define operations as predicates. • Model data variants through functors. • Achieve extensibility through “multi-file” predicates. 79
  • 61. (C) 2010-2013 Ralf Lämmel The initial program 80 :- multifile prettyPrint/2. prettyPrint(lit(I),S) :- string_to_atom(S,I). prettyPrint(add(L,R),S) :- prettyPrint(L,S1), prettyPrint(R,S2), format(string(S),"~s + ~s", [S1,S2]).
  • 62. (C) 2010-2013 Ralf Lämmel A data extension 81 :- multifile prettyPrint/2. :- multifile evaluate/2. prettyPrint(neg(E),S) :- prettyPrint(E,S1), format(string(S),"- (~s)",[S1]). evaluate(neg(E),I) :- evaluate(E,I1), I is - I1.
  • 63. (C) 2010-2013 Ralf Lämmel An operation extension 82 :- multifile evaluate/2. evaluate(lit(I),I). evaluate(add(L,R),I) :- evaluate(L,I1), evaluate(R,I2), I is I1 + I2.
  • 64. (C) 2010-2013 Ralf Lämmel Program composition 83 :- [ 'InitialProgram.pro' , 'OperationExtension.pro' , 'DataExtension.pro' ].
  • 65. (C) 2010-2013 Ralf Lämmel Discussion of the Prolog approach • Full extensibility • No descriptive overhead • Lack of static typing • Performance penalty 84
  • 66. (C) 2010-2013 Ralf Lämmel Solutions of the expression problem • Open classes in more dynamic languages (Smalltalk, etc.) • Extensible predicates in Prolog (code-level extensibility only) • Java, C# & Co. • Clever encodings (Torgersen, ECOOP 2004) • AOP-like Open classes (introductions) • .NET-like partial classes (code-level extensibility only) • Expanders (Warth et al., OOPSLA 2006) • JavaGI (Wehr et al., ECOOP 2007) • ... 85
  • 67. (C) 2010-2013 Prof. Dr. Ralf Lämmel, Universität Koblenz-Landau (where applicable) Summary on extensibility Wanted Data extensibility and Operation extensibility and Soft or strong static type checking and Separate compilation/deployment and Unanticipated extension and Configurability and Composability and Efficiency (“No distributed fat”)