/
Deprecating the Observer Pattern with Scala Deprecating the Observer Pattern with Scala

Deprecating the Observer Pattern with Scala - PDF document

ellena-manuel
ellena-manuel . @ellena-manuel
Follow
404 views
Uploaded On 2015-05-28

Deprecating the Observer Pattern with Scala - PPT Presentation

React EPFLREPORT176887 Ingo Maier Martin Odersky EPFL rstnamelastnameepch Abstract Programming interactive systems by means of the observer pattern is hard and errorprone yet is still the implementation standard in many production environments We s ID: 76023

React EPFLREPORT176887 Ingo Maier Martin

Share:

Link:

Embed:

Download Presentation from below link

Download Pdf The PPT/PDF document "Deprecating the Observer Pattern with Sc..." is the property of its rightful owner. Permission is granted to download and print the materials on this web site for personal, non-commercial use only, and to display it on your personal computer provided you do not modify the materials and that you retain all copyright notices contained in the materials. By downloading content from our website, you accept the terms of this agreement.


Presentation Transcript

mousemoveobserverandweneedtorememberthesub-ject(pointofinstallation).SeparationofconcernsTheobserversfromourexamplenotonlytracethemousepathbutalsocalladraw-ingcommand,ormoregenerally,includetwodifferentconcernsinthesamecodelocation.Itisoftenprefer-abletoseparatetheconcernsofconstructingthepathanddisplayingit,e.g.,asinthemodel-view-controller(MVC)[31]pattern.DataconsistencyWecanachieveaseparationofconcernswithapaththatitselfpublisheseventswhenitchanges.Unfortunately,thereisnoguaranteefordataconsistencyintheobserverpattern.Supposewecreatearectanglethatrepresentstheboundsofourpath,i.e.,apublisherthatdependsonchangesinouroriginalpath.Alsocon-sideranobserverlisteningtochangesinboththepathanditsboundsinordertodrawaframedpath.Thisobserverneedstotrackexplicitlywhethertheboundsarealreadyupdatedand,ifnot,deferthedrawingoperation.Other-wisetheusercouldobserveaframeonthescreenthathasthewrongsize,whichisanexampleofaglitch.UniformityDifferentmethodstoinstalldifferentobserversdecreasecodeuniformity.AbstractionTheobserverpatternpromotestheuseofheavy-weightinterfaces.Theexamplereliesonacontrolclassthatoftendenesamuchlargerinterfacethanamethodtoinstallmouseeventobservers.Therefore,wecannotabstractovereventsourcesindividually.Forinstance,wecouldlettheuserabortadragoperationbyhittinganypredenedkeyoruseadifferentpointerdevicesuchasatouchscreenorgraphicstablet.SemanticdistanceTheexampleishardtounderstandbe-causethecontrolowisinvertedwhichresultsinmuchboilerplatecodeandincreasesthesemanticdistancebe-tweentheprogrammersintentionandtheactualcode.Mousedraggingisjustanexampleofthemoregeneralsetofinputgesturerecognition.Ifwefurthergeneralizethistoeventsequencerecognitionwith(boundedorunbounded)loops,alltheproblemswementionedabovestillremain.Manyexamplesinuserinterfaceprogrammingarethereforeequallyhardtoimplementwithobservers,suchasselectingasetofitems,steppingthroughaseriesofdialogs,editingandmarkingtext–essentiallyeveryoperationwheretheusergoesthroughanumberofsteps.1.1ContributionsandOverviewWepresentScala.React,alibraryofcomposable,discretereactiveprogrammingabstractionsthatprovidesseveralAPIlayerstoallowprogrammerstostepwisemigratefromanobserver-basedtoareactivedata-owprogrammingmodelthateventuallyaddressesalloftheissuesraisedabove.Ourcontributionsareinparticular:WeextendScalawithatypedhigher-orderreactivepro-gramminglibrarythatallowstocombinereactivepro-grammingbothinafunctionalaswellasinimpera-tivestyle.WeshowhowtheseabstractionintegratewithScala'sobjectsystemandhowthetraitconceptsimpliesbindingobserver-basedinterfacestoourreactiveabstrac-tions.Weshowhowtoincorporateasynchronousdata-owlanguagesimilartoEsterel[6],butextendedtoamulti-valueddomainandwithhigher-orderfeatures,intoourreactiveframework.Wepresentanapproachbasedontraitsandweakrefer-encesthatautomaticallybindsthelife-timeofobserverstoanenclosingobject,eliminatingacommonsourceofmemoryleaksinobserver-basedandreactiveprogram-ming.Weshowhowtoimplementourlanguageasalibraryintermsofadependencystack,closuresanddelimitedcontinuations.Incontrasttoprevioussimilarsystems,ourimplementationisagnosticofanyhostlanguagefeature,andtreatseveryexpressionuniformly,nomatterwhetherbuilt-inoruser-dened,includingfunctionapplication,conditionals,loops,exceptionsandcustomcontrolowoperators,withoutspecialtreatmentbyamacrosystemorexplicitlifting.WepresentandanalyzeperformanceresultsofdifferentimplementationapproachesinScala.Reactandpresenttherstperformancecomparisonoftworelatedreac-tivelibrariesondifferent,productionqualityplatforms.Inordertoobtainmeaningfulresults,wemeasureper-formanceofreactiveimplementationsrelativetocorre-spondingobserver-basedimplementationsonthesameplatform.Weanalyzeexistingfunctionalreactivepro-gramsandproposefavorablesolutionsusingalternativeabstractionsinScala.React.Althoughourrunningexampleisdrawnfromuserinter-faceprogramming,Scala.Reactcanalsobeusedforamanyothereventprocessingdomains,suchasnancialengineer-ing,industrialcontrolsystems,automaticpatientsupervi-sion,RFIDtrackingorrobotics.2.Eventstreams:auniforminterfaceforcomposableeventsAsarststeptosimplifyeventlogicweintroduceagen-eraleventinterface,addressingtheissuesofuniformityandabstractionfromabove.Athirdaspecttothisisreusability:byhidingeventpropagationandobserverhandlingbehindageneralinterface,clientscaneasilypublisheventsfortheirowndatastructures.WeintroduceaclassEventSource[A],whichrepresentsgenericsourcesofeventsoftypeA.Wecanscheduleaneventsourcetoemitavalueatanytime.Here22012/5/4 defaddActionListener(a:ActionListener)defremoveActionListener(a:ActionListener)valactionPerformed:Events[Action]=newEventSource[Action]{source=�this.addActionListener(newActionListener{defactionPerformed(e:ActionEvent)=sourceemitgetAction})}}TheabovecreatesatraitHasActionthatdenesasetofabstractmethodsthatitexpectstobeimplemented.WecannowtakeaJavaSwingJButtonandaddanactionPerformedeventstreambywritingclassMyButtonextendsJButtonwithHasActionvalbutton=newMyButtonobserve(button.actionPerformed){println("clicked")}NotethattheScalacompilerndsimplementationsofmeth-odsdenedintraitsbasedontheirsignature.ThisallowsustoconvenientlybindJButtontoaneventstreambecausefromtheperspectiveofthecompiler,classJButtonimple-mentstheabstractmethodsfromtraitHasActioneventhoughSwingdoesnotknowaboutourtrait.Inourexample,inordertologareasonwhytheap-plicationshouldquit,weneedtoconvergeonacommoneventtypeforallinvolvedstreams,e.g.,String.Wecanex-tractquitmessagesfromeachofthemergedeventstreamswiththehelpofthemapcombinatorwhichisdenedintraitEvents[A]:defmap[B](f:A=�B):Events[B]Itreturnsastreamofresultsthatemitsatthesametimeastheoriginalstreambuteacheventappliedtothegivenfunction.Wecannowimplementquitasfollows:valquit=quitButton.clicks.map(x=�"Ok")mergequitMenu.clicks.map(x=�"Ok")mergefatalExceptions.map(x=�x.getMessage)TherearemanymoreusefulcommonFRPcombinatorsinclassEventsaswewillseelater.3.Reactors:observerswithoutinversionofcontrolSincewehaveauniformobservationmechanismandrst-classevents,wecanabstractovertheeventsinvolvedinadragoperation.Therefore,wecandeneafunctionthatinstallsallnecessaryobserversforourdragcontroller:defmakePath(start:Events[Pos],move:Events[Pos],end:Events[Pos]):Path={valpath:Path=newPath()varmoveObserver:Observer=nullobserve(start){pos=�path.clear()path.moveTo(pos)moveObserver=observe(moves){pos=�...}}observe(end){pos=�moveObserver.dispose();...}path}Now,wecaneasilyletusersperformdragoperationswithadifferentpointerdeviceandstartorabortwithkeycommands.Forexample:makePath(pen.down,pen.moves,pen.upmergeescapeKeyDown.map(x=�pen.pos.now))Yet,threeimportantissuesremain.Thecontrolowisstillinverted,wehavetoexplicitlydisposethemousemoveobserverandhavenoeasymeanstodisposethedragbehav-iorasawhole.Ideally,wewanttodirectlyencodeastatemachinewhichcanbedescribedinformallyasfollows:1.Startanewpath,oncethemousebuttonispressed2.Untilthemouseisreleased,logallmousemovesaslinesinthepath3.Oncethemousebuttonisreleased,closethepathWecanturntheabovestepsintocodeinastraightforwardway,usingScala.React'simperativedata-owlanguageandtheconceptofreactors.Thefollowingreactorimplementsourrunningexamplewithoutinversionofcontrol.Reactor.loop{self=�//step1valpath=newPath((selfawaitmouseDown).position)self.loopUntil(mouseUp){//step2valm=selfawaitNextmouseMovepath.lineTo(m.position)draw(path)}path.close()//step3draw(path)}FactorymethodReactor.loopcreatesanewreactor,takingafunctionasanargumentwhichacceptsthereactorunderconstructionselfasanargument.Thisselfreferencegivesthefunctionahandletoadata-owDSL,fromwhichweusethreeoperatorsabove.MethodawaitandawaitNextaredenedasdefawait[A](e:Events[A]):AdefawaitNext[A](e:Events[A]):Aandsuspendthecurrentreactoruntilthegiveneventstreameemitsavalue.Methodawaitreturnimmediately,ifthegivenstreamiscurrentlyemitting,whereasawaitNextalwayssuspendsrst.Oncethestreamemitsanevente,itevaluatestoeandcontinuesthereactor'sexecution.Anotherusefuloperatorispause,returningnothing.Itsuspendsthecurrentreactorandcontinuesafterallpendingmessageshavebeenpropagatedbythereactiveframework.42012/5/4 self()=self.previous.close()}MethodSignal.flowissimilartoReactor.flow.Insteadofcreatingareactor,though,itscreatesanewsignalandtakesaninitialvalue.Intheexample,wecreateasignalthatstartswithanemptypathandthenproceedsoncethroughthegivendata-owbody.Argumentselfreferstothesig-nalunderconstructionandisoftypeSignalFlowOps[Path],whichextendsthedataowlanguageofreactors.Comparedtothereactor-basedversion,wehavereplacedallpathmuta-tionsanddrawingcallsbyoperationsoftheformself()=x,whichchangestheresultingpathsignalimmediately.Wecallmethodself.previousinordertoobtainthepreviousvalueofourpathsignalandmodifyitssegments.NotethattheDSLexposedbyselfdoesnotprovideamethodtoobtainthecurrentvalue,sincewecannotobtainthecurrentvaluewhileintheprocessofevaluatingit.Weareusinganim-mutablePathclassabove.MethodslineToandclosedonotmutatetheexistinginstance,butreturnanewpathinstancewhichextendsorclosesthepreviousone.5.1Animperativedata-owlanguageWehavenowtwovariantsofanimperativedata-owlan-guage,oneforreactorsandoneforsignals.Inordertokeeptheselanguagesconsistentandextractcommonfunctional-ity,wefactorourexistingabstractionsintoaclasshierarchyasfollows2.traitReactive[+P,+V]{defvalueNow:Option[V]defpulseNow:Option[P]defsubscribe(dependent:Reactive[Any,Any])...}traitSignal[+A]extendsReactive[A,A]traitEvents[+A]extendsReactive[A,Unit]ClassesSignalandEventsshareacommonbasetraitReactive.Wewillthereforecollectivelyrefertothemasreactivesinthefollowing.Wewillrefertotheirdata-owversionsasowreactives.TraitReactivedeclarestwotypeparameters:oneforthetypeofpulsesaninstanceemitsandoneforthevaluesitholds.Whilepulsesvanishaftertheywerepropagated,valuespersist.Fornow,wehavesubclassSignalwhichemitsitscurrentvalueaspulses,andthereforeitspulseandvaluetypesareidentical.SubclassEventonlyemitspulsesandneverholdsanyvalue.ItsvaluetypeishencesingletontypeUnit.Companionobjects3EventsandSignaldenemethodsflow,whichwehaveseenpreviously,andloop,whichrunsthebodyrepeatedly.Hereishowtheyaredenedforsignals:defflow[A](init:A) 2Theclasshierarchywepresenthereisslightlysimpliedcomparedtotheactualimplementationandfocussesontheconceptuallyinterestingaspects.3CodeincompanionobjectsinScalaaresimilartostaticclassmembersinJava.(op:SignalFlowOps[A]=�Unit):Signal[A]=newFlowSignal(init){defbody=op(this)}defloop[A](init:A)(op:SignalFlowOps[A]=�Unit):Signal[A]=flow(init){self=�while(!isDisposed)op(self)}WeseethattheselfargumentforowsignalsisoftypeSignalFlowOpswhichextendsabasetraitFlowOps,deningmostdataowoperationsthatavailableforreactivesandreactors.Wesummarizetheminthefollowing.defpause:UnitSuspendsthecurrentowreactiveandcontinuesitsexecu-tionthenextpropagationturn.Asmostdataowoperatorsreacttotheirinputinstantaneously,thisoperatorisusuallyusedtobreakinnitecyclesaswewillseeinlaterexamples.defhalt:UnitSuspendsanddisposesthecurrentreactive.defawait[A](input:Reactive[A,Any]):AWaitsforthenextmessagefromthegivenreactiveinput.Itimmediatelyreturnsifinputiscurrentlyemitting.defawaitNext[A](input:Reactive[A,Any]):AEquivalenttopause;await(input),i.e.,itignoresthecurrentpulsefrominputifpresent.defpar(left:=�Unit)(right:=�Unit):UnitItrstrunstheleftthentherightbranchuntiltheysuspend,nishorcalljoin.Ifbothbranchesnish,oratleastonebranchcalledjoin,thismethodimmediatelyreturns.Ifnobranchcalledjoinandatleastonebranchisnotnishedyet,thismethodsuspendsuntilnextturnwhenitwillcontinueevaluatingeachbranchwhereitstoppedpreviously.Itpro-ceedssountilbothbranchesarenishedoratleastonecallsjoin.defjoin:UnitHaltstheexecutionofthecurrentbranchand,ifpresent,joinstheinnermostenclosing`par`expression.Haltsthecurrentbranchonlyifthereisnoenclosingparexpression.defloopUntil[A](r:Reactive[A,Any])(body:=�Unit):ARepeatedlyevaluatesbodyuntilremits.Ifthebodyissus-pendedandhasn'tnishedexecuting,thecontinuationofthebodyisthrownaway.Returnsthepulseofr.defloopEndUntil[A](r:Reactive[A,Any])(body:=�Unit):ASimilartoloopUntilbutreturnsonlyafterthebodyhasnishedevaluating.defabortOn[A](input:Reactive[A,Any])(body:=�Unit)SimilartoloopUntilbutevaluatesbodyonlyonce.62012/5/4 varinner:Events[B]=Events.NeverEvents.loop[B]{self=�vales=loopUntil(outer){self(selfawaitinner)self.pause}inner=isEvents(es)}}Itrepeatedlywaitsforvaluesinthecurrentinnerstreamun-tiltheouterstreamemits.Oncethathappens,thenewinnerstreamisstoredandtheprocessstartsagain.Weusetheim-plicitargumentasawitnesstoensurethatflattencanonlybecalledforwhichemittedvaluesoftypeAareindeedoftypeEvents[B].Implicitsargumentsofthiskindareauto-maticallysuppliedbythecompiler.Theinnerstreamvari-ableisinitializedwithEvent.Neverwhichcreatesastreamthatneveremits.Themergecombinatorcanbeimplementedasfollows:defmerge[B&#x-523;:A](that:Events[B]):Events[B]=Events.flow[B]{self=&#x-523;par{while(!that.isDiposed){self(selfawaitthat)self.pause}}{while(!outer.isDiposed){self(selfawaitouter)self.pause}}}Thebranchesareswitchedbecauseeventsfromoutertakeprecedence.Eachbranchterminatesoncethecorrespondingeventstreamisdisposed.Asaresultandbecauseoftheab-senceofajoin,theparstatementreturnsassoonasboththeoutertheparameterstreamshavebeendisposed,disposingtheresultingstream.6.Routers:imperativeeventcoordinationSofar,wehavebeendealingwithabstractionsthatspecifytheirdependenciesatthepointofcreation.Whetherthroughcombinator-basedcomposition,signalexpressionsorowreactives,oncewecreateanewreactive,allitsdependen-ciesarefullyspeciedbyitsimplementation.Incontrasttoobserver-basedeventhandling,whereclientsestablishdataowindifferentplacesthroughside-effects,dataowinre-activeprogrammingismorelocalizedandvisible,asarguedinmoredetailbyCourtneyin[16].Eventhoughimplemen-tationsarenotnecessarilyfunctional,e.g.,inthecontextofowreactives,dependenciesarespeciedinafunctionalway.Thisisnotanecessity,however,forCourtney'sargu-menttoremaintrue.WewilldemonstratethisattheexampleofanotherreactiveabstractioninScala.React,therouter.Considerthetaskofroutingmouseclicksthroughacon-trolhierarchyinaGUIframework.Amouseclickarrivingfromthesystemisusuallydispatchedtothecontrolclosesttotheleafsbutstillcontainingthecoordinatesoftheclick.Afunctionalwaytomodelthisistoleteverycontrolcontainaneventstreamofmouseevents,lteringthesystemeventstreambasedonthecontrol'sbounds.However,thismakesdispatchingan(n)operation,withnbeingthenumberofcontrolsintheUI,whenitcouldbeanO(d)operation,withdbeingthemaximumdepthofthecontrolhierarchy,amor-tizedusuallyO(log(n)).Theproblemwiththegivenfunc-tionalimplementationisthateverylteredeventstreamhasonlylocalknowledge,whenthereistheglobalknowledgethattherewillbepreciselyonecontrolreceivingthemouseevent.Wecansimplifythisproblemtoademultiplexer,i.e.,routingasinglesourceeventtooneofnoutputsbasedontheeventvalue.Adomainwheredemultiplexersarecom-monarereactivetradingsystems,whereaneventstreamofmarketdataisoftenpartitionedandsenttodifferenttargets,dependingonthetypeofsecurity,forexample.Afunctionalreactivedemultiplexerimplementationwouldlookasfol-lows:valsource=EventSource[Int]valouts:Array[Events[Int]]=Array.tabulate(n){i=&#x-523;sourcefilter{x=&#x-523;x==i}}Thishastheaforementionedproblemofan(n)runningtime.UsingaScala.Reactrouter,wecanimplementitasanO(1)operation:valsource=EventSource[Int]valrouter=newRouter{valouts=Array.tabulate(n){i=&#x-523;EventSource[Int]}defreact(){valx=selfawaitsourceouts(x)=xself.pause}}ThisimplementationofarouterusesthedataowDSLtowaitforthesourcetoemitandthenredirectsthevaluetothecorrectoutput.Routersarenotonlyawaytoimplementcertaindatade-pendenciesmoreefciently,theyarealsousefulforpro-grammersthataremorefamiliarwithanimperativepro-grammingstyle.Assuch,theycanbeconsideredabridgebetweenobserver-basedprogrammingandamoredeclara-tivereactiveprogrammingstylethatestablishesdependen-ciesinafunctionalway.7.ImplementationScala.Reactproceedsindiscretesteps,called(propaga-tion)turns.Itisdrivenbytwocustomizablecorecompo-82012/5/4 7.3SignalExpressionsandOpaqueNodesAsignaloftheformSignal{a()+b()}createsagraphnodethatcapturesitsdependenciesinsideaclosure.Incon-trasttoothersystems,weneitheruseanexplicitliftingmechanismthatliftsregularfunctions,suchasthe+opera-torintheexampletothesignaldomainsuchasinFlapjaxorFran[19,33]nordoweuseamacrosystemtoperformlift-ingautomaticallyasinFrTime[13].Thesepreviousimple-mentationshaveincommonthateverylanguageconstruct,suchasfunctionapplication,conditionalexpressions,loopsandexceptions,needstobetreatedspeciallybeforetheycanbeusedinareactivesystem.Weuseanapproachinstead,thatiscompletelyagnosticofanylanguagefeature,whichisextremelyvaluableinanevolvinglanguagewhichalsosup-portsuserdenablecontrolowoperators.InScala.React,signalscreatedwithaclosureasabove,arecompletelyopaquetotheframework.Itdoesnotknowanythingaboutthesignal'sdependencystructureinadvance.Thesameistrueforowreactivesorreactors.Suchnodesareaggedasopaque.Nodesthatarenotopaquearegener-allythosecreatedusingcombinatorssuchasmaporfilter.WhenconstructingsignalSignal{a()+b()},weareinfactcallingmethoddefSignal[A](op:=�A):Signal[A]withargument{a()+b()}.TheScalacompilerrewritesexpressionsa()andb()tomethodcallsa.apply()andb.apply(),whichbecomesimportantbelow.Thearrowno-tation�=Amakesopacall-by-nameargumentthatevaluatestovaluesoftypeA.ThismeansthesumexpressiongetsconvertedtoaclosureandispassedtotheSignalmethodwithoutevaluatingit.Thisishowwecapturesignalexpres-sions.TheactualevaluationhappensintheSignal.applymethodwhichreturnsthecurrentvalueofthesignalwhileestablishingsignaldependencies.Itmaintainsastackofde-pendentreactivesthatareusedtoestablishdependencies.Asignalsiseithervalidorhasbeeninvalidatedinthecurrentorapastpropagationturn.Ifsisvalid,Signal.applytakesthetopmostreactivefromthedependentsstackwithoutre-movingit,addsittoitssetofdependentsandreturnsitsowncurrentvalidvalue.Ifsisinvalid,itadditionallypushesit-selfontothedependentstack,evaluatesthecapturedsignalexpression,andpopsitselffromthestackbeforereturningitscurrentvalue.Thisway,signalsfurtherdownstreamwilladdstotheirdependencies.Forsomelanguageexpressions,suchasconditionaloper-ations,dependenciesaredynamic.Considersignalvals=Signal{if(c())a()elseb()}Signalsshouldideallyeverdependonlyontwosignals:onsignalcandalsoonsignalaifcistrue,otherwiseoncandb.Therefore,whenanodenotiesitsdependentsofachange,itremovesalldependentsthatareaggedasopaque.Intheexample,onceanotiessofachange,itremovessfromitsdependentset.If,inthemeanwhile,chaschangedtofalse,swillbeaddedtobbutnottoaagain,sinceitdoesnotevaluatea.applyinthiscase.Notethatthisisaslightcompromisetotheidealcase.Ifcchanges,sisnotautomaticallyremovedfromaorb,butonlynexttimeaorbchange.Dependencytrackingforadynamicopaquenodecanhenceover-approximateuntilthenextchangeoccursinanodethatitlogicallydoesnotdependonanymore.Thisapproach,however,workswithanycontrolowoperation,eitherbuilt-inoruser-dened.Wethereforetradeabitofredundantcomputationforthebenetsofasinglegeneralimplementation.ThetechniquewedescribehereissomewhatrelatedtoloweringforFrTimeasdescribedbyBurchettin[9].Incon-trasttoBurchett'sapproach,weuseitasourprincipalcom-positionmechanismatruntimeandnotasanoptimizationpassatcompiletimeafteralldependenciesareknownfromamacro-basedlifting.Moreover,wekeeptrackofdynamicdependencies,whereasin[9],aloweredsignaldependsontheunionofitspotentialstaticallyknowndependencies,i.e.,theconditionalsignalfromabovewoulddependona,bandcatanytime.Mostimportantly,ourimplementationisgen-eral,whereasloweringneedstobeadaptedforallkindsoflanguageexpressions.Forexample,incontrasttolower-ing,ourapproachhandlesruntimedependenciesandhigher-orderprogrammingwithoutfurtheradaptation.Considerthefollowingfunction,whichcreatesthereactivesumofarun-timelistofintegersignals:defsum(xs:List[Signal[Int]])=Signal{xs.foldLeft(0){(sig,sum)=�sig()+sum}}Thiscannotbeloweredwiththeapproachfrom[9]becausetheloweringoperatorneedstoknowalloftheresultingde-pendencies.,whichisnotpossibleintheexample.Thesameistrueforvirtualmethodsforwhichtheoptimizercannotpredictthesignaltheyreturn.Alsoconsiderthefollowingexample,dealingwithhigher-ordersignals:classRPoint{valx,y:Signal[Int]}valp1,p2:Signal[RPoint]=...valx=Signal{if(p1()!=null)p1().x()elsep2().x()}Thischoosesacoordinatesignalfromoneoftwopoints,basedonastandardnullpointercheck.Ifwewouldneedtoevaluatethebranchesintheexampleeagerlyinordertodetermineallofx'spotentialdependencies,wewouldneedtobecarefultoavoidanullpointerexception.Wenditthereforeimportanttopreservetheevaluationorderofdifferentlanguageconstructs,suchasconditionalevaluationinifexpressionsorshortcircuitsemanticsinbooleanoperations.Analconsiderationisthatwithourapproachthecreationofreactivenodesistransparenttotheprogrammer,whereaswhenperformedasanoptimization,thenumberofnodescreatedislesspredictable.102012/5/4 defevalBranches(left:=�Unit)(right:=�Unit)...evalBranches{reset{left;latch-=1}}{reset{right;latch-=1}}}Wecapturethecontinuationaftertheparstatement,calledexitK.Weintroduceafreshlatchvariablethatindicateshowmanybrancheshavenished.Wesetthecontinuationvariableusedbyjointoaclosurethatsetslatchtozero,indicatingthatbothbranchesareforcedtoterminate.Wethenwrapbothbranchesinseparateresetcallstodelimitthecontinuationscopeinthebranches.Wealsocountdownthelatchvariableattheendofeachbranchtoindicatethattheyhavenished.EvaluationofthebranchesishandledbylocalfunctionevalBranches,whichisdenedasfollows:defevalBranches(left:=�Unit)(right:=�Unit){valoldJoin=_join_join=doJoinvalleftK=continueWith(left)if(latch�0){valrightK=continueWith(right)_join=oldJoinif(latch�0){_continue=()=�evalBranches{leftK()}{rightK()}}elseexitK()}elseexitK()}Inordertobeabletodealwithnestedparstatements,werstreplacetheoldjoinclosurewiththeonethatcapturesthecorrectlatchvariable.Thenweevaluatetheleftbranchandiflatchindicatesthatweshouldcontinue,weevaluatethesecondbranch.Foreachbranch,wesavetheremainingcontinuationsinleftKandrightK.Itisimportantthatwrapeachbranchinaresetcallabovesotheyaredelimitedcor-rectlyanddon'tcaptureanythingbeyondtheparstatement.Thenwereinstalltheoldjoinclosureforpotentialjoincallsinasurroundingparstatementtoworkcorrectly.Ifthecur-rentparstatementhasn'tterminatedyet,westoreacontinu-ationthatevaluatestherestofthebranches.Ifweencounterthattheparstatementshouldterminate,wecallexitK,thecontinuationstartingaftertheparstatement.Otherhigh-leveldata-owexpressionscanbewrittenintermsoftheaboveoperators.LoopoperatorloopEndUntilthatloopsuntilagivenreactiveemits,butalwaysnishestheloopbodyrst,canbeimplementedasfollows:defloopEndUntil[A](r:Reactive[A,Any])(body:=�Unit):A={vardone=falsepar{await(r);done=true}{while(!done)body}r.getPulse}Onebranchwaitsfortheinputtoemitandthensetsvari-abledonewhichisusedastheloopconditioninthesecondbranch.MethodabortOnisavariationofthis,butinsteadofmain-tainingaconditionvariable,wecanusethejoinoperatortoabortthesecondbranchimmediately.defabortOn[A](input:Reactive[A,Any])(body:=�Unit):Unit=par{await(input);join}{body;join}NotethattheorderofbranchesforbothloopEndUntilandabortOndetermineasubtlesemanticdetail.Thegivenor-dermakessurethattheabortionconditionholdsinthesameturninwhichtheinputemitted.Ifthebrancheswereex-changed,loopEndUntilmightstillstartthebodyoncemoreandabortOnmightstillrunasliceoftheloopbodyinthesameturninwhichtheinputemitted.Now,wecanimplementloopUntileitherusingpardi-rectly,oruseabortOntoaborttheloopimmediately:defloopUntil[A](r:Reactive[A,Any])(body:=�Unit):A={abortOn(r){while(true)body}r.getPulse}Whenvalidatedduringapropagationturn,adata-owre-activesimplyrunsitscurrentcontinuationsavedinvariablecontinue,whichinitiallystartsexecutingthewholebodyofthereactive.7.5RoutersArouterendsupasadependencynodeinthegraph,onelevelhigherthanthemaximumofitsdependencies.Theyaremanagedthesamewayasotherreactives.AsourcereactivesuchasanEventSourceoraVarthatiscreatedinsidearouterisnotonlevel0asusual,butonalevelabovetherouter.Sourcereactiveconstructorsknowwheretheyarecreatedbyusinganimplicitargument.MethodVar,forinstance,actuallyacceptsanadditionalimplicitargumentownerthatisautomaticallypassedinbythecompilerwhenoneisinscope.Thedefaultargumentspeciesthedomainobjectastheowner.Insidearouter,however,therouteroverwritestheimplicitownerwithitself,whichcreatesthecorrectdependencystructure.7.6LevelMismatchesOpaquenodes,suchasexpressionsignalsorowreactives,forwhichtheframeworkdoesnotknowthedependencystructure,canaccessarbitrarydependenciesduringtheirevaluationwhichcanchangefromturntoturn.Wethere-foreneedtoprepareforanopaquenodentoaccessanothernodethatisonahighertopologicallevel.Everynodethatisreadfromduringn'sevaluation,rstcheckswhetherthecurrentpropagationlevelwhichismaintainedbytheprop-agatorisgreaterthanthenode'slevel.Ifitis,itproceed122012/5/4 wayworkslikeanexpressionsignalbutlikeallobserversareleafnodesthatneverabort,soitsafetocalldrawingcodewhenevaluating.8.3CalculatorAnFRPimplementationofasimplecalculatorisoneofthestandarddemosthatcanbefoundontheFlapjaxwebsite4.TheeventhandlinglogicoftheFlapjaxexampleisnon-trivial,using16reactivecombinators,andcreatesasmanyreactivenodes,someofwhicharehigher-order.Thecorre-spondingeventhandlingcodeforacalculatorinidiomaticScala.Reactisasfollows:valdigits:Events[Int]=...valops:Events[Int]valoperators:Array[Double=�Double=�Double]=...valdisplay:Signal[Double]={varf={x:Double=�x}Signal.loop(0.0){self=�valop=self.loopUntil(ops){self()=10*self.previos+(selfawaitdigits)}f=operators(op)(self.previos)self()=f(now)self.loopUntil(digits){f=operators(selfawaitNextops)(self.previos)}}}Entereddigitsarriveatstreamdigits.Binaryoperatorsarestoredascurriedfunctionsinarrayops,withoperatorinputsarrivingatopsindexingintothearray.Thedisplaysignalholdsthecontentsofthedisplay.Itstartsbyreceivingdigitsupdatingthedisplayuntilanoperatorisentered.Thenitstoresthatoperatorinaninternalfunctionandproceedsreceivingoperatorinputsuntilthenextdigitisreceived.ThiscodeisequallydensetotheFlapjaximplementationandlessthanhalfofitssize.Itsimperativenaturedirectlyreectsthestatemachinecharacterofthisexampleandcreatesonlyasinglereactivenodeatruntime.9.EvaluationandDiscussionWewillnowshowfurtherexamplesandbenchmarkresults.Asitisnotverymeaningfultocompareabsoluteperfor-manceacrosslanguagesandplatforms,weshowhowourexamplesperformrelativetoabaselineimplementationintermsofobserversonthesameplatform.Thisgivesusanindication–andbynomeansevidence–howviableintermsofperformanceareactiveimplementationiscomparedtoanobserver-basedone.AllmeasurementsweredoneonaMac-bookProLate2011,i72.4Ghz,8GBRAMonMacOSX10.7withScala2.9.1(withoptimizationsenabled)onOr-acle'sJava1.6update31.FlapjaxexampleswereruninChrome15.0withthelatestFlapjaxversionasofApril7th, 4http://www.flapjax-lang.org/try/index.html?edit=calc.html2012from[39],optimizedwithGoogle'sclosurecompiler.Allnumbersaresteadystateperformanceafterapropernumberofwarmupiterations.Wefollowthegeneralguide-lineandmeasureacrossmultipleinvocationsoftheVM[27].9.1ReactiveChainsandFansThissimplebenchmarkmeasuresthetimeittakestoprop-agateasingleeventalongalinearchainandafanofreac-tivescomparedtoaverysimpleobserverimplementation.ThereactivedependencygraphsaredepictedinFigure3.Thistestgivesanindicationoftheoverheadofthediffer-entliftingmechanismsandhowmuchtimetheframeworkspendstoensuredataconsistency.WeimplementthesamefunctionalityforEScala[26],Scala.ReactandFlapjax[33].Fortheobserverimplementation,wehaveimplementedabasicObservableclassthatstoresregisteredobserversinanarrayandnotiesthemwhenchanged.Forthelinearchain,oneobservablealwaysnotiesasingleotherobservable.Forthefan,oneobservablenotiesnotherobservables,whichthennotifyoneotherobservableeachthataccumulatestheresult.ForEScala,whichsupportsrst-classeventsbutnosignals,wederiveeventsfromasourceusingthemapcombi-nator.Werun4variantsforScala.React,composingeventswithmap,whichreturnsalazyreactive,withcollect,whichreturnsastrictreactive,andnallycomposingsignalsus-ingtheLazyandStrictconstructorsfromSection7.3.Werun2variantsforFlapjax,oneusingeventscomposedwithmapandoneusingbehaviors(Flapjax'stime-varyingvalueabstraction)usingFlapjax'sbuilt-inliftingmechanism. Figure3:Dependencygraphsforreactivechainsandfans.9.1.1ResultsResultscanbefoundinFigures4and5.WearemostlyinterestedinrelativeperformanceasshowninFigure5butincludeabsolutenumbersforreference.Naturally,theobserver-basedimplementationbeatseveryotherimplemen-tationonthesameplatformbyquitesomemargin.EventhoughwedealwithonemorelevelofindirectioninScala.ReactcomparedtoFlapjaxorEScala,byusingweakforwardreferences,ourimplementationscomparedtothecorrespondingimplementationsinFlapjaxandEScalaper-formwell.InEScala,thetasktoensuredataconsistencyisfundamentallyeasier,sinceitonlysupportseventsandnohigher-ordercombinators,nodynamicgraphsandalldepen-152012/5/4 }valmoves=mouseDownmap{md=�pos0=md.posinner}...Ifwewanttostaypurelyfunctional,wewouldhavetouseadifferentsetofcombinators,potentiallywritingourown.Weconcludethatdealingwitheventsequencesinafunctionalreactivewaycanbecomecomplicated.Inparticular,dealingwithhigherordereventstreamsefcientlyisanimportantissuethatprogrammersneedtobeawareof.Ourdata-owformulationofthesameproblem,whichisverysimilartoourrunningexampleandthereforewon'tre-peathere,avoidsthisproblementirelywithoutusinghigherordereventstreams.Dependentsandinternalcallbacksaredeactivatedassoonaspossible.Performanceissuesaside,wealsoarguethatthesourcecodeiseasiertounderstand,atleastforprogrammersnotusedtoafunctionalstyle.Onecandiscusshowvaluableourmeasurementswepresentbelowareforadraggingexamplewheretheeventloadisinherentlylimited.Note,however,thatthisprob-lemisjustoneinstanceofcorrelatingasequenceofevents,whichiscommoninmanyotherdomainswithhighereventloadssuchasRFIDtracking,frauddetection,patientmoni-toringorindustrialcontrolsystems.WemainlyfocusonthedraggingexamplebecausethereisanFRPimplementationavailablethatwaswrittenbyathirdparty.9.2.1ResultsResultscanbefoundinFigure6.Theygivetherelativerun-ningtimesinrelationtoacorrespondingobserver-basedim-plementationonthesameplatform.Oneiterationsimulatesamousedown,followedby10mousemoves,followedby1mouseupevent,followedbynmousemoveevents,withnvaryingalongthehorizontalaxis.Thismeansweincreasethenumberofeventsthatshouldnotbeconsideredforadragoperation.TheoriginalFRPimplementationinScala.React,repeat-edlycreatingnewdanglingdependentsimprovesovertimeinrelationtotheobserverimplementation.Asthegarbagecollectorkeepsthenumberofthoseunnecessarydependentsnearlyconstant,theabsoluterunningtimestaysatanearlyconstantlow,relativelyindependenttotheeventload.ThetwofastestimplementationsaretheimprovedFRPandowimplementationsinScala.Reactapproachingfactor0.7forhigheventloads.Forloweventloads,theowim-plementationisslightlyslowerbecauseitcreatesmoreclo-suresinternallyandrepeatedlyun-andresubscribesdepen-dents.Thisoverheadbecomeslessapparentforhigheventloads,alsobecausetheimprovedFRPimplementationstillmaintainsoneunnecessarydependentbetweenmouseupanddownevents.ForFlapjax,weonlygiveresultsforanimprovedim-plementation,sincetheoriginalversioncreatestoomanydanglingreferencesthatareneverdisposedduetothelackofweakreferencesinJavascript.TheimprovedFlapjaximplementationhasamuchhigheroverheadcomparedtothecorrespondingobserverimplementationthanthetwoScala.Reactimplementations.WedonotprovideresultsforEScalabecauseitlackssup-portforhigher-ordereventstreams,imperativedataoworsimilarfacilitiesthatwouldallowustoimplementrecogniz-ingeventsequencesconveniently. Figure6:Draggingperformanceofdifferentimplementa-tionsrelativetoanobserver-basedimplementationonthesameplatform.9.3DemultiplexerFigure7showsthattherouterimplementationofademulti-plexerhasconstantspeedwithrespecttothenumberofout-puts.TheFRPimplementationsinScala.ReactandEScalaaregenerallyslowerevenforsmallernumberofoutputs.TheEScalaimplementationrunsfasterthanScala.Reactusingfilter,sincethelteringoperationinEScalaislazywhereasinScala.React,itisstrict.WehavediscussedthebenetsofastrictlterimplementationinSection7.2. Figure7:Demultiplexingasingleeventtoanumberofoutputs.172012/5/4 formulationincontinuationpassingstyle[22,23].TheAFPdependencygraphandpropagationalgorithmsaremuchmoreheavyweightthanScala.React'sbeingbasedontimestampsandaselectivereplaymechanism.Ourimperativedata-owreactivessharecertainchar-acteristicswithcomplexeventprocessing(CEP)systemssuchasTelegraphCQ[11],SASE[46],Cayuga[18].ThesesystemsusecustomquerylanguagessimilartoSQL[17]torecognizeeventpatternsfrommultiplesources.Queriescanoftenbestateful,similartoimperativedata-owre-actives,butarenotdesignedforexternalside-effectsbuttocomposecomplexeventsoutofsimplerones.CEPsys-temsareusuallyoptimizedforlarge-scalestreamprocessingwhileourimplementationistargetedtowardsgeneralpur-poseeventsystems.EventJava[21]isaCEPsystemthatex-tendsJavawithaneventnotionanddeclarativeexpressionsforeventcorrelation.EventJava'seventsarespecialmeth-odsthatareeithercalleddirectlyorbasedontheirenclosingtype,i.e.,theprogrammingmodelisfundamentallydifferentfromScala.Reactandembracesacertaindegreeofinversionofcontrol.Itfurtherdiffersfromourworkinthatitrequiresitsowncompilerandisstream-orientedandasynchronous.TherearemanymoresimilarCEPorpublish/subscribesys-temsthatwecannotmentionduetospacereasons.Theyareusuallyimplementedasalanguageextensionandfavoracertainprogrammingparadigmandreactiveabstraction,whileScala.Reactprovidesawiderrangeofabstractionsthatsupportreactiveprogramminginmultipleparadigms.Ourimperativedata-owreactives(andreactors)sharecertainsimilaritieswithactors[3,30].Actorsrunconcur-rentlyandcommunicatewitheachotherthroughmessages.Incontrasttoourreactorsandreactives,actorsareasyn-chronous.Statetransitionsanddataavailabilityaresynchro-nizedamongreactives,whereasactorsbehaveasindepen-dentunitsofcontrol,i.e.,thereisnonotionofsimultane-ityandorderofmessagearrivalacrossactorsisunspecied(apartfromanotionoffairness).Actorscommunicatewitheachotherdirectly,whereasreactivesbroadcasttoadynamicsetofdependents.11.ConclusionWehavedemonstratedanewmethodbackedbyasetoflibraryabstractionsthatallowstransitioningfromclassicaleventhandlingwithobserverstoreactiveprogrammingab-stractions.Thekeyideaistointegratebasiceventhandlingwithobservers,functionreactiveprogrammingandanem-beddedhigher-orderdataowlanguageintoasingleframe-work.Programmerscanchoosebetweenabstractionsthatsuittheirneed.Whenamoredeclarativesolutionisnotobvi-ousorlessefcient,theycanalwaysreverttolower-levelob-serversorimperativeabstractionssuchasrouters.Differentaspectsofoursystemaddressdifferentsoftwareengineeringprinciplesweidentiedintheintroduction:Uniformity/AbstractionFirst-classpolymorphiceventsandsignals,generalizedtoreactives,offerlightweight,reusableanduniforminterfaces.Low-levelobservers,reactorsandowreactivesworkthesameway,regardlessofthepre-ciserepresentationoftheirdependencies.Side-effects/EncapsulationReactorsandowreactivesen-capsulatecomplexeventlogicsuchasinthedraggingex-amplewithoutexposingexternalstate.ResourcemanagementObserverlife-timesareautomati-callyrestrictedbytheObservingtrait.Ourdata-owlan-guageensuresthatinternalobserversaredisposedwhennolongerneeded.ComposabilityReactivescanbecomposedwithsignalex-pressions,functionalcombinatorsorimperativedata-ow.Thatwaywecanobtainahandletoanentityrepre-sentingasinglefeatureinsteadofmultiplelooselycou-pledobjects.SeparationofconcernsUniformreactivesmakeitstraight-forwardtocreatesignalsandeventsofexistingim-mutabledata-structuresandfactortheinteractionwithexternalAPIsintoobserversorreactors.ConsistencyScala.React'ssynchronouspropagationmodelensuresthatnoreactivecaneverseeinconsistentreac-tivedata,regardlessofthenumberorshapeofreactivedependencies.SemanticdistanceThesemanticdistanceisvastlyreducedbyavoidinginversionofcontrolevenforcomplexeventlogic.Scala.Reactandcodeexamplesfromabovecanbedown-loadedfromhttp://lamp.epfl.ch/~imaier.References[1]UmutA.Acar,GuyE.Blelloch,andRobertHarper.Adaptivefunctionalprogramming.ACMTrans.Program.Lang.Syst.,28(6):990–1034,2006.[2]AdobeSystems.Flexquickstart:Handlingdata.http://www.adobe.com/devnet/flex/quickstart/using_data_binding/,2010.[3]GulAgha.Actors:amodelofconcurrentcomputationindistributedsystems.MITPress,Cambridge,MA,USA,1986.[4]AlbertBenveniste,PaulLeGuernic,andChristianJacque-mot.Synchronousprogrammingwitheventsandrelations:theSIGNALlanguageanditssemantics.Sci.Comput.Pro-gram.,16(2):103–149,1991.[5]G.Berry.Theconstructivesemanticsofpureesterel,1999.[6]GérardBerryandGeorgesGonthier.TheESTERELsyn-chronousprogramminglanguage:design,semantics,imple-mentation.Sci.Comput.Program.,19(2),1992.[7]AlanBorning,RobertDuisberg,BjornFreeman-Benson,AxelKramer,andMichaelWoolf.Constrainthierarchies.InOOP-SLA,pages48–60,1987.192012/5/4 [8]BryanCattle.Ifonlywe'dusedantsprolerear-lier...http://www.codeproject.com/KB/showcase/IfOnlyWedUsedANTSProfiler.aspx,2007.[9]KimberleyBurchett,GregoryH.Cooper,andShriramKrish-namurthi.Lowering:astaticoptimizationtechniquefortrans-parentfunctionalreactivity.InPEPM,pages71–80,2007.[10]MagnusCarlsson.Monadsforincrementalcomputing.InICFP,2002.[11]SirishChandrasekaran,OwenCooper,AmolDeshpande,MichaelJ.Franklin,JosephM.Hellerstein,WeiHong,SaileshKrishnamurthy,SamuelR.Madden,FredReiss,andMehulA.Shah.TelegraphCQ:continuousdataowprocessing.InSIG-MOD,pages668–668,2003.[12]Jean-LouisColaço,AlainGirault,GrégoireHamon,andMarcPouzet.Towardsahigher-ordersynchronousdata-owlan-guage.InEMSOFT,pages230–239,2004.[13]GregoryH.Cooper.IntegratingDataowEvaluationintoaPracticalHigher-OrderCall-by-ValueLanguage.PhDthesis,BrownUniversity,2008.[14]GregoryH.CooperandShriramKrishnamurthi.Embeddingdynamicdataowinacall-by-valuelanguage.InESOP,pages294–308,2006.[15]AntonyCourtney.Frappé:FunctionalreactiveprogramminginJava.InPADL,2001.[16]AntonyCourtney.Functionallymodeleduserinterfaces.InInteractiveSystems.Design,Specication,andVerication.2003.[17]ChristopherJ.Date.AguidetotheSQLstandard:auser'sguidetothestandardrelationallanguageSQL.Addison-Wesley,Reading,Mass.[u.a.],1987.[18]AlanJ.Demers,JohannesGehrke,MingshengHong,MirekRiedewald,andWalkerM.White.Towardsexpressivepub-lish/subscribesystems.InEDBT,pages627–644,2006.[19]ConalElliott.Push-pullfunctionalreactiveprogramming.InHaskell,2009.[20]ConalElliottandPaulHudak.Functionalreactiveanimation.InICFP,1997.[21]PatrickEugsterandK.R.Jayaram.Eventjava:Anextensionofjavaforeventcorrelation.InECOOP,2009.[22]AndrzejFilinski.Representingmonads.InPOPL,1994.[23]AndrzejFilinski.Representinglayeredmonads.InPOPL,1999.[24]BjornN.Freeman-Benson.Kaleidoscope:mixingobjects,constraints,andimperativeprogramming.InOOPSLA/E-COOP,pages77–88,1990.[25]ErichGamma,RichardHelm,RalphJohnson,andJohnVlis-sides.Designpatterns:elementsofreusableobject-orientedsoftware.Addison-Wesley,1995.[26]VaidasGasiunas,LucasSabatina,MiraMenzini,AngelNúnez,andJacquesNoyé.Escala:Modularevent-drivenobjectinteractionsinscala.InAOSD,2011.[27]AndyGeorges,DriesBuytaert,andLievenEeckhout.Sta-tisticallyrigorousjavaperformanceevaluation.InOOPSLA,OOPSLA'07,2007.[28]N.Halbwachs,P.Caspi,P.Raymond,andD.Pilaud.ThesynchronousdataowprogramminglanguageLUSTRE.InProceedingsoftheIEEE,pages1305–1320,1991.[29]NicolasHalbwachs,AlbertBenveniste,PaulCaspi,andPaulLeGuernic.Data-owsynchronouslanguages,1993.[30]PhilippHallerandMartinOdersky.ActorsthatUnifyThreadsandEvents.Technicalreport,EcolePolytechniqueFederaledeLausanne,2007.[31]GlennE.KrasnerandStephenT.Pope.Acookbookforusingthemodel-viewcontrolleruserinterfaceparadigminsmalltalk-80.J.ObjectOrientedProgram.,1(3):26–49,1988.[32]SeanMcDirmidandWilsonC.Hsieh.Superglue:Componentprogrammingwithobject-orientedsignals.InECOOP,pages206–229.Springer,2006.[33]LeoA.Meyerovich,ArjunGuha,JacobBaskin,GregoryH.Cooper,MichaelGreenberg,AleksBromeld,andShriramKrishnamurthi.Flapjax:aprogramminglanguageforajaxapplications.OOPSLA,pages1–20,2009.[34]MicrosoftCorporation.ReactiveExtensionsfor.NET(Rx).http://msdn.microsoft.com/en-us/devlabs/ee794896.aspx/,2010.[35]MartinOderskyandal.Anoverviewofthescalaprogram-minglanguage.TechnicalReportIC/2004/64,EPFLLau-sanne,Switzerland,2004.[36]OracleCorporation.JavaFX.http://javafx.com/,2010.[37]SeanParent.Apossiblefutureofsoftwaredevel-opment.http://stlab.adobe.com/wiki/index.php/Image:2008\_07\_25\_google.pdf,2008.[38]TomasPetricekandDonSyme.Collectinghollywood'sgarbage:avoidingspace-leaksincompositeevents.InISMM,2010.[39]BrownPLT.Flapjaxgithubrepository.http://github.com/brownplt/flapjax.[40]HrideshRajanandGaryT.Leavens.Ptolemy:Alanguagewithquantied,typedevents.InECOOP,2008.[41]TiarkRompf,IngoMaier,andMartinOdersky.Implement-ingrst-classpolymorphicdelimitedcontinuationsbyatype-directedselectiveCPS-transform.InICFP,pages317–328,2009.[42]FriedrichSteimann,ThomasPawlitzki,SvenApel,andChris-tianKästner.Typesandmodularityforimplicitinvocationwithimplicitannouncement.TOSEM,2010.[43]TheEclipseFoundation.JFaceDataBinding.http://wiki.eclipse.org/index.php/JFace_Data_Binding,2010.[44]MadsTorgersen.QueryinginC#:howlanguageintegratedquery(LINQ)works.InOOPSLA'07:Companiontothe22ndACMSIGPLANconferenceonObject-orientedpro-grammingsystemsandapplicationscompanion,2007.[45]ZhanyongWanandPaulHudak.Functionalreactivepro-grammingfromrstprinciples.InInACMSIGPLANConfer-enceonProgrammingLanguageDesignandImplementation,pages242–252,2000.[46]EugeneWu,YanleiDiao,andShariqRizvi.High-performancecomplexeventprocessingoverstreams.InSIG-MOD,pages407–418,2006.202012/5/4