【发布时间】:2021-06-03 08:45:24
【问题描述】:
我目前正在阅读论文 Extensibility for the Masses。 Bruno C. d. 对象代数的实用可扩展性 S. Oliveira 和 William R. Cook(可在互联网上的许多地方找到 - 例如这里:https://www.cs.utexas.edu/~wcook/Drafts/2012/ecoop2012.pdf)。
在第 10 页,他们写道:
添加新的数据变体很容易。第一步是创建新类
Bool和Iff采用通常的面向对象风格(如Lit和Add):class Bool implements Exp {...} class Iff implements Exp {...}
Exp 的实现似乎留给读者作为练习。但是,我不清楚本文的这一部分是如何定义 Exp 的。我的问题是:
Bool和Iff应该如何实现?
这是我尝试过的:
Exp 的第一个定义
在论文的早期,Exp 接口是这样定义的:
interface Exp {
Value eval();
}
这里,Value 是由另一个接口定义的:
interface Value {
Integer getInt();
Boolean getBool();
}
然而,这篇论文很快就偏离了Exp 的定义,转而支持基于访问者的定义。
Bool 的可能实现
基于该定义,应该如何实现Bool 类?
这样的事情似乎是一个开始:
class Bool implements Exp {
boolean x;
public Bool(boolean x) { this.x = x; }
public Value eval() {
return new VBool(x);
}}
然而,问题变成了如何正确实现Value?
论文只显示了这一点:
class VBool implements Value {...}
在我看来,实现并不完全:
class VBool implements Value {
boolean x;
public VBool(boolean x) { this.x = x; }
public Boolean getBool() {
return new Boolean(x);
}
public Integer getInt() {
// What to return here?
}
}
正如我上面的尝试所示,尚不清楚从getInt 返回什么。我想我可以返回 null 或抛出异常,但这意味着我的实现是partial。
无论如何,Exp 的第一个定义似乎仅作为论文中的一个激励示例存在,然后继续定义更好的替代方案。
Exp的第二个定义
在第 4 页,论文将Exp 重新定义为内部访问者:
interface Exp {
<A> A accept(IntAlg<A> vis);
}
其中IntAlg<A>是另一个接口:
interface IntAlg<A> {
A lit(int x);
A add(A e1, A e2);
}
到目前为止,事情似乎很清楚,直到我们开始实施 Bool 和 Iff...
Bool 的可能实现
我们应该如何基于Exp的这个定义来实现提议的Bool类?
class Bool implements Exp {
boolean x;
public Bool(boolean x) { this.x = x; }
public <A> A accept(IntAlg<A> vis) {
// What to return here?
}}
没有办法凭空变出A 值,因此必须与vis 交互才能产生A 值。但是,vis 参数只定义了lit 和add 方法。
lit 方法需要 int,而 Bool 中没有。
同样,add 需要 两个 A 值,这也是不可用的。再一次,我发现自己陷入了僵局。
Exp的第三个定义?
然后,在第 8 页,论文展示了这个例子:
int x = exp(base).eval();
这里,exp(base) 返回Exp,但这是eval 的哪个定义?
显然,Exp 仍然(或再次?)有一个 eval 方法,但现在它返回 int。是这样的吗?
interface Exp {
int eval();
}
论文没有显示这个定义,所以我可能误解了一些东西。
Bool 的可能实现
我们可以用Exp的这个定义来实现Bool和Iff吗?
class Bool implements Exp {
boolean x;
public Bool(boolean x) { this.x = x; }
public int eval() {
// What to return here?
}}
同样,不清楚如何实现接口。当然,可以返回0 为假,1 为真,但这只是一个任意决定。这似乎不合适。
我缺少Exp 的第四个定义吗?或者论文中是否还有其他一些信息让我无法理解?
顺便说一句,如果我在尝试中犯了错误,我深表歉意。我通常不写 Java 代码。
【问题讨论】:
-
这个抽象根本就不是抽象。当我声明一个必须支持从
int到该类型并返回到int的“抽象类型”时,我只是声明了这个类型是一个int容器。这条线public A add(A x, A y) { return valFact.lit(x.getInt() + y.getInt()); }总是执行int加法,无论A是如何实现的,并且以不同方式实现int容器的可能性在实践中并没有真正的帮助。您已经在为VBool苦苦挣扎,但是如何添加,例如VString?我在本文中没有看到解决方案。 -
@Holger 你可能是对的。我正在看这篇论文,因为每次我在互联网上提到表达问题时,总是有人向我扔这篇论文。我试图弄清楚它是否有任何实质内容。我开始以开放的心态阅读,但现在,由于我在这里概述的问题,我在围栏上。
标签: oop computer-science extensibility