the expression problem - uni koblenz-landaulaemmel/paradigms1011/...the expression problem •...
TRANSCRIPT
![Page 1: The Expression Problem - Uni Koblenz-Landaulaemmel/paradigms1011/...The Expression Problem • Program = data + operations. • There could be many data variants. E.g.: expression](https://reader033.vdocument.in/reader033/viewer/2022042311/5ed917696714ca7f47692216/html5/thumbnails/1.jpg)
Ralf LämmelSoftware Language Engineer
University of Koblenz-LandauGermany
The Expression Problem
1
![Page 2: The Expression Problem - Uni Koblenz-Landaulaemmel/paradigms1011/...The Expression Problem • Program = data + operations. • There could be many data variants. E.g.: expression](https://reader033.vdocument.in/reader033/viewer/2022042311/5ed917696714ca7f47692216/html5/thumbnails/2.jpg)
© 2010 Ralf Lämmel
Demo of an expression languagesusceptible to the expression problem
2
> let x = Const 40
> let y = Const 2
> let z = Add x y
> prettyPrint z
"40 + 2"
> evaluate z
42
![Page 3: The Expression Problem - Uni Koblenz-Landaulaemmel/paradigms1011/...The Expression Problem • Program = data + operations. • There could be many data variants. E.g.: expression](https://reader033.vdocument.in/reader033/viewer/2022042311/5ed917696714ca7f47692216/html5/thumbnails/3.jpg)
© 2010 Ralf Lämmel
The Expression Problem
• Program = data + operations.
• There could be many data variants.
E.g.: expression forms: constant, addition.
• There could be many operations.
They dispatch on and recurse into data.
E.g.: pretty printing, evaluation.
• Data & operations should be extensible!
3
![Page 4: The Expression Problem - Uni Koblenz-Landaulaemmel/paradigms1011/...The Expression Problem • Program = data + operations. • There could be many data variants. E.g.: expression](https://reader033.vdocument.in/reader033/viewer/2022042311/5ed917696714ca7f47692216/html5/thumbnails/4.jpg)
© 2010 Ralf Lämmel
Extensibility
Static type safety
Separatecompilation
Code-level modularization
4
![Page 5: The Expression Problem - Uni Koblenz-Landaulaemmel/paradigms1011/...The Expression Problem • Program = data + operations. • There could be many data variants. E.g.: expression](https://reader033.vdocument.in/reader033/viewer/2022042311/5ed917696714ca7f47692216/html5/thumbnails/5.jpg)
© 2010 Ralf Lämmel
Pretty printing and evaluating expressions
with Haskell
5
![Page 6: The Expression Problem - Uni Koblenz-Landaulaemmel/paradigms1011/...The Expression Problem • Program = data + operations. • There could be many data variants. E.g.: expression](https://reader033.vdocument.in/reader033/viewer/2022042311/5ed917696714ca7f47692216/html5/thumbnails/6.jpg)
© 2010 Ralf Lämmel
6
module Data where
data Expr = Const Int | Add Expr Expr
Data variants
![Page 7: The Expression Problem - Uni Koblenz-Landaulaemmel/paradigms1011/...The Expression Problem • Program = data + operations. • There could be many data variants. E.g.: expression](https://reader033.vdocument.in/reader033/viewer/2022042311/5ed917696714ca7f47692216/html5/thumbnails/7.jpg)
© 2010 Ralf Lämmel
7
module PrettyPrinter where
import Data
prettyPrint :: Expr -> StringprettyPrint (Const i) = show iprettyPrint (Add l r) = prettyPrint l ++ " + " ++ prettyPrint r
One operation
![Page 8: The Expression Problem - Uni Koblenz-Landaulaemmel/paradigms1011/...The Expression Problem • Program = data + operations. • There could be many data variants. E.g.: expression](https://reader033.vdocument.in/reader033/viewer/2022042311/5ed917696714ca7f47692216/html5/thumbnails/8.jpg)
© 2010 Ralf Lämmel
8
module Evaluator where
import Data
evaluate :: Expr -> Intevaluate (Const i) = ievaluate (Add l r) = evaluate l + evaluate r
Another operation
![Page 9: The Expression Problem - Uni Koblenz-Landaulaemmel/paradigms1011/...The Expression Problem • Program = data + operations. • There could be many data variants. E.g.: expression](https://reader033.vdocument.in/reader033/viewer/2022042311/5ed917696714ca7f47692216/html5/thumbnails/9.jpg)
© 2010 Ralf Lämmel
9
Evaluator
PrettyPrinter
Data
![Page 10: The Expression Problem - Uni Koblenz-Landaulaemmel/paradigms1011/...The Expression Problem • Program = data + operations. • There could be many data variants. E.g.: expression](https://reader033.vdocument.in/reader033/viewer/2022042311/5ed917696714ca7f47692216/html5/thumbnails/10.jpg)
© 2010 Ralf Lämmel
10
Some expression formswith pretty printing
More expression formswith pretty printing
Some expression formswith pretty printing and expression evaluation
!
Operationextension "
Dataextension
![Page 11: The Expression Problem - Uni Koblenz-Landaulaemmel/paradigms1011/...The Expression Problem • Program = data + operations. • There could be many data variants. E.g.: expression](https://reader033.vdocument.in/reader033/viewer/2022042311/5ed917696714ca7f47692216/html5/thumbnails/11.jpg)
© 2010 Ralf Lämmel
11
It’s easy to add operations in basic functional programming; it’s not so easy to add data variants (without touching existing code).
![Page 12: The Expression Problem - Uni Koblenz-Landaulaemmel/paradigms1011/...The Expression Problem • Program = data + operations. • There could be many data variants. E.g.: expression](https://reader033.vdocument.in/reader033/viewer/2022042311/5ed917696714ca7f47692216/html5/thumbnails/12.jpg)
© 2010 Ralf Lämmel
Pretty printing and evaluating expressions
with C#
12
![Page 13: The Expression Problem - Uni Koblenz-Landaulaemmel/paradigms1011/...The Expression Problem • Program = data + operations. • There could be many data variants. E.g.: expression](https://reader033.vdocument.in/reader033/viewer/2022042311/5ed917696714ca7f47692216/html5/thumbnails/13.jpg)
© 2010 Ralf Lämmel
13
public abstract class Expr { } public class Const : Expr { public int info; } public class Add : Expr { public Expr left, right; }
The initial data variantswithout any operations
![Page 14: The Expression Problem - Uni Koblenz-Landaulaemmel/paradigms1011/...The Expression Problem • Program = data + operations. • There could be many data variants. E.g.: expression](https://reader033.vdocument.in/reader033/viewer/2022042311/5ed917696714ca7f47692216/html5/thumbnails/14.jpg)
© 2010 Ralf Lämmel
14
public abstract class Expr { public abstract string PrettyPrint(); } public class Const : Expr { public int info; public override string PrettyPrint() { return info.ToString(); } } public class Add : Expr { public Expr left, right; public override string PrettyPrint() { return left.PrettyPrint() + " + " + right.PrettyPrint(); } }
An initial program with classes for
initial data variants and one operation
![Page 15: The Expression Problem - Uni Koblenz-Landaulaemmel/paradigms1011/...The Expression Problem • Program = data + operations. • There could be many data variants. E.g.: expression](https://reader033.vdocument.in/reader033/viewer/2022042311/5ed917696714ca7f47692216/html5/thumbnails/15.jpg)
© 2010 Ralf Lämmel
15
public class Neg : Expr { public Expr operand; public override string PrettyPrint() { return "- (" + operand.PrettyPrint() +")"; } }
A data extension
![Page 16: The Expression Problem - Uni Koblenz-Landaulaemmel/paradigms1011/...The Expression Problem • Program = data + operations. • There could be many data variants. E.g.: expression](https://reader033.vdocument.in/reader033/viewer/2022042311/5ed917696714ca7f47692216/html5/thumbnails/16.jpg)
© 2010 Ralf Lämmel
16
Data extension fornegation
Initial data variants with pretty printing
![Page 17: The Expression Problem - Uni Koblenz-Landaulaemmel/paradigms1011/...The Expression Problem • Program = data + operations. • There could be many data variants. E.g.: expression](https://reader033.vdocument.in/reader033/viewer/2022042311/5ed917696714ca7f47692216/html5/thumbnails/17.jpg)
© 2010 Ralf Lämmel
17
Some expression formswith pretty printing
More expression formswith pretty printing
Some expression formswith pretty printing and expression evaluation
!Operationextension
"
Dataextension
![Page 18: The Expression Problem - Uni Koblenz-Landaulaemmel/paradigms1011/...The Expression Problem • Program = data + operations. • There could be many data variants. E.g.: expression](https://reader033.vdocument.in/reader033/viewer/2022042311/5ed917696714ca7f47692216/html5/thumbnails/18.jpg)
© 2010 Ralf Lämmel
18
It’s easy to add data variants in basic OO programming; it’s not so
easy to add operations (without touching existing code).
![Page 19: The Expression Problem - Uni Koblenz-Landaulaemmel/paradigms1011/...The Expression Problem • Program = data + operations. • There could be many data variants. E.g.: expression](https://reader033.vdocument.in/reader033/viewer/2022042311/5ed917696714ca7f47692216/html5/thumbnails/19.jpg)
© 2010 Ralf Lämmel
Extensibility
Static type safety
Separatecompilation
Code-level modularization
19
![Page 20: The Expression Problem - Uni Koblenz-Landaulaemmel/paradigms1011/...The Expression Problem • Program = data + operations. • There could be many data variants. E.g.: expression](https://reader033.vdocument.in/reader033/viewer/2022042311/5ed917696714ca7f47692216/html5/thumbnails/20.jpg)
© 2010 Ralf Lämmel
Non-solutions in C#
20
• The Visitor Pattern
We get extensibility like in basic Haskell.
• Partial classes
Let’s pretend we want separate compilation!
• Cast-based type switch
Let’s pretend we want static type safety!
• Extension methods
We need virtual methods for extensibility!
![Page 21: The Expression Problem - Uni Koblenz-Landaulaemmel/paradigms1011/...The Expression Problem • Program = data + operations. • There could be many data variants. E.g.: expression](https://reader033.vdocument.in/reader033/viewer/2022042311/5ed917696714ca7f47692216/html5/thumbnails/21.jpg)
© 2010 Ralf Lämmel
Non-solution in C#:The Visitor Pattern
21
![Page 22: The Expression Problem - Uni Koblenz-Landaulaemmel/paradigms1011/...The Expression Problem • Program = data + operations. • There could be many data variants. E.g.: expression](https://reader033.vdocument.in/reader033/viewer/2022042311/5ed917696714ca7f47692216/html5/thumbnails/22.jpg)
© 2010 Ralf Lämmel
22
public interface Visitor<R> { R Visit(Const that); R Visit(Add that); }
The generic type of all operations
![Page 23: The Expression Problem - Uni Koblenz-Landaulaemmel/paradigms1011/...The Expression Problem • Program = data + operations. • There could be many data variants. E.g.: expression](https://reader033.vdocument.in/reader033/viewer/2022042311/5ed917696714ca7f47692216/html5/thumbnails/23.jpg)
© 2010 Ralf Lämmel
23
public class PrettyPrinter : Visitor<string> { public string Visit(Const that) { return that.info.ToString(); } public string Visit(Add that) { return !that.left.Accept(this) ! ! ! ! + ! " + " ! ! ! ! + ! that.right.Accept(this); } }
One operation
![Page 24: The Expression Problem - Uni Koblenz-Landaulaemmel/paradigms1011/...The Expression Problem • Program = data + operations. • There could be many data variants. E.g.: expression](https://reader033.vdocument.in/reader033/viewer/2022042311/5ed917696714ca7f47692216/html5/thumbnails/24.jpg)
© 2010 Ralf Lämmel
24
Another operation
public class Evaluator : Visitor<int> { public int Visit(Const that) { return that.info; } public int Visit(Add that) { return !that.left.Accept(this) ! ! ! ! + ! that.right.Accept(this); } }
![Page 25: The Expression Problem - Uni Koblenz-Landaulaemmel/paradigms1011/...The Expression Problem • Program = data + operations. • There could be many data variants. E.g.: expression](https://reader033.vdocument.in/reader033/viewer/2022042311/5ed917696714ca7f47692216/html5/thumbnails/25.jpg)
© 2010 Ralf Lämmel
25
public abstract class Expr { public abstract R Accept<R>(Visitor<R> v); } public class Const : Expr { public int info; public override R Accept<R>(Visitor<R> v) { return v.Visit(this); } } public class Add : Expr { public Expr left, right; public override R Accept<R>(Visitor<R> v) { return v.Visit(this); } }
Data variants with
accept
![Page 26: The Expression Problem - Uni Koblenz-Landaulaemmel/paradigms1011/...The Expression Problem • Program = data + operations. • There could be many data variants. E.g.: expression](https://reader033.vdocument.in/reader033/viewer/2022042311/5ed917696714ca7f47692216/html5/thumbnails/26.jpg)
© 2010 Ralf Lämmel
26
A riddle with visitors
Can we extend visitors to incorporate new
data variants?
![Page 27: The Expression Problem - Uni Koblenz-Landaulaemmel/paradigms1011/...The Expression Problem • Program = data + operations. • There could be many data variants. E.g.: expression](https://reader033.vdocument.in/reader033/viewer/2022042311/5ed917696714ca7f47692216/html5/thumbnails/27.jpg)
© 2010 Ralf Lämmel
Non-solution in C#:Partial classes
27
![Page 28: The Expression Problem - Uni Koblenz-Landaulaemmel/paradigms1011/...The Expression Problem • Program = data + operations. • There could be many data variants. E.g.: expression](https://reader033.vdocument.in/reader033/viewer/2022042311/5ed917696714ca7f47692216/html5/thumbnails/28.jpg)
© 2010 Ralf Lämmel
28
public abstract partial class Expr { } public partial class Const : Expr { public int info; } public partial class Add : Expr { public Expr left, right; }
The initial data variants
![Page 29: The Expression Problem - Uni Koblenz-Landaulaemmel/paradigms1011/...The Expression Problem • Program = data + operations. • There could be many data variants. E.g.: expression](https://reader033.vdocument.in/reader033/viewer/2022042311/5ed917696714ca7f47692216/html5/thumbnails/29.jpg)
© 2010 Ralf Lämmel
29
public abstract partial class Expr { public abstract string PrettyPrint(); } public partial class Const : Expr { public override string PrettyPrint() { return info.ToString(); } } public partial class Add : Expr { public override string PrettyPrint() { return left.PrettyPrint() + " + " + right.PrettyPrint(); } }
The initial pretty printer as an operation extension of the initial
data variants.
![Page 30: The Expression Problem - Uni Koblenz-Landaulaemmel/paradigms1011/...The Expression Problem • Program = data + operations. • There could be many data variants. E.g.: expression](https://reader033.vdocument.in/reader033/viewer/2022042311/5ed917696714ca7f47692216/html5/thumbnails/30.jpg)
© 2010 Ralf Lämmel
30
public abstract partial class Expr { public abstract int Evaluate(); } public partial class Const : Expr { public override int Evaluate() { return info; } } public partial class Add : Expr { public override int Evaluate() { return left.Evaluate() + right.Evaluate(); } }
The initial evaluator as an operation
extension of the initial data variants.
![Page 31: The Expression Problem - Uni Koblenz-Landaulaemmel/paradigms1011/...The Expression Problem • Program = data + operations. • There could be many data variants. E.g.: expression](https://reader033.vdocument.in/reader033/viewer/2022042311/5ed917696714ca7f47692216/html5/thumbnails/31.jpg)
© 2010 Ralf Lämmel
31
public partial class Neg : Expr { public Expr operand; public override string PrettyPrint() { return "- (" + operand.PrettyPrint() +")"; } public override int Evaluate() { return - operand.Evaluate(); } } A data
extension
![Page 32: The Expression Problem - Uni Koblenz-Landaulaemmel/paradigms1011/...The Expression Problem • Program = data + operations. • There could be many data variants. E.g.: expression](https://reader033.vdocument.in/reader033/viewer/2022042311/5ed917696714ca7f47692216/html5/thumbnails/32.jpg)
© 2010 Ralf Lämmel
Non-solution in C#:Cast-based type switch
32
![Page 33: The Expression Problem - Uni Koblenz-Landaulaemmel/paradigms1011/...The Expression Problem • Program = data + operations. • There could be many data variants. E.g.: expression](https://reader033.vdocument.in/reader033/viewer/2022042311/5ed917696714ca7f47692216/html5/thumbnails/33.jpg)
© 2010 Ralf Lämmel
33
public abstract class Expr { } public class Const : Expr { public int info; } public class Add : Expr { public Expr left, right; }
The initial data variants
![Page 34: The Expression Problem - Uni Koblenz-Landaulaemmel/paradigms1011/...The Expression Problem • Program = data + operations. • There could be many data variants. E.g.: expression](https://reader033.vdocument.in/reader033/viewer/2022042311/5ed917696714ca7f47692216/html5/thumbnails/34.jpg)
© 2010 Ralf Lämmel
34
public static class Evaluator { public static int Evaluate(Expr that) { var c = that as Const; if (c != null) return c.info; var a = that as Add; if (a != null) return Evaluate(a.left) + Evaluate(a.right); throw new ArgumentException(); } }
One operation
![Page 35: The Expression Problem - Uni Koblenz-Landaulaemmel/paradigms1011/...The Expression Problem • Program = data + operations. • There could be many data variants. E.g.: expression](https://reader033.vdocument.in/reader033/viewer/2022042311/5ed917696714ca7f47692216/html5/thumbnails/35.jpg)
© 2010 Ralf Lämmel
35
public class PrettyPrinter { public virtual string PrettyPrint(Expr that) { var c = that as Const; if (c != null) return c.info.ToString(); var a = that as Add; if (a != null) return PrettyPrint(a.left) + "+" + PrettyPrint(a.right); throw new ArgumentException(); } }
Another operation
![Page 36: The Expression Problem - Uni Koblenz-Landaulaemmel/paradigms1011/...The Expression Problem • Program = data + operations. • There could be many data variants. E.g.: expression](https://reader033.vdocument.in/reader033/viewer/2022042311/5ed917696714ca7f47692216/html5/thumbnails/36.jpg)
© 2010 Ralf Lämmel
36
public class Neg : Expr { public Expr operand; } public class PrettyPrinterWithNeg : PrettyPrinter { public override string PrettyPrint(Expr that) { try { return base.PrettyPrint(that); } catch (ArgumentException) { var n = that as Neg; if (n != null) return "- (" + PrettyPrint(n.operand) + ")"; throw new ArgumentException(); } } }
A data extension
![Page 37: The Expression Problem - Uni Koblenz-Landaulaemmel/paradigms1011/...The Expression Problem • Program = data + operations. • There could be many data variants. E.g.: expression](https://reader033.vdocument.in/reader033/viewer/2022042311/5ed917696714ca7f47692216/html5/thumbnails/37.jpg)
© 2010 Ralf Lämmel
Non-solution in C#:Extension methods
37
![Page 38: The Expression Problem - Uni Koblenz-Landaulaemmel/paradigms1011/...The Expression Problem • Program = data + operations. • There could be many data variants. E.g.: expression](https://reader033.vdocument.in/reader033/viewer/2022042311/5ed917696714ca7f47692216/html5/thumbnails/38.jpg)
© 2010 Ralf Lämmel
38
public abstract class Expr { } public class Const : Expr { public int info; } public class Add : Expr { public Expr left, right; }
The initial data variants
![Page 39: The Expression Problem - Uni Koblenz-Landaulaemmel/paradigms1011/...The Expression Problem • Program = data + operations. • There could be many data variants. E.g.: expression](https://reader033.vdocument.in/reader033/viewer/2022042311/5ed917696714ca7f47692216/html5/thumbnails/39.jpg)
© 2010 Ralf Lämmel
39
public static class PrettyPrinter { public static string PrettyPrint(this Const that) { return that.info.ToString(); } public static string PrettyPrint(this Add that) { return that.left.PrettyPrint() + " + " + that.right.PrettyPrint(); } }
One operation
Requires dispatch!
![Page 40: The Expression Problem - Uni Koblenz-Landaulaemmel/paradigms1011/...The Expression Problem • Program = data + operations. • There could be many data variants. E.g.: expression](https://reader033.vdocument.in/reader033/viewer/2022042311/5ed917696714ca7f47692216/html5/thumbnails/40.jpg)
© 2010 Ralf Lämmel
40
Summary
How are we supposed to design a program so that we can achieve both data extensibility
and operation extensibility? What language concepts help us to achieve both
dimensions of extensibility (and separate compilation and static type safety)?
An informal definition of “Expression Problem”
![Page 41: The Expression Problem - Uni Koblenz-Landaulaemmel/paradigms1011/...The Expression Problem • Program = data + operations. • There could be many data variants. E.g.: expression](https://reader033.vdocument.in/reader033/viewer/2022042311/5ed917696714ca7f47692216/html5/thumbnails/41.jpg)
© 2010 Ralf Lämmel
41
Further reading
• Phil Wadler’s seminal email on the problem
http://www.daimi.au.dk/~madst/tool/papers/expression.txt
• Clever encodings (Torgersen, ECOOP 2004)
• Open classes (AspectJ et al.)
• Expanders (Warth et al., OOPSLA 2006)
• JavaGI (Wehr et al., ECOOP 2007)
• Haskell’s type classes (Lämmel, Ostermann, GPCE 2006)
• ...
![Page 42: The Expression Problem - Uni Koblenz-Landaulaemmel/paradigms1011/...The Expression Problem • Program = data + operations. • There could be many data variants. E.g.: expression](https://reader033.vdocument.in/reader033/viewer/2022042311/5ed917696714ca7f47692216/html5/thumbnails/42.jpg)
© 2010 Ralf Lämmel
Thanks!Questions and comments welcome.
42