I'm studying the expression problem at the moment and it seems like I'm missing something. I used a data-centered approach (i.e. OOP) as the basic setup and then introduced two type variables, one for each operand in Add
. These type variables are bounded to subtypes of Exp
- this constraint is further narrowed down, when a new operation is added. For example in Java this would look like this:
interface Exp {
int eval();
}
class Lit implements Exp {
int value;
public Lit(int value) {
this.value = value;
}
@Override
public int eval() {
return this.value;
}
}
class Add<T extends Exp, U extends Exp> implements Exp {
public T e1;
public U e2;
public Add(T e1, U e2) {
this.e1 = e1;
this.e2 = e2;
}
@Override
public int eval() {
return this.e1.eval() + this.e2.eval();
}
}
interface ExpP extends Exp {
String print();
}
class LitP extends Lit implements ExpP {
LitP(int value) {
super(value);
}
@Override
public String print() {
return "" + this.value;
}
}
class AddP<T extends ExpP, U extends ExpP> extends Add<T, U> implements ExpP {
AddP(T e1, U e2) {
super(e1, e2);
}
@Override
public String print() {
return this.e1.print() + " + " + this.e2.print();
}
}
public class Main {
public static void main(String[] args) {
ExpP add2to3 = new AddP<>(new LitP(2), new LitP(3));
System.out.println(add2to3.print() + " = " + add2to3.eval());
}
}
Now, type parameterization is a very obvious and simple approach, so there must be something wrong with it. Which requirement does this (non-)solution violate?
I'm aware of correct solutions like The Expression Problem, Trivially! and The Expression Problem Revisited, which are similar in structure. I merely strive for a better understanding of the topic.
Exp
s! How do you printExp
expressions? $\endgroup$