Kas yra (funkcinis) reaktyvus programavimas?

Aš perskaičiau Wikipedia straipsnį apie reaktyvų programavimą . Taip pat perskaitysiu trumpą straipsnį apie funkcinį reaktyvų programavimą . Apibūdinimas yra gana abstraktus.

  • Ką praktiškai reiškia funkcinis reaktyvus programavimas (FRP)?
  • Kas yra reaktyvus programavimas (priešingai nei reaktyvus programavimas?)?

Mano fonas yra būtinas / OO kalbos, todėl vertiname su šiuo paradigmu susijusį paaiškinimą.

1149
22 июня '09 в 19:41 2009-06-22 19:41 JtR nustatytas birželio 22 d., 09:41, 2009-06-22 19:41
@ 19 atsakymų

Jei norite pajusti FRP, nuo 1998 m. Galite pradėti nuo senos „ Fran“ pamokos , kurioje yra animacinių iliustracijų. Dokumentams pradėkite nuo Funkcinio reagavimo animacijos , o tada sekite nuorodas į skelbimo nuorodą mano pagrindiniame puslapyje ir Haskell wiki FRP .

Asmeniškai norėčiau galvoti apie tai, ką FRP reiškia prieš nuspręsdama, kaip tai padaryti. (Kodas be specifikacijos yra atsakymas be klausimo ir, vadinasi, „netgi ne“.) Todėl nepranešiu FRP pateikimo / įgyvendinimo požiūriu, nes Thomas K daro kitą atsakymą (grafikai, mazgai, briaunos, šaudymas, vykdymas ir ir tt). Yra daug galimų įgyvendinimo stilių, tačiau įgyvendinimas nesako, kas yra FRP.

Aš tikrai džiaugiuosi paprastu Laurence G aprašymu, kad FRP reiškia „duomenų tipus, kurie laikui bėgant yra vertingi“. Paprastas imperatyvus programavimas užfiksuoja šias dinamines vertybes tik netiesiogiai, per valstybės ir mutacijas. Ji taip pat neturi pirmos klasės požiūrio, be to, gali būti (netiesiogiai) užfiksuotos tik diskretiškai keičiamos vertės, nes imperatyvi paradigma laikinai yra atskirta, o atvirkščiai, FRP fiksuoja šias besikeičiančias vertybes ir neturi jokių problemų su nuolat besikeičiančios vertybės.

FRP taip pat yra neįprastas, nes jis yra lygiagretus, nesukuriant teorinės ir pragmatinės žiurkių lizdo, kuris reikalauja imperatyvumo. Semantiškai FRP sutapimas yra smulkiagrūdis, deterministinis ir nuolatinis. (Kalbu apie prasmę, o ne apie įgyvendinimą. Įgyvendinimas gali apimti arba negali apimti lygiagretumo ar lygiagretumo.) Semantinis tikrumas yra labai svarbus argumentavimui, tiek griežtam, tiek neformaliam. Nors lygiagretumas suteikia milžinišką sudėtingumą imperatyviam programavimui (dėl ne deterministinio interleavingo), jis yra lengvas FRP.

Taigi, kas yra FRP? Jūs galėtumėte pats su juo sugalvoti. Pradėkite nuo šių idėjų:

  • Dinaminės / keičiamosios vertės (t. Y. „Per tam tikrą laiką“) yra pačios pirmos klasės vertės. Galite nustatyti ir sujungti juos, perkelti juos į ir iš funkcijų. Šiuos dalykus pavadinau „elgesiu“.

  • Elgesys sukuriamas iš kelių primityvių, tokių kaip pastovus (statinis) elgesys ir laikas (pavyzdžiui, laikrodis), o po to su serijiniu ir lygiagrečiu deriniu. n yra sujungtos, taikant n-ary funkciją (statinėmis vertėmis), „taškas pagal tašką“, t.y. laikui bėgant.

  • Atskleidžiant atskirus reiškinius, egzistuoja skirtingas „įvykių“ tipas (šeima), kurių kiekvienas turi įvykių srautą (baigtinį ar begalinį). Kiekvienas įvykis turi atitinkamą laiką ir vertę.

  • Norėdami parengti kompozicijos žodyną, iš kurio galite sukurti visą elgesį ir įvykius, žaisti su kai kuriais pavyzdžiais. Toliau dekonstruoti į dažniau pasitaikančius / paprastesnius gabalus.

  • Kad žinotumėte, kad esate tvirtame pagrinde, suteikite visam modeliui sudėtinį pagrindą, naudojant denotacinį semantikos metodą, kuris paprasčiausiai reiškia, kad (a) kiekvienas tipas turi atitinkamą paprastą ir tikslų matematinį „reikšmės“ tipą ir (b) kiekvieną primityvų ir operatorių Ji turi paprastą ir tikslią reikšmę kaip komponentų vertybių funkciją. Niekada niekada nesuderinkite įgyvendinimo aspektų mokslinių tyrimų procese. Jei šis aprašymas jums yra gibberis, pasikonsultuokite (a) Denotacinis dizainas su klasės tipo morfizmais , (b) stūmimo funkcinis reaktyvus programavimas (ignoruojant diegimo bitus) ir (c) „ Denatational Semantics Haskell“ wikibooks puslapis . Atkreipkite dėmesį į tai, kad denotacinė semantika susideda iš dviejų dalių: iš dviejų steigėjų: Kristoferis Straha ir Dana Scott: paprastesnė ir naudingesnė baimių dalis ir sudėtingesnė bei mažiau naudinga (programinės įrangos kūrimo) dalis.

Jei laikotės šių principų, tikiuosi, kad kažką daugiau ar mažiau gausite FRP dvasia.

Kur galiu gauti šiuos principus? Programinės įrangos kūrimo metu visada užduodu tą patį klausimą: „ką tai reiškia?“. Denominacinis semantika davė man aiškų pagrindą šiam klausimui, o tas, kuris atitinka mano estetiką (priešingai nei operatyviniai ar aksiominiai semantika, kurie abu palieka mane nepatenkinti). Taigi paklausiau savęs, koks toks elgesys? Greitai supratau, kad laikinas diskretiškas skaičiavimo pobūdis yra tam tikro automobilio stiliaus vieta, o ne pats natūralus elgesio aprašymas. Paprasčiausias tikslus elgesio aprašymas, kurį galiu galvoti, yra tik „(tęstinė) laiko funkcija“, todėl mano modelis. Maloniai, šis modelis tvarko nenutrūkstamą deterministinį sutapimą lengvai ir maloniai.

Tai buvo gana sunku įgyvendinti šį modelį teisingai ir efektyviai, bet tai dar viena istorija.

932
23 июня '09 в 7:31 2009-06-23 07:31 atsakymą pateikė Conal birželio 23 d., 07:31, 2009-06-23 07:31

Grynai funkciniu programavimu nėra jokių šalutinių poveikių. Daugeliui programinės įrangos tipų (pavyzdžiui, kažkas su vartotojo sąveika), šalutinis poveikis yra būtinas tam tikru lygiu.

Vienas iš būdų gauti šalutinį poveikį, kaip ir palaikant funkcinį stilių, yra naudoti funkcinį reaktyvųjį programavimą. Tai yra funkcinio programavimo ir reaktyvaus programavimo derinys. („Wikipedia“ straipsnis, į kurį kalbate, nurodo pastarąjį.)

Pagrindinė reaktyvaus programavimo idėja yra tai, kad yra tam tikrų tipų duomenų, kurie atspindi „laikui bėgant“. Skaičiavimai, į kuriuos įeina šios vertės su laiko pasikeitimu, patys turės laiko pokyčių.

Pvz., Galite pagalvoti apie pelės koordinates kaip verčių porą su sveikais skaičiais. Tarkime, mes turime kažką panašaus (tai yra pseudokodas):

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

Bet kuriuo metu x ir y turės pelės koordinates. Skirtingai nei neaktyvus programavimas, mes turime atlikti šią užduotį tik vieną kartą, o kintamieji x ir y liks automatiškai atnaujinami. Štai kodėl reaktyvus programavimas ir funkcinis programavimas veikia taip gerai: reaktyvus programavimas pašalina poreikį keisti kintamuosius, o tuo pačiu leidžia jums daryti daug su kintamomis mutacijomis.

border=0

Jei atliksite kai kuriuos skaičiavimus pagal tai, gautos vertės taip pat bus laikui bėgant keičiančios vertės. Pavyzdžiui:

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

Šiame pavyzdyje minX visada bus 16 mažesnis nei pelės žymiklio x koordinatė. Su bibliotekomis, galinčiomis atsakyti, galite pasakyti kažką panašaus:

 rectangle(minX, minY, maxX, maxY) 

Ir 32x32 >

Čia yra gana geras straipsnis apie funkcinį reaktyvų programavimą .

740
22 июня '09 в 21:06 2009-06-22 21:06 Atsakymą pateikė Laurence Gonsalves birželio 22 d., 09:21 2009-06-22 21:06

Lengvas būdas pasiekti pirmąją intuiciją - įsivaizduoti, kad jūsų programa yra skaičiuoklė, ir visi jūsų kintamieji yra ląstelės. Jei pasikeičia bet kuri skaičiuoklėje esanti ląstelė, taip pat pasikeičia visos ląstelės, kuriose nurodoma ši ląstelė. Tai yra lygiai taip pat su FRP. Dabar įsivaizduokite, kad kai kurios ląstelės savaime keičiasi (arba yra paimtos iš išorinio pasaulio): situacijoje su grafine sąsaja pelės padėtis būtų geras pavyzdys.

Tai tikrai praleis daug. Metafora greitai sugenda, kai naudojate FRP sistemą. Pirma, paprastai bandoma modeliuoti atskirus įvykius (pavyzdžiui, pelės paspaudimus). Aš ką tik įdėjau čia, kad suteikčiau jums idėjos, kaip jums patinka.

144
23 июня '09 в 17:52 2009-06-23 17:52 atsakymą pateikė Bobas birželio 23 d. 09:17 val. 2009-06-23 17:52

Man tai yra apie dvi skirtingas simbolio reikšmes = :

  • Matematikoje x = sin(t) reiškia, kad x kitas sin(t) . Taigi x + y yra toks pat kaip sin(t) + y . Funkcinis reaktyvus programavimas yra panašus į matematiką šiuo atžvilgiu: jei rašote x + y , jis apskaičiuojamas naudojant bet kurią t vertę jos naudojimo metu.
  • C tipo programavimo kalbomis (imperatyvios kalbos) x = sin(t) yra tikslas: tai reiškia, kad x išsaugo vertę sin(t) paimtas paskirties vietoje.
132
25 мая '12 в 17:52 2012-05-25 17:52 atsakymą pateikė vartotojo712092 gegužės 25, 12, 17:52 2012-05-25 17:52

Gerai, iš foninių žinių ir Wikipedia puslapio, kurį nurodėte, skaitymas, atrodo, kad reaktyvus programavimas yra kažkas panašaus į duomenų apdorojimo srautą, bet su specialiais išoriniais "stimulais", kurie inicijuoja mazgų rinkinį pradėti ir atlikti jų skaičiavimus.

Tai puikiai tinka vartotojo sąsajos dizainui, pavyzdžiui, kai paliesite vartotojo sąsają (pvz., Muzikos programos garsumo valdymas) gali tekti atnaujinti įvairius ekrano elementus ir faktinį garso išvesties tūrį. Pakeitus garsumą (pvz., Slankiklį), kuris atitinka nukreipto grafiko vertės, susijusios su mazgu, pasikeitimą.

Įvairūs mazgai, turintys kraštų iš šio mazgo „tūrio vertės“, automatiškai pradės veikti, o visi būtini skaičiavimai ir naujinimai natūraliai pulsuos per taikomąją programą. Programa „reaguoja“ į vartotojo stimulą. Funkcinis reaktyvus programavimas paprasčiausiai bus šios idėjos įsikūnijimas funkcine kalba arba, paprastai, funkcinės programavimo paradigmos sistemoje.

Daugiau informacijos apie „duomenų srauto apskaičiavimą“ rasite šiuos du žodžius „Wikipedia“ arba naudokite savo mėgstamą paieškos variklį. Bendra idėja yra tokia: programa yra nukreiptų mazgų, kurių kiekvienas atlieka kelis paprastus skaičiavimus, grafikas. Šie mazgai yra tarpusavyje sujungti grafiniais ryšiais, kurie suteikia kai kurių mazgų išvestį kitiems.

Kai mazgas prasideda arba atlieka savo skaičiavimus, prie jo išėjimų prijungti mazgai turi atitinkamus įėjimus „suaktyvinti“ arba „pažymėti“. Įjungiamas bet kuris mazgas, kuriame yra visi įėjimai, kurie yra paleisti / pažymėti / prieinami automatiškai. Grafikas gali būti netiesioginis arba aiškus, priklausomai nuo to, kaip įgyvendinamas reaktyvus programavimas.

Mazgai gali būti vertinami kaip lygiagrečiai šaudomi, tačiau dažnai jie atliekami nuosekliai arba ribotai lygiagrečiai (pavyzdžiui, gali būti kelios temos). Gerai žinomas pavyzdys yra „ Manchester Dataflow“ mašina , kuri (IIRC) naudojo žymėtą duomenų architektūrą, kad grafikas per mazgus įvykdytų vienu ar daugiau vienetų. Kompiuterinių duomenų srautas gana gerai tinka situacijoms, kai skaičiavimų inicijavimas asinchroniškai lemia kaskadinius skaičiavimus, veikia geriau nei bandymas atlikti laikrodį (ar valandas).

Reaktyvus programavimas importuoja šią „vykdymo kaskados“ idėją ir, atrodo, galvoja apie duomenų srauto stiliaus programą, tačiau su sąlyga, kad kai kurie mazgai yra prijungti prie „išorinio pasaulio“ ir paleisti vykdymo kaskadas, kai šie jutimo tipo mazgai pasikeičia. Programos vykdymas atrodytų panašus į sudėtingą refleksinį lanką. Programa gali būti arba negali būti sėdimoji tarp dirgiklių, arba gali pasilikti paprastai sėdimoje būsenoje tarp stimulų.

„Neaktyvus“ programavimas bus programuojamas visiškai kitokiu požiūriu į vykdymo srautą ir santykį su išoriniais įėjimais. Tai tikriausiai bus šiek tiek subjektyvus, nes žmonės gali būti linkę pasakyti kažką, kas reaguoja į išorinius išteklius, „reaguoja“ į juos. Tačiau žvelgiant į dalyko dvasią, programa, kuri apklausa įvykių eilę fiksuotu intervalu ir siunčia visus įvykio (ar srauto) įvykius, yra mažiau reaktyvi (nes ji naudojama tik vartotojo įvesties nustatytu intervalu). Vėlgi, tai yra šio dalyko dvasia: galite įsivaizduoti, kad apklausa įterpiama į greitojo apklausos intervalą į sistemą labai žemu lygmeniu ir programavimo reakcija į jį.

71
22 июня '09 в 20:45 2009-06-22 20:45 Atsakymas Thomas Kammeyer'ui birželio 22 d., 09:45 , 2009-06-22 20:45

Perskaitęs daugelį FRP puslapių, aš pagaliau atėjau į šį Šviečiantį laišką apie FRP, jis pagaliau privertė mane suprasti, kas yra FRP.

Aš cituoju žemiau Heinrich Apfelmus (reaktyvinio banano autorius).

Kas yra funkcinio reaktyvaus programavimo esmė?

Bendras atsakymas yra tas, kad "FRP yra sistemos aprašymas, atsižvelgiant į laiko kintančias funkcijas, o ne keičiamą būseną", ir tai tikrai nebus klaida. Tai yra semantinis požiūris. Tačiau, mano nuomone, gilesnis, patenkinamas atsakymas, remiantis grynai sintaksiniu kriterijumi:

Funkcinio reaktyvaus programavimo esmė yra tiksliai apibrėžti dinaminę vertės reikšmę deklaracijos metu.

Pavyzdžiui, paimkite skaitiklio pavyzdį: turite du mygtukus, pažymėtus „aukštyn“ ir „žemyn“, kuriuos galima naudoti norint padidinti ar sumažinti skaitiklį. Būtinai pirmiausia turite nurodyti pradinę vertę ir tada ją pakeisti, kai paspausite mygtuką; kažkas panašaus:

  counter: = 0 - начальное значение on buttonUp = (счетчик: = счетчик + 1) - изменить его позже on buttonDown = (счетчик: = счетчик - 1) Код> 

Faktas yra tas, kad paskelbimo metu nurodoma tik pradinė skaitiklio vertė; Skaitiklio dinaminis elgesys yra įtrauktas į likusį programos tekstą. Priešingai, funkcinis reaktyvus programavimas nustato visą dinaminį elgesį deklaravimo metu, pavyzdžiui:

  counter:: Behavior Int counter = accumulate ($) 0   (fmap (+1) eventUp`union` fmap (вычесть 1) eventDown) Код> 

Jei norite suprasti skaitiklio dinamiką, turite tik pažvelgti į jo apibrėžimą. Viskas, kas jam gali įvykti, bus rodoma dešinėje. Tai labai skiriasi nuo tada, kai vėlesnės deklaracijos gali dinamiškai elgtis pagal anksčiau deklaruotas vertes.

Taigi, mano supratimu, FRP programa yra lygčių rinkinys: 2019

65
31 янв. jhegedus atsakymas yra sausio 31 d 2015-01-31 06:46 '15 at 6:46 2015-01-31 06:46

Atsakomybės apribojimas: mano atsakymas yra rx.js kontekste - „reaktyvaus programavimo“ biblioteka „Javascript“.

Funkcinio programavimo atveju, vietoj to, kad kartotumėte kiekvieną kolekcijos elementą, pačiai kolekcijai taikysite aukštesnes užsakymo funkcijas (HoF). Taigi FRP idėja yra ta, kad vietoj kiekvieno atskiro įvykio apdorojimo sukurkite įvykių srautą (įgyvendinamas naudojant stebimą *) ir vietoj to taikykite HoF. Taigi, galite vizualizuoti sistemą kaip duomenų srautus, jungiančius leidėjus su abonentais.

Pagrindiniai pastebėto:
i) ji ištraukia būseną iš jūsų kodo, pavyzdžiui, jei norite, kad įvykių tvarkytojas būtų paleistas tik už kiekvieną antrąjį įvykį arba sustabdytų šaudymą po pirmųjų „n“ įvykių arba pradėsite fotografuoti tik po pirmojo „n“, galite tiesiog vietoj nustatymo, atnaujinimo ir tikrinimo naudokite „HoFs“ (filtras, paimkite iki, praleiskite atitinkamai).
ii) pagerina kodų lokalizaciją - jei turite 5 skirtingus įvykių tvarkytojus, kurie keičia komponento būseną, galite derinti jų stebimus ir nustatyti vieną stebėtojo stebėtoją, efektyviai derinant 5 įvykių tvarkytojus 1. Tai leidžia lengvai suprasti , какие события во всей системе могут повлиять на компонент, поскольку все это присутствует в одном обработчике.

  • Наблюдаемое - это двойственное значение Итерабельного.