현재 Functional Reactive Programming 구현 상태는 어떻습니까?


90

Haskell에서 간단한 자동 물리 시스템 (진자, 로봇 팔 등)을 시각화하려고합니다. 종종 이러한 시스템은 다음과 같은 방정식으로 설명 할 수 있습니다.

df/dt = c*f(t) + u(t)

여기서 u(t)'지능형 제어'의 어떤 종류를 나타냅니다. 이러한 시스템은 Functional Reactive Programming 패러다임에 매우 잘 맞는 것으로 보입니다.

그래서 저는 Paul Hudak의 "The Haskell School of Expression"이라는 책을 집어 들고 거기에 제시된 도메인 특정 언어 "FAL"(기능적 애니메이션 언어의 경우)이 실제로 제 간단한 장난감 시스템에 대해 매우 만족스럽게 작동한다는 것을 발견했습니다 (일부 기능, 특히 integrate, 효율적으로 사용하기에는 너무 게으른 것처럼 보였지만 쉽게 고칠 수 있습니다.)

제 질문은 오늘날 더 발전된 응용 프로그램이나 실용적인 응용 프로그램을 위해 더 성숙하고, 최신이며, 잘 유지되고, 성능이 조정 된 대안은 무엇입니까?

이 위키 페이지 에는 Haskell에 대한 몇 가지 옵션 나열되어 있지만 다음 사항에 대해 명확하지 않습니다.

  1. 이 프로그래밍 패러다임의 발명가 중 한 명인 Conal Eliott의 프로젝트 인 "reactive"의 상태는 약간 진부 해 보입니다. 나는 그의 코드를 좋아하지만 다른 최신 대안을 시도해야할까요? 구문 / 성능 / 런타임 안정성 측면에서 이들의 주요 차이점은 무엇입니까?

  2. 2011 년 의 설문 조사 에서 인용하자면 , 섹션 6, " ... FRP 구현은 여전히 ​​지연 시간 보장이 필요한 도메인에서 효과적으로 사용할 수있을만큼 충분히 효율적이지 않거나 성능을 예측할 수 없습니다 .". 설문 조사는 몇 가지 흥미로운 최적화를 제안하지만 FRP가 15 년 이상 존재한다는 사실을 감안할 때이 성능 문제 는 최소한 몇 년 이내에 해결하기가 매우 또는 본질적으로 어려울 수 있다는 인상을 받았습니다 . 이것이 사실입니까?

  3. 설문 조사의 동일한 작성자가 자신의 블로그 에서 "시간 누출"에 대해 이야기 합니다. FRP에만 문제가 있습니까? 아니면 순수하고 엄격하지 않은 언어로 프로그래밍 할 때 일반적으로 발생하는 문제입니까? 성능이 충분하지 않으면 시간이 지남에 따라 FRP 기반 시스템을 안정화하는 것이 너무 어렵다는 사실을 알게 된 적이 있습니까?

  4. 아직 연구 수준의 프로젝트입니까? 플랜트 엔지니어, 로봇 공학 엔지니어, 금융 엔지니어 등과 같은 사람들이 실제로 사용하고 있습니까 (자신의 요구에 맞는 언어로)?

개인적으로 Haskell 구현을 선호하지만 다른 제안에 열려 있습니다. 예를 들어, Erlang을 구현하는 것이 특히 재미있을 것입니다. 그러면 지능적이고 적응력이 뛰어난자가 학습 서버 프로세스를 갖는 것이 매우 쉽습니다!

답변:


82

현재 기능적 반응 프로그래밍을 위해 주로 두 개의 실용적인 Haskell 라이브러리가 있습니다. 둘 다 한 사람이 관리하지만 다른 Haskell 프로그래머로부터 코드 기여를 받고 있습니다.

  • Netwire 는 효율성, 유연성 및 예측 가능성에 중점을 둡니다. 자체 이벤트 패러다임을 가지고 있으며 네트워크 서비스 및 복잡한 시뮬레이션을 포함하여 기존 FRP가 작동하지 않는 영역에서 사용할 수 있습니다. 스타일 : 적용 및 / 또는 화살표. 초기 저자 및 유지 관리자 : Ertugrul Söylemez (저입니다).

  • 반응 바나나 는 전통적인 FRP 패러다임을 기반으로합니다. 사용하는 것이 실용적이지만 고전적인 FRP 연구의 기반 역할도합니다. 주요 초점은 사용자 인터페이스에 있으며 wx에 대한 기성 인터페이스가 있습니다. 스타일 : 적용. 초기 저자 및 관리자 : Heinrich Apfelmus.

둘 다 시도해야하지만 응용 프로그램에 따라 둘 중 하나가 더 적합하다는 것을 알 수 있습니다.

게임, 네트워킹, 로봇 제어 및 시뮬레이션의 경우 Netwire가 유용하다는 것을 알게 될 것입니다. 다양한 유용한 차동 장치, 적분 및 투명한 이벤트 처리를위한 많은 기능을 포함하여 이러한 애플리케이션을 위해 기성품 와이어 가 함께 제공됩니다 . 튜토리얼을 보려면 Control.Wire내가 링크 한 페이지 의 모듈 문서를 방문하십시오 .

그래픽 사용자 인터페이스의 경우 현재 최선의 선택은 반응 바나나입니다. 이미 wx 인터페이스 (별도의 라이브러리 react-banana-wx)가 있으며 Heinrich는이 컨텍스트에서 코드 샘플을 포함하여 FRP에 대해 많은 블로그를 게시합니다.

다른 질문에 답하기 위해 : FRP는 실시간 예측 가능성이 필요한 시나리오에 적합하지 않습니다. 이것은 주로 Haskell 때문이지만 불행히도 FRP는 저수준 언어로 실현하기가 어렵습니다. Haskell 자체가 실시간으로 준비되면 FRP도 거기에 도달 할 것입니다. 개념적으로 Netwire는 실시간 애플리케이션을위한 준비가되어 있습니다.

시간 누출은 더 이상 실제로 문제가되지 않습니다. 왜냐하면 주로 모나 딕 프레임 워크와 관련이 있기 때문입니다. 실용적인 FRP 구현은 단순히 모나 딕 인터페이스를 제공하지 않습니다. Yampa는 이것을 시작했고 Netwire와 react-banana는 모두이를 기반으로합니다.

지금은 FRP를 사용하는 상업용 또는 대규모 프로젝트가 없다는 것을 알고 있습니다. 도서관은 준비되었지만 사람들은 아직 준비되지 않은 것 같습니다.


훌륭한 대답입니다. 감사합니다. 라이브러리 위에 강화 학습 알고리즘을 구현하는 것은 재미있는 연습이 될 것입니다.
mnish

3
특히 최근 Haskell ( Nikki and the Robots )로 작성된 인디 게임 은 FRP를 사용 하지 않기로 결정했습니다 .
Alex R

23

이미 좋은 답변이 있지만 구체적인 질문에 답하려고 노력할 것입니다.

  1. 리 액티브는 시간 누출 문제로 인해 심각한 프로젝트에 사용할 수 없습니다. (# 3 참조). 가장 유사한 디자인의 현재 라이브러리는 React-banana로, 리 액티브를 영감으로 개발하고 Conal Elliott와 논의 중입니다.

  2. Haskell 자체는 하드 실시간 애플리케이션에 적합하지 않지만 경우에 따라 소프트 실시간 애플리케이션에 Haskell을 사용할 수 있습니다. 저는 현재 연구에 익숙하지 않지만 이것이 극복 할 수없는 문제라고 생각하지 않습니다. Yampa와 같은 시스템이나 Atom과 같은 코드 생성 시스템이이 문제를 해결하는 가장 좋은 방법이라고 생각합니다.

  3. "시간 누출"은 전환 가능한 FRP에 특정한 문제입니다. 누수는 시스템이 오래된 개체를 해제 할 수 없을 때 발생합니다. 나중에 스위치가 발생할 경우 필요할 수 있기 때문입니다. 메모리 누수 (매우 심각 할 수 있음) 외에도 또 다른 결과는 전환이 발생할 때 시스템이 현재 상태를 생성하기 위해 이전 개체의 체인을 통과하는 동안 일시 중지해야한다는 것입니다.

Yampa 및 이전 버전의 반응 바나나와 같은 전환 불가능한 frp 라이브러리는 시간 누출로 고통받지 않습니다. 전환 가능한 frp 라이브러리는 일반적으로 두 가지 방식 중 하나를 사용합니다. 즉, FRP 값이 생성되는 특수 "생성 모나드"가 있거나 "에이징"유형 매개 변수를 사용하여 전환이 발생할 수있는 컨텍스트를 제한합니다. elerea (그리고 아마도 netwire?)는 전자를 사용하는 반면 최근의 반응성 바나나와 자몽은 후자를 사용합니다.

"switchable frp"는 Conal의 기능 switcher :: Behavior a -> Event (Behavior a) -> Behavior a또는 동일한 의미 를 구현하는 것을 의미합니다. 이것은 네트워크의 모양이 실행될 때 동적으로 전환 될 수 있음을 의미합니다.

이것은 모나 딕 인터페이스에 대한 @ertes의 진술과 실제로 모순되지 않습니다. Monad인스턴스를 제공 Event하면 시간 누출이 가능하며 위의 접근 방식 중 하나를 사용하면 더 이상 동등한 Monad 인스턴스를 정의 할 수 없습니다.

마지막으로, FRP로 수행해야 할 작업이 아직 많이 남아 있지만 일부 최신 플랫폼 (reactive-banana, elerea, netwire)은 안정적이고 성숙하여 신뢰할 수있는 코드를 작성할 수 있다고 생각합니다. 그러나 좋은 성능을 얻는 방법을 이해하기 위해 많은 시간을 할애해야 할 수 있습니다.


2
화살표 기반 라이브러리 (Yampa, netwire)의 경우에도 전환이 가능합니다. 그 이유는 화살에 노화가 내장되어 있기 때문에 실제로 제거 할 수 없기 때문입니다. (화살표들은 입력 스트림의 시작 시간에 대해 불가지론 자이고, 스트림 변압기된다.)
하인리히 Apfelmus


1
@HeinrichApfelmus : 흥미로운 점입니다. 나는 일반적으로 화살표 기반 라이브러리를 elerea / grapefruit / current-reactive-banana와 같은 방식으로 전환 할 수 있다고 생각하지 않습니다. 나는 그들의 전환이 이전 버전의 반응 바나나에서 요구했던 것에 훨씬 더 가깝다고 생각합니다. 이것은 단지 직감 일뿐입니다. 제가 의미하는 바를 설명 할만큼 충분히 생각하지 않았습니다.
John L

2
@ DanBurton 감사합니다, 나는 그 이름을 기억하려고 실패했습니다. 나트륨은 반응성 바나나만큼 인기가 없지만 현대적인 FRP 라이브러리로 간주되어야한다는 데 동의합니다.
John L

계속되는 논의는 따라하기가 조금 어렵지만 GC 시간이 어떤 식 으로든 제한 될 수 있다면 소프트 실시간 시스템이 실제로 가능하다는 것을 나타내는 것 같습니다. 어쨌든 귀하의 훌륭한 답변에 감사드립니다.
mnish

20

Mono와 .Net 공간에 몇 가지 항목을 나열하고 얼마 전에 찾은 Haskell 공간에서 하나를 나열하겠습니다. Haskell부터 시작하겠습니다.

느릅 나무- 링크

사이트에 따른 설명 :

Elm은 프런트 엔드 웹 개발을보다 즐겁게 만드는 것을 목표로합니다. HTML, CSS 및 JavaScript의 시스템 문제를 수정하는 GUI 프로그래밍에 대한 새로운 접근 방식을 소개합니다. Elm을 사용하면 시각적 레이아웃으로 빠르고 쉽게 작업하고, 캔버스를 사용하고, 복잡한 사용자 입력을 관리하고, 콜백 지옥에서 벗어날 수 있습니다.

FRP 자체 변형이 있습니다. 예제를 가지고 놀아 보면 꽤 성숙해 보입니다.

반응 확장- 링크

첫 페이지의 설명 :

Reactive Extensions (Rx)는 관찰 가능한 시퀀스와 LINQ 스타일 쿼리 연산자를 사용하여 비동기 및 이벤트 기반 프로그램을 구성하기위한 라이브러리입니다. Rx를 사용하여 개발자는 Observable로 비동기 데이터 스트림을 표현하고, LINQ 연산자를 사용하여 비동기 데이터 스트림을 쿼리하고, 스케줄러를 사용하여 비동기 데이터 스트림의 동시성을 매개 변수화합니다. 간단히 말해서, Rx = Observables + LINQ + Scheduler입니다.

Reactive Extensions는 MSFT에서 제공되며 이벤트 처리를 단순화하는 많은 우수한 연산자를 구현합니다. 며칠 전 오픈 소스 였습니다 . 그것은 매우 성숙하고 생산에 사용됩니다. 제 생각에는 TPL 라이브러리가 제공하는 것보다 Windows 8 API를위한 더 좋은 API 였을 것입니다. Observable은 hot과 cold, 재시도 / 병합 등이 될 수 있지만, 작업은 항상 실행 중이거나 오류가 있거나 완료된 계산을 나타내거나 완료되었음을 나타냅니다.

비동기 성을 위해 Rx를 사용하여 서버 측 코드를 작성했지만 C #으로 기능적으로 작성하는 것이 약간 성 가실 수 있음을 인정해야합니다. F #에는 몇 개의 래퍼가 있지만 그룹이 상대적으로 닫혀 있고 다른 프로젝트와 마찬가지로 MSFT에서 홍보하지 않기 때문에 API 개발을 추적하기가 어려웠습니다.

오픈 소싱은 IL-JS 컴파일러의 오픈 소싱과 함께 제공되었으므로 JavaScript 또는 Elm과 잘 작동 할 수 있습니다.

RabbitMQ 및 SocksJS와 같은 메시지 브로커를 사용하여 F # / C # / JS / Haskell을 매우 멋지게 바인딩 할 수 있습니다.

Bling UI 툴킷- 링크

첫 페이지의 설명 :

Bling은 Microsoft의 WPF / .NET에서 이미지, 애니메이션, 상호 작용 및 시각화를 쉽게 프로그래밍 할 수있는 C # 기반 라이브러리입니다. Bling은 풍부한 UI 디자인 아이디어의 신속한 프로토 타이핑을 지원하기 위해 때때로 프로그래밍하는 디자이너와 같은 디자인 기술자를 대상으로합니다. 학생, 예술가, 연구자 및 애호가들은 Bling이 아이디어 나 시각화를 빠르게 표현하는 도구로 유용하다는 것을 알게 될 것입니다. Bling의 API 및 구조는 생산 코드를 신중하게 프로그래밍하는 것과 달리 폐기 코드의 빠른 프로그래밍에 최적화되어 있습니다.

무료 LtU 기사 .

나는 이것을 테스트했지만 클라이언트 프로젝트를 위해 작업하지 않았습니다. 멋져 보이고 값 사이의 바인딩을 형성하는 멋진 C # 연산자 오버로딩이 있습니다. WPF / SL / (WinRT)의 종속성 속성을 이벤트 원본으로 사용합니다. 3D 애니메이션은 합리적인 하드웨어에서 잘 작동합니다. 시각화가 필요한 프로젝트를 끝내면 이것을 사용합니다. 아마도 Windows 8로 포팅 할 것입니다.

ReactiveUI- 링크

이전에 MSFT에서 근무한 Paul Betts는 현재 Github에서이 프레임 워크를 작성했습니다. 나는 그것을 꽤 광범위하게 다루었 고 모델을 좋아합니다. Blink (Rx 및 추상화를 사용하는 특성상)보다 분리되어있어이를 사용하여 코드를 단위 테스트하기가 더 쉽습니다. Windows 용 github git 클라이언트가 여기에 작성되었습니다.

코멘트

반응 형 모델은 성능이 요구되는 대부분의 애플리케이션에서 충분히 성능을 발휘합니다. 어려운 실시간을 생각하고 있다면 대부분의 GC 언어에 문제가 있다고 확신합니다. Rx, ReactiveUI는 구독이 생성 / 처리되고 콜백의 반응 "모나드"에서 중간 값이 진행되는 방식이기 때문에 GC가 필요한 작은 개체를 약간 생성합니다. 일반적으로 .Net에서는 콜백이 정적 (컴파일 시간에 알려짐, 할당 없음)이고 작업이 동적으로 할당 (알 수 없음, 모든 호출에 인스턴스 필요, 가비지 생성)되기 때문에 작업 기반 프로그래밍보다 반응 형 프로그래밍을 선호합니다. 컴파일러 생성 클래스.

분명히 C #과 F #은 엄격하게 평가되므로 여기서 시간 누출은 문제가되지 않습니다. JS도 마찬가지입니다. 그래도 재생 가능하거나 캐시 된 관찰 가능 항목에는 문제가 될 수 있습니다.


훌륭한 답변에 감사드립니다. Haskell FRP 구현에 대해 내가 좋아하는 것 중 하나는 컨트롤에 대한 계산 u(t)f(t). F # 구현의 경우입니까?
mnish

이 두 기능이 일시적으로 분리되어 있다고 말할 수 있습니다. 하지만 논리적으로 분리되지는 않았습니다. ;)
Henrik

내가 아는 한, Reactive Extensions 및 기타보다 세련된 UI (사실 Haskell 외부의 모든 패키지 포함)는 이벤트 의미 만 사용합니다. 즉, 전환 할 수있는 이벤트 개념이 있습니다. 그러나 방정식 적으로 상호 작용할 수있는 연속적인 시간 신호의 개념은 아닙니다. GUI 구축의 경우 이것은 괜찮다고 생각합니다. 그러나 건물 시뮬레이션 및 모델의 경우 불행 할 수 있습니다.
sclv

모든 기능적 리 액티브 프로그래밍 lib 구현이 개별적으로가 아니라 지속적으로 시간을 모델링해야한다는 것을 암시하고 있습니까? "타이밍이있는 프로세스 대수 : 실시간 및 이산 시간"이라는 논문을 찾았습니다. 이것이 당신이 말하는 것을 이해하는 좋은 출발점입니까?
Henrik

모든 것이 필요하다고 말하는 것이 아닙니다. 일부는해야하고 일부는 그렇지 않습니다. 하지만 그렇게하는 것은 특정 작업에 더 적합하고 다른 작업에는 더 적합하지 않습니다 ...
sclv
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.