2014-04-01 14 views
5

Gần đây tôi đã xem this bài thuyết trình thú vị về lập trình phản ứng trong Elm.Có thể dịch ví dụ Mario từ Elm sang JavaFX thuần túy hoặc sang JavaFX + RxJava trong khi vẫn giữ được mức trừu tượng cao của Elm không?

Điều này khiến tôi băn khoăn liệu cấu trúc ngôn ngữ được sử dụng để triển khai trò chơi Mario (trong bản trình bày được hiển thị và cũng như trong hình bên dưới) có thể được ánh xạ tới các cấu trúc ngôn ngữ cao cấp tương đương trong JavaFX hoặc JavaFX thuần túy với RxJava?

Nói cách khác, có thể diễn tả trò chơi Mario được triển khai trong Elm bằng cách sử dụng cùng một khái niệm trừu tượng (tức là các giá trị phụ thuộc thời gian) trong JavaFX đơn thuần hoặc trong JavaFX + RxJava không?

Vì vậy, nếu một lập trình viên JavaFX có kinh nghiệm 1) hoặc JavaFX + RxJava + Lập trình viên chức năng muốn chuyển trò chơi Mario từ Elm sang 1) JavaFX hoặc 2) JavaFX + RxJava thì lập trình viên nào có thể thực hiện tác vụ này bởi sử dụng các phép trừu tượng mức cao tương tự như đã được sử dụng trong Elm?

Tóm tắt mà tôi có trong đầu cho JavaFX là các ràng buộc và cho JavaFX + RxJava là các ràng buộc + Quan sát/Đối tượng/Đăng ký.

enter image description here

Trả lời

7

Tôi đã xem nhanh Elm và nó khá ấn tượng (và biểu cảm).

Trong Elm bạn xây dựng cảnh của bạn như

Signal Element 

mà trong JavaFX sẽ tương đương với

ObservableValue<Node> 

dịch Naive để JavaFX có nghĩa là bạn trao đổi toàn bộ quang cảnh trên mỗi lần cập nhật, mà là cực kỳ tốn kém. Trong Elm, Element là một đại diện trừu tượng bất biến của một nút cảnh, được tạo ra khỏi màn hình (ngoài DOM). Nó đủ rẻ để tái tạo toàn bộ đồ thị cảnh trên mỗi lần cập nhật (vì tính bất biến, an toàn để tái sử dụng các nhánh không thay đổi). Gốc Element được trả về DOM, nhưng, như tôi đã hiểu, chỉ lần đầu tiên DOM được xây dựng đầy đủ. Trên các bản cập nhật tiếp theo, thời gian chạy Elm chạy một thuật toán để so sánh phần tử gốc mới với phần tử cũ và chỉ sửa đổi các phần của DOM cần cập nhật, đủ nhanh. Kỹ thuật tương tự được sử dụng bởi React.js. Vì vậy, cả Elm và React.js đều cung cấp khả năng trừu tượng hóa chức năng ở mức cao, nhưng sử dụng khả năng biến đổi dưới các trình bao cho các lý do hiệu suất.

Với một số tiếng ồn cú pháp bổ sung, bạn có thể dịch hầu hết các cấu trúc Elm sang JavaFX (*). Ví dụ,

lift2 display Window.dimensions gameState 

tương đương với

import static org.fxmisc.EasyBind.*; 

combine(Window.dimensions, gameState, display) 

Các mảnh còn thiếu là thư viện của cơ quan đại diện phụ tùng trừu tượng bất biến và cung cấp hiệu quả của họ vào cảnh graph JavaFX.

gì bạn có thể làm là:

  • tạo ra như một thư viện widget cho JavaFX;
  • hoặc thậm chí biên dịch Elm thành JavaFX (thay vì HTML + JavaScript).

Tôi rất muốn xem một trong hai việc đó.


(*) Tôi nghĩ Elm records rất mạnh mẽ và sẽ đòi hỏi một nhiều của soạn sẵn trong Java (hoặc Scala).

Elm:

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); 

Scala:

case class Point(x: Float, y: Float) 

val p = Point(0.0, 0.0) 
val q = p.copy(x = 5.0f) 
+0

Câu trả lời rất chính xác cho thấy sự tương ứng giữa Elm và JavaFX! Câu trả lời này thậm chí sẽ giúp tôi trong luận án của tôi. (Btw, làm việc tốt trên ReactFX. Các ví dụ của nó trên [blog] của bạn (http://tomasmikula.github.io/blog/2014/04/25/combining-reactfx-and-asynchronous-processing.html) rất ấn tượng. đã lên kế hoạch một phần về ReactFX trong fyi luận án của tôi.) – Eugen

+0

Cảm ơn bạn đã trả lời chi tiết. Làm thế nào về dịch Elm xây dựng để JavaFX + RXJava? Điều đó sẽ dễ dàng hơn (ít lò hơi) so với việc dịch các cấu trúc Elm sang JavaFX? – jhegedus

+0

Tôi không nghĩ vậy. Các boilerplate là do Elm _language_ tính năng mất tích từ Java, như suy luận kiểu mạnh mẽ hơn, loại bí danh, loại bản ghi ... Không có thư viện Java sẽ thêm rằng vào ngôn ngữ. Các hàm thuần túy (tác dụng phụ) và các đối tượng bất biến không thể được thực thi trong Java, nhưng có thể đạt được bằng kỷ luật của riêng bạn. Các nút JavaFX có thể thay đổi theo thiết kế, vì vậy bạn cần thư viện tiện ích không thay đổi mà tôi đã đề cập. Chức năng thành phần là đủ dễ dàng với Java 8 lambdas. –

4

tôi nói nó là có thể, mà không thực sự làm việc đó :-)

Đây chỉ là một phỏng đoán như tôi có ít kinh nghiệm trong lĩnh vực này và không có gì cả với Elm.

Tôi nghĩ bạn sẽ gần nhất với Elm bằng cách tạo trình bao bọc ScalaFX cho ReactFX, mặc dù bạn có thể cũng sử dụng Java 8 lambdas kết hợp với ReactFX thay vì Scala. Bạn có thể sẽ phải thực hiện khá một vài mở rộng để ReactFX cũng như các cơ sở khác để có được sự trừu tượng và sang trọng mà bạn mong muốn.

Thanh toán Deprecating the Observer Pattern nếu bạn chưa làm như vậy. Tôi nghĩ rằng nó là khá liên quan đến chủ đề này đặc biệt là liên quan đến suy nghĩ về một mô hình lập trình phản ứng như trái ngược với một mô hình quan sát (đó là những gì JavaFX ChangeListeners được). Điều đó nói rằng, tôi nghĩ nếu bạn sử dụng các thư viện như ReactFX được xây dựng dựa trên khung công tác và khung lắng nghe JavaFX, thì bạn có thể kết thúc với sự trừu tượng mức cao hơn của các luồng sự kiện hữu ích cho lập trình phản ứng. Chắc chắn, bạn có thể tạo một trò chơi Mario trong JavaFX mà không sử dụng ReactFX, nhưng mã sẽ khá khác và bạn sẽ làm việc ở một mức trừu tượng khác với thứ mà bạn sẽ sử dụng với ReactFX. Vì vậy, thuần JavaFX, không có ReactFX sẽ ít Elm như thế nào. Đối với lớp mạng, akka có thể được sử dụng để cung cấp khung phản ứng cho trò chơi nhiều người chơi, điều này sẽ cho phép bạn sử dụng chương trình phản ứng từ trên xuống dưới, cả trong giao diện người dùng và trong hệ thống liên lạc của bạn.

Đối với hoạt ảnh Sprite trong mẫu Mario, hãy sử dụng mã netopyr cho Creating a Sprite Animation with JavaFX.

Đối với các phép tính vật lý, bạn có thể sử dụng thư viện JBox2D. Bạn sẽ cần phải tạo một số loại trình bao bọc phản ứng xung quanh JBox2D để làm cho nó nhận thức được những thứ như các thuộc tính JavaFX và các luồng sự kiện ReactFX và các đăng ký. Đối với mẫu Mario đơn giản, việc sử dụng thư viện bên ngoài có lẽ sẽ gặp nhiều rắc rối hơn giá trị của nó. Thay vào đó, bạn có thể sử dụng mô hình vật lý gia đình cơ bản (ví dụ:một cái gì đó như thế này ball animation experiment) và móc nó vào khung phản ứng của bạn.

Tôi khuyên bạn nên liên lạc với Tomas Mikula, người đã tạo ReactFX và hỏi anh ta lập trình phản ứng của bạn cho các câu hỏi JavaFX. Robert Ladstätter cũng đã thực hiện một số nội dung thú vị với ScalaFX và có thể cung cấp cho bạn thêm một số lời khuyên, mặc dù tôi không biết liệu anh ấy có làm việc với chương trình Reactive không. Tôi cũng khuyên bạn nên ping các ScalaFX users forums, nhưng tôi thấy bạn đã làm điều đó :-)

Elm Mario sample là khá đơn giản, vì vậy tôi khuyên bạn thử bản dịch ReactFX mình. Sau đó, tôi nghĩ câu trả lời cho câu hỏi của bạn sẽ trở nên hiển nhiên. Bây giờ tôi đã viết này => nếu bạn không thực sự triển khai nó và xuất bản giải pháp của bạn là câu trả lời chính xác, tôi có thể phải săn bạn xuống và bạn sẽ không muốn điều đó :-)

+0

Tôi thấy điểm của bạn :) cảm ơn rất nhiều. Cảm ơn bạn cho sự khích lệ. – jhegedus

+0

Hiện tại tôi đang đọc Haskell School of Expressions có một chương rất thú vị và rất giới thiệu để xây dựng các trò chơi phản ứng trong Haskell. Tôi vẫn còn khá mới bắt đầu trong lĩnh vực này thú vị nhưng hy vọng tôi sẽ nhận được lên đến tốc độ sớm :) – jhegedus

4

Tôi hiện đang so sánh lập trình GUI hướng đối tượng truyền thống với lập trình GUI chức năng cho luận văn thạc sĩ của tôi. Trong thực tế, một phần mà tôi sắp bắt đầu trước khi sử dụng Elm để tạo lại một số chương trình GUI truyền thống trong JavaFX/ScalaFX. Khi tôi kết thúc với điều đó, tôi có lẽ sẽ có thể đưa ra một câu trả lời chính xác hơn nhiều nhưng tôi vẫn muốn cung cấp một số con trỏ hữu ích nói chung bây giờ.


Thứ nhất, có hai giấy tờ tốt mà cung cấp một cái nhìn tổng quan của cảnh quan FRP, cụ thể là “A Survey on Reactive Programming““Towards Reactive Programming for Object-oriented Applications”. Cụ thể, trước đây, cung cấp phân loại các hệ thống FRP phân biệt “Anh chị em của FRP” và “Anh em họ của FRP” (ám chỉ đến mối quan hệ họ hàng với ý tưởng của Fran). Anh chị em của FRP tập trung vào giá trị thay đổi theo thời gian, anh em họ của FRP tập trung vào luồng sự kiện, bộ sưu tập quan sát và không đồng bộ và không có trừu tượng nguyên thủy để biểu thị giá trị thay đổi theo thời gian. Với sự phân biệt đó trong đầu, Elm là anh chị em của FRPRxJava/ReactFX là một người anh em họ của FRP. Tôi đoán bạn có thể nói rằng họ là động vật khác nhau mặc dù cả hai đều là hệ thống FRP và có chồng chéo, một cách tự nhiên.

Thứ hai, giấy “Crossing State Lines: Adapting Object-Oriented Frameworks to Functional Reactive Languages” cung cấp một bản tóm tắt rất đẹp và gọn gàng trong những khác biệt giữa phương pháp FRP như trong Elm và cách tiếp cận OOP truyền thống như trong JavaFX:

OO làm cho nhà nước rõ ràng nhưng gói gọn nó, trong khi trạng thái trong FRP được ẩn từ lập trình viên bằng các trừu tượng thời gian của ngôn ngữ.

Vì vậy, có cách tiếp cận cơ bản khác với thiết kế chương trình. Do đó, đối với tôi, vẫn chưa rõ liệu bạn có thể đạt được sự trừu tượng mức cao "giống nhau" với JavaFX (+ RxJava/ReactFX) như với Elm hay không. Điều đó không có nghĩa là nó là không thể nhưng nó không phải là hiển nhiên trên cái nhìn đầu tiên.

Cuối cùng, một quan sát chung về Elm và nó “alienness” cực so với các phương pháp OOP truyền thống từ luận án của tôi để làm cho những trở ngại trong việc đạt được kết quả tương tự trong JavaFX rõ ràng hơn:

Rất nhiều thư viện GUI ngay cả trong các ngôn ngữ chức năng thuần túy, về bản chất là một mảnh mỏng mỏng trên một bộ công cụ GUI hướng đối tượng (bắt buộc). Điều này có nghĩa là, đối với ví dụ , các tiện ích đó không phải là các hàm thuần túy. Tiện ích có trạng thái và do đó, danh tính.Nếu chúng ta ẩn lên núm chức năng trên bảng điều khiển của bộ công cụ GUI với giá trị tối đa của chúng ta, chúng ta phải đến một tình huống mà ngay cả các vật dụng không là gì ngoài chức năng thuần túy. Elm là một ví dụ về một ngôn ngữ chức năng và bộ công cụ GUI tối đa cùng một lúc. Như callbacks là tất cả về tác dụng phụ Elm tự nhiên không sử dụng callbacks nào cho mã hành vi liên quan nhưng thay vì FRP. Nơi tuỳ biến trong một ngôn ngữ OOP thường được thực hiện với thừa kế, trong Elm chỉ có con đường của thành phần chức năng ...

Điểm mấu chốt là trong Elm quan điểm là chức năng tinh khiết và, về cơ bản, Elm buộc bạn phải cấu trúc mã theo cách này. Trong JavaFX bạn không bị ép buộc vì vậy bạn phải cố ý cẩn thận để làm điều đó.

Nhân tiện, có một số game skeleton cho các trò chơi Elm như Mario. Bạn có thể nghiên cứu nó và suy nghĩ về cách bạn sẽ thiết kế chương trình JavaFX của bạn theo bộ xương này. Có lẽ bạn thậm chí có thể tạo ra một bộ xương như vậy cho JavaFX sau khi học? Tôi muốn được quan tâm đến nó.

+1

Âm thanh rất thú vị, cảm ơn cho câu trả lời chi tiết! Xin vui lòng gửi một liên kết đến luận án của bạn, tôi rất muốn đọc nó khi nó đã hoàn thành. – jhegedus

+1

Có, ReactFX là về các luồng sự kiện, nhưng JavaFX đơn giản đã có các giá trị thay đổi theo thời gian, cụ thể là ObservableValue. ReactFX cung cấp một cách dễ dàng để chuyển đổi hai: 'EventStreams.valuesOf (observableValue)' tạo ra một luồng sự kiện từ một giá trị quan sát được, trong khi 'stream.toBinding (initialValue)' biến luồng sự kiện thành một giá trị quan sát được. –

2

Tôi đã đặt ra câu hỏi này cách đây một năm. Kể từ đó tôi đã học được một hoặc hai điều về FRP. Tôi nghĩ rằng câu trả lời là không, ít nhất là không dễ dàng với RX, nó sẽ là tốt hơn để sử dụng thư viện JavaFX + Sodium FRP.

Tại sao không (rất dễ dàng) với RX? Vì ELM là FRP, trong khi RX là FRP trừ đi các giao dịch (mơ hồ). Vì vậy, thực tế, nếu ai đó muốn thực hiện trò chơi Mario trong ELM thì cô ấy sẽ phải thêm giao dịch vào RX (để tránh glitches).

Các vấn đề liên quan