代码之家  ›  专栏  ›  技术社区  ›  jhegedus

在保留Elm的高级抽象的同时,是否可以将Mario示例从Elm转换为纯JavaFX或JavaFX+RxJava?

  •  5
  • jhegedus  · 技术社区  · 12 年前

    我最近看到 this 关于Elm中的反应式编程的有趣演示。

    这让我怀疑,用于实现马里奥游戏的语言结构(在所示的演示文稿中,以及下图中)是否可以映射到类似的 高水位,高水位 纯JavaFX或与RxJava结合的JavaFX语言构造?

    换言之,是否可以单独使用JavaFX或JavaFX+RxJava使用相同的概念抽象(即时间相关值)来表达在Elm中实现的马里奥游戏?

    因此,如果一位经验丰富的1)JavaFX程序员或2)JavaFX+RxJava+功能性程序员想要将马里奥游戏从Elm移植到1)JavaFX或2)Java FX+RxJava,那么哪个程序员可以通过以下方式完成这项任务 使用类似的高级抽象 就像在Elm使用的那样?

    对于JavaFX,我想到的抽象是绑定,对于JavaFX+RxJava,抽象是绑定+Observables/Subjects/Subscription。

    enter image description here

    4 回复  |  直到 12 年前
        1
  •  7
  •   Tomas Mikula    12 年前

    我很快看了一下Elm,它给人留下了深刻的印象(而且富有表现力)。

    在Elm中,您将场景构造为

    Signal Element
    

    这在JavaFX中大致相当于

    ObservableValue<Node>
    

    简单地转换为JavaFX意味着每次更新都要交换整个场景,这代价高昂。在Elm, Element 是场景节点的不可变抽象表示,在屏幕外(在DOM外)构建。在每次更新时重新创建整个场景图是足够便宜的(由于不变性,重用未更改的分支是安全的)。根 要素 被呈现为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 records 非常强大,需要 大量 Java中的样板 (或Scala) .

    榆树:

    type Point = { x:Float, y:Float }
    
    p = { 0.0, 0.0 }
    q = { p | x <- 5.0 }
    

    Java语言:

    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)
    
        2
  •  4
  •   jewelsea    12 年前

    我说这是可能的,但实际上没有做到:-)

    这只是一个猜测,因为我在这个领域几乎没有经验,而且根本没有埃尔姆的经验。

    我认为通过为 ReactFX ,不过您也可以将Java 8 lambdas与ReactFX结合使用,而不是Scala。您可能需要对ReactFX以及其他各种设施实现相当多的扩展,以获得所需的抽象和优雅。

    结账 Deprecating the Observer Pattern 如果你还没有这样做的话。我认为这与本主题非常相关,特别是关于思考反应式编程模型而不是可观察模型(这就是JavaFX ChangeListeners 是)。也就是说,我认为如果您使用基于JavaFX属性和侦听器框架的ReactFX等库,那么您可能会得到对反应式编程有用的事件流的更高级别抽象。

    当然,你可以在不使用ReactFX的情况下用JavaFX制作马里奥游戏,但代码会非常不同,你将在与ReactFX不同的抽象级别上工作。因此,如果没有ReactFX,纯JavaFX就不像Elm了。

    对于网络层, akka 可以用于为多玩家游戏提供反应式框架,这将允许您在UI和通信系统中从上到下使用反应式编程。

    对于马里奥示例中的精灵动画,采用netopyr代码 Creating a Sprite Animation with JavaFX .

    对于物理计算,您可以使用 JBox2D 图书馆您需要围绕JBox2D创建某种反应式包装器,以使其了解JavaFX财产和ReactFX事件流和订阅等内容。对于简单化的马里奥示例,使用外部库可能会比它的价值更麻烦。相反,你可以使用基本的自制物理模型(例如 ball animation experiment )并将其连接到您的反应框架中。

    我建议与创建ReactFX的Tomas Mikula联系,并向他询问JavaFX的反应式编程问题。 Robert Ladstätter 他还用ScalaFX做了一些很酷的事情,也许能给你一些进一步的建议,尽管我不知道他是否使用过Reactive编程。我还建议 ScalaFX users forums ,但我知道你已经做到了:-)

    这个 Elm Mario sample 非常简单,所以我建议您自己尝试翻译成ReactFX。那么我认为你的问题的答案将变得不言自明。现在我已经写了这个=>如果你没有真正实现它,并将你的解决方案作为正确答案发布,我可能会找你,你不会想要的:-)

        3
  •  4
  •   Roamer-1888    9 年前

    我目前正在比较传统的面向对象GUI编程和函数式GUI编程,以备硕士论文之用。事实上,我不久将要开始的一部分是使用Elm在JavaFX/ScalaFX中重新创建许多传统的GUI程序。当我完成这项工作后,我可能会给出一个更精确的答案,但我现在仍然想提供一些通常有用的指导。


    首先,有两篇很好的论文概述了FRP景观,即 “A Survey on Reactive Programming“ “Towards Reactive Programming for Object-oriented Applications” 前者尤其提供了FRP系统的分类法,区分了FRP的兄弟姐妹和FRP的兄弟姊妹(暗示他们与 Fran ). FRP的兄弟姐妹专注于 时变值 ,玻璃钢的表兄弟专注于 事件流、可观察集合和异步 并且对于时变值的表示没有原始抽象。考虑到这种区别, Elm是FRP的兄弟姐妹 RxJava/RreactFX是FRP的表亲 我想你可以说他们是 不同的动物 尽管两者都是FRP系统,自然也有重叠。

    第二,论文 “Crossing State Lines: Adapting Object-Oriented Frameworks to Functional Reactive Languages” 对Elm中的FRP方法与JavaFX中的传统OOP方法之间的差异进行了非常简洁的总结:

    OO使状态显式,但将其封装,而FRP中的状态隐藏 通过语言的时间抽象。

    因此,程序设计有一种根本不同的方法。因此,对我来说,目前还不清楚是否以及如何使用JavaFX(+RxJava/RactFX)实现与Elm相同的高级抽象。这并不意味着这是不可能的,但乍一看并不明显。

    最后,从我的论文中,对Elm及其与传统OOP方法的极端差异进行了一般性观察,以明确在JavaFX中实现相同结果的障碍:

    许多GUI库(即使是纯函数语言)本质上是一个 在(强制的)面向对象GUI工具包上使用薄垫片。这意味着 例如,小部件不是纯函数。小工具具有状态,因此 身份。如果我们隐喻性地打开GUI工具箱的功能旋钮 控制板达到其最大值时,我们必须达到以下情况: 这些小部件只是纯函数。榆树就是这样一个例子 同时提供最大功能语言和GUI工具包。作为回调 都是关于副作用的Elm自然不会使用回调 行为相关代码,而不是FRP。OOP语言中的自定义 在Elm中,只有 函数组合。。。

    关键是,在Elm中,视图是纯函数,基本上,Elm迫使您以这种方式构造代码。在JavaFX中,你不是被迫的,所以你必须小心去做。

    顺便说一下,有一个 game skeleton 像马里奥这样的Elm游戏。您可以研究它并思考如何按照这个框架设计JavaFX程序。也许你可以在学习之后为JavaFX创建这样一个框架?我会感兴趣的。

        4
  •  2
  •   Community Mohan Dere    9 年前

    我一年前就提出过这个问题。从那以后,我对玻璃钢有所了解。我认为答案是否定的,至少RX不容易,使用JavaFX会更好+ Sodium FRP 图书馆

    为什么RX不可能(非常容易)?因为ELM是FRP,而RX是FRP 交易(模糊地说)。因此,实际上,如果有人想在ELM中实现马里奥游戏,那么她必须向RX添加事务(以避免 glitches ).

    推荐文章