2012-03-08 37 views
6

Tôi đang triển khai khung FRP trong Scala và dường như tôi đã gặp sự cố. Thúc đẩy bởi một số suy nghĩ, câu hỏi này tôi đã quyết định để hạn chế các giao diện công cộng của khuôn khổ của tôi vì vậy Hành vi chỉ có thể được đánh giá trong 'hiện tại' ví dụ:Thực hiện ảnh chụp nhanh trong FRP

behaviour.at(now) 

này cũng rơi vào phù hợp với giả định Conal trong giấy Fran rằng Hành vi chỉ được đánh giá/lấy mẫu vào thời gian tăng. Nó hạn chế sự biến đổi về hành vi nhưng nếu không chúng tôi tìm thấy chính mình trong những vấn đề lớn với hành vi mà đại diện cho một số đầu vào:

val slider = Stepper(0, sliderChangeEvent) 

Với hành vi này, việc đánh giá giá trị tương lai sẽ không chính xác và đánh giá giá trị trong quá khứ sẽ đòi hỏi một số lượng không giới hạn của bộ nhớ (tất cả các lần xuất hiện được sử dụng trong sự kiện 'thanh trượt' sẽ phải được lưu trữ).

Tôi gặp sự cố với đặc điểm kỹ thuật cho hoạt động 'chụp nhanh' trên Hành vi do hạn chế này. Vấn đề của tôi được giải thích tốt nhất với một ví dụ (sử dụng thanh trượt đề cập ở trên):

val event = mouseB // an event that occurs when the mouse is pressed 
val sampler = slider.snapshot(event) 
val stepper = Stepper(0, sampler) 

Vấn đề của tôi ở đây là nếu tổ chức sự kiện của mouseB 'đã xảy ra khi mã này được thực thi thì giá trị hiện tại của 'bước' will là 'mẫu' cuối cùng của 'thanh trượt' (giá trị tại thời điểm xảy ra lần cuối). Nếu thời gian xảy ra lần cuối cùng trong quá khứ thì chúng tôi sẽ kết thúc đánh giá 'thanh trượt' bằng cách sử dụng thời gian qua đã phá vỡ quy tắc được đặt ở trên (và giả định ban đầu của bạn). Tôi có thể thấy một vài cách để giải quyết này:

  1. Chúng tôi 'kỷ lục' quá khứ (giữ chân tất cả các lần xuất hiện trước đây trong một sự kiện) cho phép đánh giá các hành vi với thời gian vừa qua (sử dụng một số lượng không giới hạn của bộ nhớ)
  2. Chúng tôi sửa đổi 'ảnh chụp nhanh' để tham gia một đối số thời gian ("mẫu sau thời gian này") và thực thi thời gian đó> = now
  3. Trong một động thái khác, chúng tôi có thể hạn chế việc tạo đối tượng FRP cho thiết lập ban đầu của chương trình bằng cách nào đó và chỉ bắt đầu xử lý sự kiện/đầu vào sau khi thiết lập này hoàn tất

Tôi cũng có thể đơn giản là không thực hiện 'mẫu' hoặc loại bỏ 'stepper'/'switcher' (nhưng tôi không thực sự muốn làm một trong những thứ này). Có ai nghĩ gì về điều này không? Tôi đã hiểu nhầm bất cứ điều gì ở đây?

+1

Bạn biết [Phản ứng] (http://www.reactive-web.co.cc/) phải không? –

+2

Phản ứng là mát mẻ nhưng nó phá vỡ một vài ý tưởng trong FRP. Ví dụ, nó không có khái niệm về các hành vi liên tục: Các tín hiệu trong sự thay đổi phản ứng một cách cụ thể trong thời gian giữa các giá trị khác nhau. Ban đầu tôi đã nhầm lẫn về cách điều này phù hợp với FRP và hỏi câu hỏi này một lúc trước: http://stackoverflow.com/questions/7451317/is-the-signal-representation-of-functional-reactive-programming-correct – seadowg

+0

Ngoài ra, Phản ứng không thực sự có bất kỳ chức năng nào như 'ảnh chụp nhanh' theo như tôi có thể nói. – seadowg

Trả lời

3

Ồ, tôi hiểu ý của bạn bây giờ.

Hạn chế "bạn chỉ có thể lấy mẫu tại 'hiện tại" "không đủ chặt chẽ, tôi nghĩ vậy. Nó cần phải mạnh hơn một chút để tránh nhìn vào quá khứ. Vì bạn đang sử dụng quan niệm môi trường của now, tôi sẽ xác định các chức năng xây dựng hành vi theo điều kiện của nó (miễn là now không thể tiến hành bởi việc thực hiện các định nghĩa đơn giản, mà theo câu trả lời cuối cùng của tôi, sẽ lộn xộn). Ví dụ:

Stepper(i,e) là một hành vi với giá trị i trong khoảng [now,e1] (nơi e1 là thời điểm xuất hiện đầu tiên của e sau now), và giá trị của sự xuất hiện gần đây nhất của e sau đó.

Với ngữ nghĩa này, dự đoán của bạn về giá trị của stepper rằng có bạn vào câu hỏi hóc búa này được tháo dỡ, và bước bây giờ sẽ có giá trị 0. Tôi không biết liệu ngữ nghĩa này là mong muốn cho bạn, nhưng dường như đủ tự nhiên đối với tôi.

+0

Đây là một cách rất hay để trình bày nó. Tôi chỉ cảm thấy thất vọng khi cố gắng tìm cách duy trì ngữ nghĩa gốc (đáng yêu) mà không cần sử dụng một lượng bộ nhớ vô biên. Tôi đã nhận thấy rằng một số triển khai loại bỏ 'stepper' và 'switcher' vì điều này nhưng họ có vẻ rất mạnh mẽ. Ah tốt. – seadowg

+0

@seadowg, ngữ nghĩa của Fran rất tuyệt vời, nhưng cho đến nay chúng tôi đã không thực hiện được chúng một cách hiệu quả (chúng luôn luôn bị rò rỉ không gian, và sự chậm chạp tương ứng). Cá nhân tôi đã dành khoảng 6 tháng cho vấn đề này. Chúng tôi cũng không thể xác định bất kỳ lý do * nào * tại sao nó sẽ là không thể, do đó, một giải pháp vẫn có thể tồn tại. Đủ để nói nó sẽ không được rõ ràng. – luqui

+1

@luqui: Trong [bài đăng trên blog này] (http://apfelmus.nfshost.com/blog/2012/01/01-frp-api-0-5.html), Heinrich Apfelmus trỏ tới [giấy] (http : //cs.ioc.ee/~tarmo/tsem10/jeltsch-slides.pdf) được cho là giải thích tại sao loại chuyển đổi sự kiện động tiêu chuẩn vốn đã sai. Tôi không đủ chuyên gia để hiểu nó, nhưng bạn đã thấy điều này chưa, và nếu có, bạn có thấy nó không thuyết phục? (Một chút chủ đề, tôi biết, nhưng tôi cho rằng điều này sẽ nổi tiếng trong cộng đồng FRP khi tôi nhìn thấy nó.) – ehird

3

Từ những gì tôi có thể nói, bạn lo lắng về điều kiện chủng tộc: điều gì xảy ra nếu sự kiện xảy ra trong khi mã đang thực thi.

Mã chức năng hoàn toàn không muốn biết rằng nó được thực thi. Các kỹ thuật chức năng là tốt nhất trong môi trường thuần túy, sao cho nó không quan trọng trong mã lệnh nào được thực thi. Một cách thoát khỏi tình huống khó xử này là giả vờ rằng mọi thay đổi xảy ra trong một đoạn mã bắt buộc (nội bộ, có thể); giả vờ rằng bất kỳ khai báo chức năng nào trong khung FRP xảy ra trong 0 thời gian để không thể thay đổi gì đó trong quá trình khai báo của chúng.

Không ai nên ngủ, hoặc thực sự làm bất cứ điều gì nhạy cảm với thời gian, trong một đoạn mã là tuyên bố hành vi và sự vật. Về cơ bản, mã hoạt động với các đối tượng FRP phải tinh khiết, sau đó bạn không có bất kỳ vấn đề gì.

Điều này không nhất thiết ngăn cản việc chạy nó trên nhiều luồng, nhưng để hỗ trợ bạn có thể cần phải tổ chức lại các đại diện nội bộ của bạn.Chào mừng bạn đến với thế giới triển khai thư viện FRP - Tôi nghi ngờ việc đại diện nội bộ của bạn sẽ biến động nhiều lần trong quá trình này. :-)

+0

Điểm thú vị. Tôi không lo lắng về việc liệu một cái gì đó xảy ra trong khi mã này đang thực thi (tất cả có thể là một vấn đề) nhưng nếu mouseB xảy ra trước đó. Chỉ đơn giản là, với định nghĩa của 'ảnh chụp nhanh', sự xuất hiện 'cuối cùng' trong sự kiện trả về sẽ là (t, slider.at (t)) trong đó t seadowg

0

Tôi nhầm lẫn về sự nhầm lẫn của bạn. Cách tôi thấy là Stepper sẽ "đặt" hành vi thành giá trị mới bất cứ khi nào sự kiện xảy ra. Vì vậy, những gì sẽ xảy ra như sau:

Trong khoảnh khắc, trong đó sự kiện mouseB xảy ra, giá trị của hành vi slider sẽ được đọc (snapshot). Giá trị này sẽ được "đặt" thành hành vi stepper.

Vì vậy, đúng là các giá trị Stepper sẽ "ghi nhớ" trước đây; vấn đề là nó chỉ nhớ giá trị mới nhất từ quá khứ, không phải mọi thứ.

Ngữ nghĩa, tốt nhất là hãy mô hình Stepper làm chức năng như luqui đề xuất.

+0

Có nếu chúng tôi không cho phép lấy mẫu trong quá khứ. Vấn đề của tôi là nếu chúng tôi gọi ảnh chụp nhanh trên Hành vi bằng cách sử dụng Sự kiện xảy ra trong quá khứ, chúng tôi sẽ lấy mẫu Hành vi này bằng cách sử dụng thời gian qua (mà tôi không muốn cho phép). Stepper đã được sử dụng để hỗ trợ các ví dụ. – seadowg

+0

@seadowg: Ah, tôi hiểu rồi. Bạn có hai lựa chọn: hoặc bạn chắc chắn rằng tại một thời điểm nào đó, quá khứ là hiện tại, tức là bạn đã "đi qua các lần xuất hiện trong quá khứ rồi". Hoặc bạn phải * cắt * các lần xuất hiện trong quá khứ mà bạn vừa mới biết. Đây là những cách duy nhất để tránh rò rỉ thời gian (= nhớ một lượng dữ liệu không bị chặn từ quá khứ). Nói chung, sự chuyển đổi tích lũy và sự kiện động không thể được kết hợp một cách tự do, phải có một số hạn chế. –

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