我快速浏览了 Elm,它给人留下了深刻的印象(并且富有表现力)。
在 Elm 中,您将场景构建为
Signal Element
在 JavaFX 中大致相当于
ObservableValue<Node>
对 JavaFX 的幼稚转换意味着您在每次更新时交换整个场景,这是非常昂贵的。在 Elm 中,Element
是场景节点的不可变抽象表示,在屏幕外(DOM 外)构建。在每次更新时重新创建整个场景图是足够便宜的(由于不变性,重用未更改的分支是安全的)。根Element
被渲染到 DOM,但是,据我所知,只有第一次构建完整的 DOM。在随后的更新中,Elm 运行时会运行一种算法来比较新根元素和旧根元素,并且只修改 DOM 中需要更新的那些部分,这已经足够快了。React.js使用了相同的技术. 因此,Elm 和 React.js 都提供了高级功能抽象,但出于性能原因,在后台使用了可变性。
使用一些额外的语法噪音,您可以将大多数 Elm 构造转换为 JavaFX (*)。例如,
lift2 display Window.dimensions gameState
相当于
import static org.fxmisc.EasyBind.*;
combine(Window.dimensions, gameState, display)
缺少的部分是不可变的抽象小部件表示库以及它们在 JavaFX 场景图中的有效呈现。
你可以做的是:
- 为 JavaFX 创建这样一个小部件库;
- 甚至将 Elm 编译为 JavaFX(而不是 HTML+JavaScript)。
我很想看到其中任何一个完成。
(*) 我认为 Elm记录非常强大,在 Java 中需要大量样板文件(或斯卡拉).
榆树:
type Point = { x:Float, y:Float }
p = { 0.0, 0.0 }
q = { p | x <- 5.0 }
爪哇:
class Point {
public final float x;
public final float y;
public Point(float x, float y) {
this.x = x;
this.y = y;
}
public Point updateX(float x) {
return new Point(x, y);
}
public Point updateY(float y) {
return new Point(x, y);
}
}
Point p = new Point(0.0, 0.0);
Point q = p.updateX(5.0);
斯卡拉:
case class Point(x: Float, y: Float)
val p = Point(0.0, 0.0)
val q = p.copy(x = 5.0f)