문제

나는 Wikipedia 기사를 읽었습니다. 반응형 프로그래밍.나는 또한에 대한 작은 기사를 읽었습니다. 함수형 반응형 프로그래밍.설명이 상당히 추상적입니다.

  1. 기능적 반응형 프로그래밍(FRP)은 실제로 무엇을 의미하나요?
  2. 반응형 프로그래밍(비반응형 프로그래밍과 반대)은 무엇으로 구성됩니까?

내 배경은 명령형/OO 언어이므로 이 패러다임과 관련된 설명을 주시면 감사하겠습니다.

도움이 되었습니까?

해결책

FRP에 대한 느낌을 얻으려면 이전부터 시작할 수 있습니다. 프랜 튜토리얼 1998 년부터 애니메이션 삽화가 있습니다. 종이의 경우부터 시작하십시오 기능적 반응성 애니메이션 그런 다음 내 홈페이지와 FRP 링크 Haskell Wiki.

개인적으로, 나는 어떤 FRP에 대해 생각하고 싶습니다 수단 구현 방법을 다루기 전에. (사양이없는 코드는 질문이없는 답변이므로 "잘못되지"않습니다.) 따라서 Thomas K가 다른 답변 (그래프, 노드, 가장자리, 발사, 실행, 실행, 표현/구현 용어에서 FRP를 설명하지 않습니다. 등). 가능한 구현 스타일이 많이 있지만 구현은 어떤 FRP를 말하지 않습니다. ~이다.

FRP는 "시간이 지남에 따라 '값을 나타내는 데이터 타입"에 관한 것이라는 Laurence G의 간단한 설명과 공명합니다. 기존의 명령 프로그램은 상태와 돌연변이를 통해 이러한 동적 값을 간접적으로 포착합니다. 완전한 역사 (과거, 현재, 미래)에는 일류 표현이 없습니다. 더욱이 분리되어 진화합니다 명령 적 패러다임이 일시적으로 이산되기 때문에 값은 (간접적으로) 포착 될 수 있습니다. 대조적으로, FRP는 이러한 진화하는 값을 캡처합니다 곧장 그리고 어려움이 없습니다 계속해서 진화하는 가치.

FRP는 또한 명령적인 동시성을 괴롭히는 이론적이고 실용적인 쥐의 둥지를 가리키지 않으면 서 동시에 동시에 있다는 점에서 드문 일입니다. 의미 적으로 FRP의 동시성입니다 세밀한, 한정된, 그리고 마디 없는. (나는 구현이 아닌 의미에 대해 이야기하고있다. 구현에는 동시성이나 병렬성이 포함될 수도 있고 아닐 수도있다.) 의미 론적 결정은 엄격하고 비공식적 인 추론에 매우 중요하다. 동시성은 명령 적 프로그래밍에 엄청난 복잡성을 추가하지만 (비 결정적 인터 리빙으로 인해) FRP에서는 쉽게 적용됩니다.

그렇다면 FRP는 무엇입니까? 당신은 그것을 직접 발명 할 수있었습니다. 이 아이디어로 시작하십시오.

  • 동적/진화 값 (즉, "시간이 지남에 따라"값 "은 그 자체로 일류 값입니다. 당신은 그것들을 정의하고 결합하여 기능을 전달할 수 있습니다. 나는 이것들을 "행동"이라고 불렀다.

  • 동작은 상수 (정적) 동작 및 시간 (시계와 같은)과 같은 몇 가지 프리미티브로 구축 된 다음 순차적이고 평행 한 조합으로 구축됩니다. N 동작은 N-Ary 함수 (정적 값), "포인트 별", 즉 시간이 지남에 따라 지속적으로 적용하여 결합됩니다.

  • 불연속 현상을 설명하기 위해, 다른 유형 (가족)의 "이벤트"가 있으며, 각 유형은 스트림 (유한 또는 무한) 발생이 있습니다. 각 발생은 관련 시간과 가치가 있습니다.

  • 모든 행동과 사건을 구축 할 수있는 구성 어휘를 생각해 내려면 몇 가지 예를 가지고 재생하십시오. 보다 일반/단순한 조각으로 해체하십시오.

  • 당신이 당신이 견고한 근거에 있다는 것을 알고 있으므로, 전체 모델에 구성 기반의 기술을 사용하여 구성 기반을 제공합니다. 이는 (a) 각 유형에 해당하는 단순하고 정확한 수학적 유형의 "의미"를 가지고 있음을 의미합니다. b) 각 원시 및 연산자는 구성 요소의 의미의 함수로서 단순하고 정확한 의미를 갖는다.절대로 구현 고려 사항을 탐색 과정에 혼합하십시오. 이 설명이 당신에게 횡설창 인 경우 (a) 유형 클래스 형태를 갖는 표시 설계, (b) 푸시 풀 기능 반응성 프로그래밍 (구현 비트 무시) 및 (c) 의미 적 의미론 Haskell Wikibooks 페이지. 두 명의 창립자 Christopher Strachey와 Dana Scott의 두 부분이 있습니다. 쉽고 유용한 Strachey 부분과 소프트웨어 디자인을 위해 더욱 유용하고 유용하지 않은 Scott 부분이 있습니다.

이 원칙을 고수한다면 FRP의 정신에서 더 많은 것을 얻을 수 있습니다.

이 원칙을 어디서 얻었습니까? 소프트웨어 디자인에서 나는 항상 같은 질문을합니다. "무슨 뜻입니까?" 표현 의미론은이 질문에 대한 정확한 프레임 워크와 내 미학에 맞는 프레임 워크를 주었다 (운영 또는 공리적 의미와는 달리, 둘 다 불만족스럽지 않게 함). 그래서 나는 행동이 무엇인지 스스로에게 물었다. 나는 순결한 계산의 일시적으로 개별적인 특성이 특정 스타일에 대한 숙박 시설이라는 것을 곧 깨달았습니다. 기계, 행동 자체에 대한 자연스러운 설명보다는. 내가 생각할 수있는 행동에 대한 가장 간단한 정확한 설명은 단순히 "(연속) 시간의 기능"이므로 제 모델입니다. 유쾌하게,이 모델은 쉽고 은혜로 지속적이고 결정적인 동시성을 처리합니다.

이 모델을 올바르게 효율적으로 구현하는 것은 매우 어려운 일이지만 또 다른 이야기입니다.

다른 팁

순수한 기능 프로그래밍에는 부작용이 없습니다. 많은 유형의 소프트웨어 (예 : 사용자 상호 작용이있는 모든 것)의 경우 어느 수준에서 부작용이 필요합니다.

기능적 스타일을 유지하면서 동작과 같은 부작용을 얻는 한 가지 방법은 기능적 반응성 프로그래밍을 사용하는 것입니다. 이것은 기능 프로그래밍과 반응성 프로그래밍의 조합입니다. (링크 된 Wikipedia 기사는 후자에 관한 것입니다.)

반응성 프로그래밍의 기본 아이디어는 "시간이 지남에 따라"값을 나타내는 특정 데이터 유형이 있다는 것입니다. 이러한 변화와 시간 값을 포함하는 계산은 자체적으로 시간이 지남에 따라 변화하는 값을 갖습니다.

예를 들어, 마우스 좌표를 한 쌍의 정수 값으로 표시 할 수 있습니다. 우리와 같은 것이 있다고 가정 해 봅시다 (이것은 의사 코드라고) :

x = <mouse-x>;
y = <mouse-y>;

언제라도 X와 Y는 마우스의 좌표를 가질 것입니다. 비 반응성 프로그래밍과 달리, 우리는이 할당을 한 번만 만들면 x 및 y 변수가 "최신"상태로 유지됩니다. 이것이 반응성 프로그래밍 및 기능 프로그래밍이 함께 잘 작동하는 이유입니다. 반응성 프로그래밍은 변수를 돌연변이 할 필요성을 제거하면서 가변 돌연변이로 달성 할 수있는 많은 일을 할 수 있습니다.

그런 다음이를 기반으로 일부 계산을 수행하면 결과 값은 시간이 지남에 따라 변경되는 값도됩니다. 예를 들어:

minX = x - 16;
minY = y - 16;
maxX = x + 16;
maxY = y + 16;

이 예에서 minX 마우스 포인터의 x 좌표보다 항상 16이 작습니다. 반응식 인식 라이브러리를 사용하면 다음과 같은 말을 할 수 있습니다.

rectangle(minX, minY, maxX, maxY)

그리고 마우스 포인터 주위에 32x32 상자가 그려져 움직이는 곳마다 추적합니다.

여기에 꽤 좋습니다 기능적 반응 프로그래밍에 관한 논문.

그것이 어떤 것인지에 대한 첫 번째 직관에 도달하는 쉬운 방법은 프로그램이 스프레드 시트이며 모든 변수가 셀이라고 상상하는 것입니다. 스프레드 시트의 셀 중 하나가 변경되면 해당 셀을 참조하는 셀도 변경됩니다. FRP와 동일합니다. 이제 일부 세포가 자체적으로 변화한다고 상상해보십시오 (또는 오히려 외부 세계에서 가져옵니다) GUI 상황에서 마우스의 위치가 좋은 예가 될 것입니다.

그것은 반드시 오히려 많은 것을 놓치고 있습니다. 실제로 FRP 시스템을 사용할 때 은유가 꽤 빨리 분해됩니다. 우선, 일반적으로 개별 이벤트를 모델링하려는 시도가 있습니다 (예 : 마우스를 클릭하는 마우스). 나는 당신에게 그것이 어떤지 아이디어를주기 위해 이것을 여기에두고 있습니다.

나에게 그것은 상징의 약 2 가지 의미입니다 =:

  1. 수학에서 x = sin(t) 그것을 의미합니다 x ~이다 다른 이름 ~을 위한 sin(t). 그래서 글쓰기 x + y 같은 것입니다 sin(t) + y. 기능적 반응 프로그래밍은 이와 관련하여 수학과 같습니다. x + y, 그것은 값이 무엇이든 계산됩니다 t 당시에는 사용됩니다.
  2. C와 같은 프로그래밍 언어 (필수 언어), x = sin(t) 과제입니다 : 그것은 의미합니다 x 저장 가치 sin(t) 과제 당시 촬영.

좋아, 배경 지식과 당신이 지적한 Wikipedia 페이지를 읽어 보면 반응형 프로그래밍은 데이터 흐름 컴퓨팅과 비슷하지만 특정 외부 "자극"이 노드 집합을 실행하여 계산을 실행하는 것으로 보입니다.

이는 예를 들어 사용자 인터페이스 컨트롤(예: 음악 재생 애플리케이션의 볼륨 컨트롤)을 터치하면 다양한 표시 항목과 오디오 출력의 실제 볼륨을 업데이트해야 하는 UI 디자인에 매우 적합합니다.방향성 그래프의 노드와 관련된 값을 수정하는 데 해당하는 볼륨(예: 슬라이더)을 수정하는 경우.

해당 "볼륨 값" 노드의 가장자리를 갖는 다양한 노드가 자동으로 트리거되고 필요한 계산 및 업데이트가 자연스럽게 애플리케이션을 통해 파급됩니다.애플리케이션은 사용자 자극에 "반응"합니다.함수형 리액티브 프로그래밍은 이 아이디어를 함수형 언어로 구현하거나 일반적으로 함수형 프로그래밍 패러다임 내에서 구현하는 것입니다.

"데이터 흐름 컴퓨팅"에 대한 자세한 내용을 보려면 Wikipedia에서 해당 두 단어를 검색하거나 즐겨 사용하는 검색 엔진을 사용하세요.일반적인 아이디어는 다음과 같습니다.이 프로그램은 각각 간단한 계산을 수행하는 노드의 방향성 그래프입니다.이러한 노드는 일부 노드의 출력을 다른 노드의 입력에 제공하는 그래프 링크로 서로 연결됩니다.

노드가 계산을 실행하거나 수행할 때 출력에 연결된 노드에는 해당 입력이 "트리거"되거나 "표시"됩니다.모든 입력이 트리거/표시/사용 가능한 모든 노드가 자동으로 실행됩니다.그래프는 반응형 프로그래밍이 어떻게 구현되는지에 따라 암시적이거나 명시적일 수 있습니다.

노드는 병렬로 실행되는 것으로 볼 수 있지만 직렬로 실행되거나 제한된 병렬 처리로 실행되는 경우가 많습니다(예를 들어 노드를 실행하는 스레드가 몇 개 있을 수 있음).유명한 예는 다음과 같습니다. 맨체스터 데이터플로우 머신, (IIRC)는 태그된 데이터 아키텍처를 사용하여 하나 이상의 실행 단위를 통해 그래프의 노드 실행을 예약했습니다.데이터 흐름 컴퓨팅은 계산의 계단식을 발생시키는 비동기식 트리거 계산이 시계(또는 시계)에 의해 실행을 제어하도록 시도하는 것보다 더 잘 작동하는 상황에 매우 적합합니다.

반응형 프로그래밍은 이 "단계적 실행" 아이디어를 가져오고 데이터 흐름과 유사한 방식으로 프로그램을 생각하는 것처럼 보이지만 일부 노드가 "외부 세계"에 연결되어 있고 이러한 감각이 실행될 때 단계적 실행이 트리거된다는 조건이 있습니다. -노드가 변경되는 것과 같습니다.그러면 프로그램 실행은 복잡한 반사 호와 유사한 것처럼 보일 것입니다.프로그램은 기본적으로 자극 사이에 고정될 수도 있고 그렇지 않을 수도 있고, 자극 사이에 기본적으로 고정 상태로 정착될 수도 있습니다.

"비반응형" 프로그래밍은 실행 흐름과 외부 입력과의 관계에 대해 매우 다른 관점으로 프로그래밍하는 것입니다.사람들은 외부 입력에 반응하는 모든 것이 자신에게 "반응"한다고 말하고 싶은 유혹을 받을 가능성이 높기 때문에 다소 주관적일 수 있습니다.그러나 기본적으로 고정된 간격으로 이벤트 큐를 폴링하고 발견된 이벤트를 함수(또는 스레드)에 전달하는 프로그램은 반응성이 덜합니다(고정된 간격으로 사용자 입력에만 주의를 기울이기 때문입니다).다시 말하지만, 여기에 있는 것의 정신은 다음과 같습니다.매우 낮은 수준의 시스템에 빠른 폴링 간격을 가진 폴링 구현을 배치하고 그 위에 반응적인 방식으로 프로그래밍하는 것을 상상할 수 있습니다.

FRP에 대한 많은 페이지를 읽은 후 마침내 이것 FRP에 대한 글쓰기를 깨달았으며, 마침내 FRP가 실제로 무엇인지 이해하게 만들었습니다.

나는 하인리히 아펠 머스 (Heinrich Apfelmus) (반응성 바나나의 저자)를 인용한다.

기능적 반응 프로그래밍의 본질은 무엇입니까?

일반적인 대답은“FRP는 변이 가능한 상태 대신 시간 변동 함수 측면에서 시스템을 설명하는 것”이며, 그것은 확실히 잘못되지 않을 것입니다. 이것은 의미 론적 관점입니다. 그러나 제 생각에는 더 깊고 만족스러운 대답은 다음과 같은 순전히 구문 적 기준에 의해 주어집니다.

기능적 반응성 프로그래밍의 본질은 선언 당시에 완전히 값의 동적 동작을 지정하는 것입니다.

예를 들어, 카운터의 예를 들어보십시오. "up"과 "down"이라는 두 개의 버튼이 카운터를 증가 시키거나 줄이는 데 사용할 수 있습니다. 필수적으로 먼저 초기 값을 지정한 다음 버튼을 누를 때마다 변경합니다. 이 같은:

counter := 0                               -- initial value
on buttonUp   = (counter := counter + 1)   -- change it later
on buttonDown = (counter := counter - 1)

요점은 선언 당시에는 카운터의 초기 값 만 지정된다는 것입니다. 카운터의 동적 동작은 나머지 프로그램 텍스트에 암시 적입니다. 대조적으로, 기능적 반응성 프로그래밍은 다음과 같이 선언 당시 전체 동적 동작을 지정합니다.

counter :: Behavior Int
counter = accumulate ($) 0
            (fmap (+1) eventUp
             `union` fmap (subtract 1) eventDown)

카운터의 역학을 이해하고 싶을 때마다 그 정의 만 살펴 봐야합니다. 일어날 수있는 모든 것이 오른쪽에 나타납니다. 이는 후속 선언이 이전에 선언 된 값의 동적 동작을 변경할 수있는 명령 적 접근법과 대조적입니다.

그래서 내 이해 FRP 프로그램은 일련의 방정식입니다.enter image description here

j 개별 : 1,2,3,4 ...

f 에 따라 다릅니다 t 따라서 이것은 외부 자극을 모델링 할 수있는 가능성을 통합합니다

프로그램의 모든 상태는 변수로 캡슐화됩니다 x_i

FRP 라이브러리는 진행 시간, 즉 j 에게 j+1.

나는이 방정식을 훨씬 더 자세히 설명합니다 이것 동영상.

편집하다:

원래 답변 이후 약 2 년 후, 최근에 나는 FRP 구현이 또 다른 중요한 측면을 가지고 있다는 결론에 도달했습니다. 그들은 중요한 실질적인 문제를 해결해야합니다. 캐시 무효화.

방정식 x_i-종속성 그래프를 설명합니다. 일부일 때 x_i 시간에 변경됩니다 j 그런 다음 다른 사람은 아닙니다 x_i'j+1 업데이트해야하므로 일부 종속성을 재 계산할 필요는 없습니다. x_i' 독립적 일 수 있습니다 x_i.

뿐만 아니라, x_i-변화하는 것은 점진적으로 업데이트 될 수 있습니다. 예를 들어 맵 작업을 고려해 봅시다 f=g.map(_+1) 스칼라에서 어디에 f 그리고 g ~이다 ListInts. 여기 f 대응합니다 x_i(t_j) 그리고 g ~이다 x_j(t_j). 이제 요소를 준비하면 g 그런 다음 수행하는 것이 낭비 될 것입니다 map 모든 요소에 대한 작동 g. 일부 FRP 구현 (예 : 반사 FRP)이 문제를 해결하는 것을 목표로하십시오. 이 문제는 다음으로도 알려져 있습니다 증분 컴퓨팅.

다시 말해, 행동 (the x_i-S) FRP에서는 캐시 엔드 계산으로 생각할 수 있습니다. FRP 엔진의 작업은 이러한 캐시 S ( x_i-S) 일부인 경우 f_i-S 변경됩니다.

종이 단순히 효율적인 기능적 반응성 Conal Elliott (직접 PDF, 233 kb)는 상당히 좋은 소개입니다. 해당 라이브러리도 작동합니다.

종이는 이제 다른 종이로 대체되었습니다. 푸시 풀 기능 반응성 프로그래밍 (직접 PDF, 286 KB).

면책 조항 : 내 대답은 rx.js -JavaScript를위한 '반응 형 프로그래밍'라이브러리의 맥락에 있습니다.

기능 프로그래밍에서 컬렉션의 각 항목을 반복하는 대신 컬렉션 자체에 고차 기능 (HOF)을 적용합니다. 따라서 FRP의 아이디어는 각 개별 이벤트를 처리하는 대신 이벤트 스트림 (관찰 가능한*로 구현)을 만들고 대신 HOF를 적용한다는 것입니다. 이렇게하면 게시자를 가입자에게 연결하는 데이터 파이프 라인으로 시스템을 시각화 할 수 있습니다.

관찰 가능한 사용의 주요 장점은 다음과 같습니다.
i) 이벤트 핸들러가 모든 'N'이벤트에 대해서만 해고되기를 원하거나 첫 번째 'N'이벤트 후에 해고를 중단하거나 첫 번째 'N 이후에만 해고를 시작하는 경우 코드에서 상태를 추상화합니다. '이벤트, 카운터를 설정, 업데이트 및 확인하는 대신 HOF (필터, 테이크 틀트, 스킵) 만 사용할 수 있습니다.
ii) 코드 로컬을 향상시킵니다 - 구성 요소의 상태를 변경하는 5 개의 이벤트 처리기가있는 경우 관찰 가능성을 병합하고 병합 된 관찰 가능한 대신 단일 이벤트 핸들러를 5 개의 이벤트 핸들러를 1로 효과적으로 결합 할 수 있습니다. 전체 시스템의 어떤 이벤트가 구성 요소에 영향을 줄 수 있는지에 대해 쉽게 추론 할 수 있습니다. 모든 것이 단일 핸들러에 존재하기 때문입니다.

  • 관찰 가능한 것은 반복 가능한 이중입니다.

반복 가능한 것은 게으르게 소비 된 시퀀스입니다. 각 항목은 반복기를 사용할 때마다 반복자에 의해 끌어 당겨서 열거는 소비자에 의해 구동됩니다.

관찰 가능한 것은 게으르게 생성 된 시퀀스입니다. 각 항목은 시퀀스에 추가 될 때마다 관찰자에게 푸시되므로 열거는 생산자에 의해 구동됩니다.

야, 이것은 놀라운 훌륭한 아이디어입니다! 왜 1998 년에 이것에 대해 알게되지 않았습니까? 어쨌든, 여기에 대한 나의 해석이 있습니다 프랜 지도 시간. 제안이 가장 환영합니다. 저는이를 기반으로 게임 엔진을 시작하는 것에 대해 생각하고 있습니다.

import pygame
from pygame.surface import Surface
from pygame.sprite import Sprite, Group
from pygame.locals import *
from time import time as epoch_delta
from math import sin, pi
from copy import copy

pygame.init()
screen = pygame.display.set_mode((600,400))
pygame.display.set_caption('Functional Reactive System Demo')

class Time:
    def __float__(self):
        return epoch_delta()
time = Time()

class Function:
    def __init__(self, var, func, phase = 0., scale = 1., offset = 0.):
        self.var = var
        self.func = func
        self.phase = phase
        self.scale = scale
        self.offset = offset
    def copy(self):
        return copy(self)
    def __float__(self):
        return self.func(float(self.var) + float(self.phase)) * float(self.scale) + float(self.offset)
    def __int__(self):
        return int(float(self))
    def __add__(self, n):
        result = self.copy()
        result.offset += n
        return result
    def __mul__(self, n):
        result = self.copy()
        result.scale += n
        return result
    def __inv__(self):
        result = self.copy()
        result.scale *= -1.
        return result
    def __abs__(self):
        return Function(self, abs)

def FuncTime(func, phase = 0., scale = 1., offset = 0.):
    global time
    return Function(time, func, phase, scale, offset)

def SinTime(phase = 0., scale = 1., offset = 0.):
    return FuncTime(sin, phase, scale, offset)
sin_time = SinTime()

def CosTime(phase = 0., scale = 1., offset = 0.):
    phase += pi / 2.
    return SinTime(phase, scale, offset)
cos_time = CosTime()

class Circle:
    def __init__(self, x, y, radius):
        self.x = x
        self.y = y
        self.radius = radius
    @property
    def size(self):
        return [self.radius * 2] * 2
circle = Circle(
        x = cos_time * 200 + 250,
        y = abs(sin_time) * 200 + 50,
        radius = 50)

class CircleView(Sprite):
    def __init__(self, model, color = (255, 0, 0)):
        Sprite.__init__(self)
        self.color = color
        self.model = model
        self.image = Surface([model.radius * 2] * 2).convert_alpha()
        self.rect = self.image.get_rect()
        pygame.draw.ellipse(self.image, self.color, self.rect)
    def update(self):
        self.rect[:] = int(self.model.x), int(self.model.y), self.model.radius * 2, self.model.radius * 2
circle_view = CircleView(circle)

sprites = Group(circle_view)
running = True
while running:
    for event in pygame.event.get():
        if event.type == QUIT:
            running = False
        if event.type == KEYDOWN and event.key == K_ESCAPE:
            running = False
    screen.fill((0, 0, 0))
    sprites.update()
    sprites.draw(screen)
    pygame.display.flip()
pygame.quit()

요컨대 : 모든 구성 요소를 숫자처럼 취급 할 수 있다면 전체 시스템을 수학 방정식처럼 취급 할 수 있습니까?

Paul Hudak의 책, Haskell School of Expression, Haskell에 대한 훌륭한 소개 일뿐 만 아니라 FRP에 상당한 시간을 소비합니다. FRP의 초보자라면 FRP의 작동 방식에 대한 감각을 제공하는 것이 좋습니다.

이 책의 새로운 재 작성 (2011 년 출시, 업데이트 된 2014), Haskell School of Music.

이전 답변에 따르면, 수학적으로, 우리는 단순히 더 높은 순서로 생각하는 것 같습니다. 가치를 생각하는 대신 엑스 유형이 있습니다 엑스, 우리는 기능을 생각합니다 엑스: 엑스, 어디 자연 수, 정수 또는 연속체 등의 시간 유형입니다. 이제 우리가 쓸 때 와이 := 엑스 + 1 프로그래밍 언어에서 우리는 실제로 방정식을 의미합니다. 와이() = 엑스() + 1.

언급 한 바와 같이 스프레드 시트처럼 작동합니다. 일반적으로 이벤트 중심 프레임 워크를 기반으로합니다.

모든 "패러다임"과 마찬가지로, 새로운 것은 논쟁의 여지가 있습니다.

액터의 분산 흐름 네트워크에 대한 나의 경험에서, 그것은 노드 네트워크에서 상태 일관성의 일반적인 문제에 쉽게 먹이를 줄 수 있습니다. 즉, 이상한 루프에서 많은 진동과 트래핑으로 끝납니다.

일부 의미론은 참조 루프 나 방송을 암시하기 때문에 피하기는 어렵고, 행위자 네트워크가 예측할 수없는 상태에서 수렴 (또는 그렇지 않음)에 따라 상당히 혼란 스러울 수 있습니다.

마찬가지로, 글로벌 주가 솔루션에서 멀어지기 때문에 잘 정의 된 가장자리가 있었음에도 불구하고 일부 주에 도달하지 못할 수 있습니다. 2+2는 2가 2가 된시기에 따라 4 살이되거나 4 살이되지 않을 수 있습니다. 스프레드 시트에는 동기 시계와 루프 감지가 있습니다. 분산 된 배우는 일반적으로 그렇지 않습니다.

모든 좋은 재미 :).

나는 Clojure Subreddit에서 FRP에 관한이 멋진 비디오를 발견했습니다. Clojure를 모르더라도 이해하기 쉽습니다.

비디오는 다음과 같습니다. http://www.youtube.com/watch?v=nket0k1rxu4

다음은 비디오가 두 번째 절반의 소스입니다. https://github.com/cicayda/yolk-examples/blob/master/src/yolk_examples/client/autocomplete.cljs

이 기사 Andre Staltz는 지금까지 본 것이 가장 좋고 명확한 설명입니다.

기사의 일부 인용문 :

반응 형 프로그래밍은 비동기 데이터 스트림으로 프로그래밍하고 있습니다.

게다가, 당신은 그 스트림을 결합, 생성 및 필터링 할 놀라운 기능 박스가 제공됩니다.

다음은 기사의 일부인 환상적인 다이어그램의 예입니다.

Click event stream diagram

시간이 지남에 따라 수학적 데이터 변환 (또는 시간 무시)에 관한 것입니다.

코드에서 이것은 기능적 순도와 선언적 프로그래밍을 의미합니다.

상태 버그는 표준 명령 패러다임에서 큰 문제입니다. 다양한 코드가 프로그램 실행에서 다른 "시간"으로 일부 공유 상태를 변경할 수 있습니다. 이것은 다루기가 어렵습니다.

FRP에서는 데이터가 한 상태에서 다른 상태로 변환되는 방법과 트리거링을 설명하는 방법을 설명합니다. 이를 통해 기능은 단순히 입력에 반응하고 현재 값을 사용하여 새 값을 만들기 때문에 시간을 무시할 수 있습니다. 이것은 상태가 변환 노드의 그래프 (또는 트리)에 포함되어 있으며 기능적으로 순수하다는 것을 의미합니다.

이것은 복잡성과 디버깅 시간을 크게 줄입니다.

수학의 A = B+C와 프로그램에서 A = B+C의 차이를 생각해보십시오. 수학에서는 결코 변하지 않는 관계를 설명하고 있습니다. 프로그램에서, 그것은 "지금 당장"A는 B+C라고 말합니다. 그러나 다음 명령은 B ++ 일 수 있습니다.이 경우 A는 B+C와 같지 않습니다. 수학 또는 선언 프로그래밍에서 A는 귀하가 요청하는 시점에 관계없이 항상 B+C와 동일합니다.

따라서 공유 상태의 복잡성을 제거하고 시간이 지남에 따라 변화하는 값을 변경함으로써. 귀하의 프로그램은 추론하기가 훨씬 쉽습니다.

EventStream은 EventStream + 일부 변환 기능입니다.

동작은 이벤트 스트림 + 메모리의 일부 가치입니다.

이벤트가 시작되면 변환 함수를 실행하여 값이 업데이트됩니다. 이것이 생성하는 값은 행동 메모리에 저장됩니다.

행동은 다른 행동을 변화시키는 새로운 행동을 만들기 위해 구성 될 수 있습니다. 이 구성된 값은 입력 이벤트 (동작) 화재로 다시 계산됩니다.

"관찰자는 무국적이기 때문에 드래그 예제에서와 같이 상태 기계를 시뮬레이션하기 위해 종종 여러 가지가 필요합니다. 위의 가변 경로와 같은 모든 관련 관찰자가 액세스 할 수있는 상태를 저장해야합니다."

인용 - 관찰자 패턴 감가 상각http://infoscience.epfl.ch/record/148043/files/deprecatingobserverstr20.pdf

반응성 프로그래밍에 대한 짧고 명확한 설명이 나타납니다. 사이클 - 반응성 프로그래밍, 간단하고 시각적 샘플을 사용합니다.

모듈/구성 요소/객체 반응성입니다 외부 이벤트에 반응하여 자체 상태를 관리 할 책임이 있음을 의미합니다.

이 접근법의 이점은 무엇입니까? 그것은이다 제어의 역전, 주로 [module/component/object]가 그 자체로 책임이 있기 때문에 공개 방법에 대한 개인 방법을 사용하여 캡슐화를 개선하기 때문입니다.

그것은 좋은 스타트 업 포인트이며, 완전한 Knowlege의 원천이 아닙니다. 거기에서 더 복잡하고 깊은 종이로 뛰어들 수 있습니다.

.NET의 RX, 반응성 확장을 확인하십시오. 그들은 ienumerable을 사용하면 기본적으로 스트림에서 '당기고있다'고 지적합니다. iqueryable/ienumerable에 대한 LINQ 쿼리는 세트에서 결과를 '빨리'하는 세트 작업입니다. 그러나 iobservable에 대한 동일한 연산자를 사용하면 '반응'이라는 LINQ 쿼리를 작성할 수 있습니다.

예를 들어, mx <100과 my <100 select new Point (mx, my)에서 MyObservableseTofMouseMovements에서 M에서 LINQ 쿼리를 작성할 수 있습니다.

그리고 RX 확장 기능을 사용하면 다음과 같습니다. 마우스 움직임의 흐름에 반응하는 UI 코드가 있으며 100,100 상자에 들어갈 때마다 드러납니다.

FRP는 기능적 프로그래밍 (모든 것이 기능이라는 아이디어를 기반으로 한 프로그래밍 패러다임)과 반응성 프로그래밍 패러다임 (모든 것이 스트림이라는 아이디어 (관찰자 및 관찰 가능한 철학))의 조합입니다. 그것은 세계 최고가되어야합니다.

반응 형 프로그래밍에 대한 Andre Staltz 게시물을 확인하십시오.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top