Download as pdf or txt
Download as pdf or txt
You are on page 1of 21

HEALTHCARE

GUIDE

BLOG

Glossary of Modern JavaScript Concepts: Part 1


Learnthefundamentalsoffunctionalprogramming,reactive

programming,andfunctionalreactiveprogramminginJavaScript.

Kim Maida

February 14, 2017

620 152 113

TL;DR:IntherstpartoftheGlossaryofModernJSConceptsseries,we'llgainanunderstandingoffunctionalprogramming,reactive
programming,andfunctionalreactiveprogramming.Todoso,we'lllearnaboutpurity,statefulnessandstatelessness,immutabilityand
mutability,imperativeanddeclarativeprogramming,higher-orderfunctions,observables,andtheFP,RP,andFRPparadigms.

Introduction

ModernJavaScripthasexperiencedmassiveproliferationoverrecentyearsandshowsnosignsofslowing.Numerousconceptsappearing
inJSblogsanddocumentationarestillunfamiliartomanyfront-enddevelopers.Inthispostseries,we'lllearnintermediateand

advancedconceptsinthecurrentfront-endprogramminglandscapeandexplorehowtheyapplytomodernJavaScript.

Concepts

Inthisarticle,we'lladdressconceptsthatarecrucialtounderstandingfunctionalprogramming,reactiveprogramming,andfunctional

reactiveprogrammingandtheirusewithJavaScript.

Youcanjumpstraightintoeachconcepthere,orcontinuereadingtolearnabouttheminorder.

Purity:PureFunctions,ImpureFunctions,SideEects

State:StatefulandStateless
ImmutabilityandMutability
ImperativeandDeclarativeProgramming
Higher-orderFunctions

FunctionalProgramming
Observables:HotandCold

ReactiveProgramming
FunctionalReactiveProgramming

Purity: Pure Functions, Impure Functions, Side E ects

Pure Functions

Apurefunction'sreturnvalueisdeterminedonlybyitsinputvalues(arguments)withnosideeects.Whengiventhesameargument,
theresultwillalwaysbethesame.Hereisanexample:

functionhalf(x){
returnx/2;

e half(x) functiontakesanumber x andreturnsavalueofhalfof x .Ifwepassanargumentof 8 tothisfunction,thefunction

willalwaysreturn 4 .Wheninvoked,apurefunctioncanbereplacedbyitsresult.Forexample,wecouldreplace half(8) with 4

whereverusedinourcodewithnochangetothenaloutcome.isiscalledreferentialtransparency.

Purefunctionsonlydependonwhat'spassedtothem.Forexample,apurefunctioncannotreferencevariablesfromaparentscopeunless
theyareexplicitlypassedintothefunctionasarguments.Eventhen,thefunctioncannotmodifytheparentscope.

varsomeNum=8;

//thisisNOTapurefunction
functionimpureHalf(){

returnsomeNum/2;

Insummary:

Purefunctionsmusttakearguments.
esameinput(arguments)willalwaysproducethesameoutput(return).
Purefunctionsrelyonlyonlocalstateanddonotmutateexternalstate(note: console.log changesglobalstate).

Purefunctionsdonotproducesideeects.

Purefunctionscannotcallimpurefunctions.

Impure Functions

Animpurefunctionmutatesstateoutsideitsscope.Anyfunctionthathassideeects(seebelow)isimpure.Proceduralfunctionswithno
utilizedreturnvaluearealsoimpure.

Considerthefollowingexamples:

//impurefunctionproducingasideeffect

functionshowAlert(){
alert('Thisisasideeffect!');

//impurefunctionmutatingexternalstate

varglobalVal=1;
functionincrementGlobalVal(x){

globalVal+=x;

//impurefunctioncallingpurefunctionsprocedurally

functionproceduralFn(){

constresult1=pureFnFirst(1);

constresult2=pureFnLast(2);

console.log(`Donewith${result1}and${result2}!`);
}

//impurefunctionthatresemblesapurefunction,

//butreturnsdifferentresultsgiventhesameinputs

functiongetRandomRange(min,max){
returnMath.random()*(maxmin)+min;

Side E ects in JavaScript

Whenafunctionorexpressionmodiesstateoutsideitsowncontext,theresultisasideeect.Examplesofsideeectsincludemakinga
calltoanAPI,manipulatingtheDOM,raisinganalertdialog,writingtoadatabase,etc.Ifafunctionproducessideeects,itis

consideredimpure.Functionsthatcausesideeectsarelesspredictableandhardertotestsincetheyresultinchangesoutsidetheirlocal
scope.

Purity Takeaways
Plentyofqualitycodeconsistsofimpurefunctionsthatprocedurallyinvokepurefunctions.isstillproducesadvantagesfortestingand
immutability.Referentialtransparencyalsoenablesmemoization:cachingandstoringfunctioncallresultsandreusingthecachedresults

whenthesameinputsareusedagain.Itcanbeachallengetodeterminewhenfunctionsaretrulypure.

Tolearnmoreaboutpurity,checkoutthefollowingresources:

Pureversusimpurefunctions
MastertheJavaScriptInterview:WhatisaPureFunction?
FunctionalProgramming:PureFunctions

State

Statereferstotheinformationaprogramhasaccesstoandcanoperateonatapointintime.isincludesdatastoredinmemoryaswell
asOSmemory,input/outputports,database,etc.Forexample,thecontentsofvariablesinanapplicationatanygiveninstantare
representativeoftheapplication'sstate.

Stateful

Statefulprograms,apps,orcomponentsstoredatainmemoryaboutthecurrentstate.eycanmodifythestateaswellasaccessits
history.efollowingexampleisstateful:

//stateful

varnumber=1;

functionincrement(){
returnnumber++;

increment();//globalvariablemodified:number=2

Stateless

Statelessfunctionsorcomponentsperformtasksasthoughrunningthemforthersttime,everytime.ismeanstheydonotreference

orutilizeanyinformationfromearlierintheirexecution.Statelessnessenablesreferentialtransparency.Functionsdependonlyontheir
argumentsanddonotaccessorneedknowledgeofanythingoutsidetheirscope.Purefunctionsarestateless.Seethefollowingexample:

//stateless

varnumber=1;

functionincrement(n){
returnn+1;
}

increment(number);//globalvariableNOTmodified:returns2

Statelessapplicationsdostillmanagestate.However,theyreturntheircurrentstatewithoutmutatingpreviousstate.isisatenetof
functionalprogramming.

State Takeaways

Statemanagementisimportantforanycomplexapplication.Statefulfunctionsorcomponentsmodifystateandstorehistory,butare

morediculttotestanddebug.Statelessfunctionsrelyonlyontheirinputstoproduceoutputs.Astatelessprogramreturnsnewstate
ratherthanmodifyingexistingstate.

Tolearnmoreaboutstate,checkoutthefollowingresources:

State
Advantagesofstatelessprogramming

Statefulandstatelesscomponents,themissingmanual
Redux:predictablestatecontainerforJavaScriptapps

Immutability and Mutability

econceptsofimmutabilityandmutabilityareslightlymorenebulousinJavaScriptthaninsomeotherprogramminglanguages.

However,youwillhearalotaboutimmutabilitywhenreadingaboutfunctionalprogramminginJS.It'simportanttoknowwhatthese
termsmeanclassicallyandalsohowtheyarereferencedandimplementedinJavaScript.edenitionsaresimpleenough:

Immutable

Ifanobjectisimmutable,itsvaluecannotbemodiedaercreation.

Mutable

Ifanobjectismutable,itsvaluecanbemodiedaercreation.

By Design: Immutability and Mutability in JavaScript

InJavaScript,stringsandnumberliteralsareimmutablebydesign.isiseasilyunderstandableifweconsiderhowweoperateonthem:

varstr='Hello!';

varanotherStr=str.substring(2);
//result:str='Hello!'(unchanged)

//result:anotherStr='llo!'(newstring)

Usingthe .substring() methodonour Hello! stringdoesnotmodifytheoriginalstring.Instead,itcreatesanewstring.Wecould

reassignthe str variablevaluetosomethingelse,butoncewe'vecreatedour Hello! string,itwillalwaysbe Hello! .

Numberliteralsareimmutableaswell.efollowingwillalwayshavethesameresult:

varthree=1+2;

//result:three=3

Undernocircumstancescould 1+2 evaluatetoanythingotherthan 3 .

isdemonstratesthatimmutabilitybydesigndoesexistinJavaScript.However,JSdevelopersareawarethatthelanguageallowsmost
thingstobechanged.Forexample,objectsandarraysaremutablebydesign.Considerthefollowing:

vararr=[1,2,3];

arr.push(4);

//result:arr=[1,2,3,4]

varobj={greeting:'Hello'};

obj.name='Jon';

//result:obj={greeting:'Hello',name:'Jon'}

Intheseexamples,theoriginalobjectsaremutated.Newobjectsarenotreturned.

Tolearnmoreaboutmutabilityinotherlanguages,checkoutMutablevsImmutableObjects.

In Practice: Immutability in JavaScript

FunctionalprogramminginJavaScripthasgainedalotofmomentum.Butbydesign,JSisaverymutable,multi-paradigmlanguage.

Functionalprogrammingemphasizesimmutability.Otherfunctionallanguageswillraiseerrorswhenadevelopertriestomutatean
immutableobject.SohowcanwereconciletheinnatemutabilityofJSwhenwritingfunctionalorfunctionalreactiveJS?

WhenwetalkaboutfunctionalprogramminginJS,theword"immutable"isusedalot,butit'stheresponsibilityofthedevelopertowrite

theircodewithimmutabilityinmind.Forexample,Reduxreliesonasingle,immutablestatetree.However,JavaScriptitselfiscapableof

mutatingthestateobject.Toimplementanimmutablestatetree,weneedtoreturnanewstateobjecteachtimethestatechanges.
JavaScriptobjectscanalsobefrozenwith Object.freeze(obj) tomakethemimmutable.Notethatthisisshallow,meaningobjectvalues

withinafrozenobjectcanstillbemutated.Tofurtherensureimmutability,functionslikeMozilla'sdeepFreeze()andnpmdeep-freeze

canrecursivelyfreezeobjects.FreezingismostpracticalwhenusedintestsratherthaninapplicationJS.Testswillalertdeveloperswhen
mutationsoccursotheycanbecorrectedoravoidedintheactualbuildwithout Object.freeze clutteringupthecorecode.

erearealsolibrariesavailabletosupportimmutabilityinJS.MorideliverspersistentdatastructuresbasedonClojure.Immutable.jsby

FacebookalsoprovidesimmutablecollectionsforJS.UtilitylibrarieslikeUnderscore.jsandlodashprovidemethodsandmodulesto

promoteamoreimmutablefunctionalprogrammingstyle.

Immutability and Mutability Takeaways

Overall,JavaScriptisaverymutablelanguage.SomestylesofJScodingrelyonthisinnatemutability.However,whenwritingfunctional

JS,implementingimmutabilityrequiresmindfulness.JSwillnotnativelythrowerrorswhenyoumodifysomethingunintentionally.
Testingandlibrariescanassist,butworkingwithimmutabilityinJStakespracticeandmethodology.

Immutabilityhasadvantages.Itresultsincodethatissimplertoreasonabout.Italsoenablespersistency,theabilitytokeepolderversions
ofadatastructureandcopyonlythepartsthathavechanged.

edisadvantageofimmutabilityisthatmanyalgorithmsandoperationscannotbeimplementedeciently.

Tolearnmoreaboutimmutabilityandmutability,checkoutthefollowingresources:

ImmutabilityinJavaScript
ImmutableObjectswithObjectFreeze

MutablevsImmutableObjects

UsingImmutableDataStucturesinJavaScript
GettingStartedwithRedux(includesexamplesforaddressingimmutablestate)

Imperative and Declarative Programming

Whilesomelanguagesweredesignedtobeimperative(C,PHP)ordeclarative(SQL,HTML),JavaScript(andotherslikeJavaandC#)

cansupportbothprogrammingparadigms.

MostdevelopersfamiliarwitheventhemostbasicJavaScripthavewrittenimperativecode:instructionsinformingthecomputerhowto

achieveadesiredresult.Ifyou'vewrittena for loop,you'vewrittenimperativeJS.

Declarativecodetellsthecomputerwhatyouwanttoachieveratherthanhow,andthecomputertakescareofhowtoachievetheend
resultwithoutexplicitdescriptionfromthedeveloper.Ifyou'veused Array.map ,you'vewrittendeclarativeJS.

Imperative Programming
Imperativeprogrammingdescribeshowaprogram'slogicworksinexplicitcommandswithstatementsthatmodifytheprogramstate.

Considerafunctionthatincrementseverynumberinanarrayofintegers.AnimperativeJavaScriptexampleofthismightbe:

functionincrementArray(arr){

letresultArr=[];
for(leti=0;i<arr.length;i++){

resultArr.push(arr[i]+1);
}
returnresultArr;

isfunctionshowsexactlyhowthefunction'slogicworks:weiterateoverthearrayandexplicitlyincreaseeachnumber,pushingittoa
newarray.Wethenreturntheresultingarray.isisastep-by-stepdescriptionofthefunction'slogic.

Declarative Programming

Declarativeprogrammingdescribeswhataprogram'slogicaccomplisheswithoutdescribinghow.

AverystraightforwardexampleofdeclarativeprogrammingcanbedemonstratedwithSQL.Wecanqueryadatabasetable( People )for


peoplewiththelastname Smith likeso:

SELECT*FROMPeopleWHERELastName='Smith'

iscodeiseasytoreadanddescribeswhatwewanttoaccomplish.ereisnodescriptionofhowtheresultshouldbeachieved.e
computertakescareofthat.

Nowconsiderthe incrementArray() functionweimplementedimperativelyabove.Let'simplementthisdeclarativelynow:

functionincrementArray(arr){
returnarr.map(item=>item+1);

Weshowwhatwewanttoachieve,butnothowitworks.e Array.map() methodreturnsanewarraywiththeresultsofrunningthe


callbackoneachitemfromthepassedarray.isapproachdoesnotmodifyexistingvalues,nordoesitincludeanysequentiallogic

showinghowitcreatesthenewarray.
Note:JavaScript's map , reduce ,and filter aredeclarative,functionalarraymethods.Utilitylibrarieslikelodash
providemethodslike takeWhile , uniq , zip ,andmoreinadditionto map , reduce ,and filter .

Imperative and Declarative Programming Takeaways

Asalanguage,JavaScriptallowsbothimperativeanddeclarativeprogrammingparadigms.MuchoftheJScodewereadandwriteis

imperative.However,withtheriseoffunctionalprogramminginJS,declarativeapproachesarebecomingmorecommon.

Declarativeprogramminghasobviousadvantageswithregardtobrevityandreadability,butatthesametimeitcanfeelmagical.Many

JavaScriptbeginnerscanbenetfromgainingexperiencewritingimperativeJSbeforedivingtoodeepintodeclarativeprogramming.

Tolearnmoreaboutimperativeanddeclarativeprogramming,checkoutthefollowingresources:

ImperativevsDeclarativeProgramming
What'stheDierenceBetweenImperative,Procedural,andStructuredProgramming?

Imperativeand(Functional)DeclarativeJSInPractice

JavaScript'sMap,Reduce,andFilter

Higher-order Functions

Ahigher-orderfunctionisafunctionthat:

acceptsanotherfunctionasanargument,or

returnsafunctionasaresult.

InJavaScript,functionsarerst-classobjects.eycanbestoredandpassedaroundasvalues:wecanassignafunctiontoavariableor

passafunctiontoanotherfunction.

constdouble=function(x){
returnx*2;
}

consttimesTwo=double;

timesTwo(4);//result:returns8

Oneexampleoftakingafunctionasanargumentisacallback.Callbackscanbeinlineanonymousfunctionsornamedfunctions:
constmyBtn=document.getElementById('myButton');

//anonymouscallbackfunction
myBtn.addEventListener('click',function(e){console.log(`Clickevent:${e}`);});

//namedcallbackfunction

functionbtnHandler(e){
console.log(`Clickevent:${e}`);

}
myBtn.addEventListener('click',btnHandler);

Wecanalsopassafunctionasanargumenttoanyotherfunctionwecreateandthenexecutethatargument:

functionsayHi(){

alert('Hi!');
}
functiongreet(greeting){

greeting();
}

greet(sayHi);//alerts"Hi!"

Note:Whenpassinganamedfunctionasanargument,asinthetwoexamplesabove,wedon'tuseparentheses () .is
waywe'repassingthefunctionasanobject.Parenthesesexecutethefunctionandpasstheresultinsteadofthefunction
itself.

Higher-orderfunctionscanalsoreturnanotherfunction:

functionwhenMeetingJohn(){

returnfunction(){
alert('Hi!');
}

}
varatLunchToday=whenMeetingJohn();

atLunchToday();//alerts"Hi!"

Higher-order Function Takeaways


enatureofJavaScriptfunctionsasrst-classobjectsmakethemprimeforfacilitatingfunctionalprogramming.

Tolearnmoreabouthigher-orderfunctions,checkoutthefollowingresources:

FunctionsarerstclassobjectsinJavaScript
Higher-OrderFunctionsinJavaScript

Higher-orderfunctions-Part1ofFunctionalProgramminginJavaScript

EloquentJavaScript-Higher-orderFunctions
HigherOrderFunctions

Functional Programming

Nowwe'velearnedaboutpurity,statelessness,immutability,declarativeprogramming,andhigher-orderfunctions.eseareallconcepts

thatareimportantinunderstandingthefunctionalprogrammingparadigm.

In Practice: Functional Programming with JavaScript

Functionalprogrammingencompassestheaboveconceptsinthefollowingways:

Corefunctionalityisimplementedusingpurefunctionswithoutsideeects.
Dataisimmutable.

Functionalprogramsarestateless.

Imperativecontainercodemanagessideeectsandexecutesdeclarative,purecorecode.*

*IfwetriedtowriteaJavaScriptwebapplicationcomposedofnothingbutpurefunctionswithnosideeects,it
couldn'tinteractwithitsenvironmentandthereforewouldn'tbeparticularlyuseful.

Let'sexploreanexample.Saywehavesometextcopyandwewanttogetitswordcount.Wealsowanttondkeywordsthatarelonger

thanvecharacters.Usingfunctionalprogramming,ourresultingcodemightlooksomethinglikethis:

constfpCopy=`Functionalprogrammingispowerfulandenjoyabletowrite.It'sverycool!`;

//removepunctuationfromstring

conststripPunctuation=(str)=>
str.replace(/[.,\/#!$%\^&\*;:{}=\_`~()]/g,'');

//splitpassedstringonspacestocreateanarray
constgetArr=(str)=>

str.split('');
//countitemsinthepassedarray
constgetWordCount=(arr)=>

arr.length;

//finditemsinthepassedarraylongerthan5characters
//makeitemslowercase
constgetKeywords=(arr)=>

arr

.filter(item=>item.length>5)
.map(item=>item.toLowerCase());

//processcopytoprepthestring,createanarray,countwords,andgetkeywords

functionprocessCopy(str,prepFn,arrFn,countFn,kwFn){
constcopyArray=arrFn(prepFn(str));

console.log(`Wordcount:${countFn(copyArray)}`);
console.log(`Keywords:${kwFn(copyArray)}`);

processCopy(fpCopy,stripPunctuation,getArr,getWordCount,getKeywords);
//result:Wordcount:11

//result:Keywords:functional,programming,powerful,enjoyable

iscodeisavailabletorunatthisJSFiddle:FunctionalProgrammingwithJavaScript.It'sbrokenintodigestible,declarativefunctions

withclearpurpose.Ifwestepthroughitandreadthecomments,nofurtherexplanationofthecodeshouldbenecessary.Eachcore

functionismodularandreliesonlyonitsinputs(pure).elastfunctionprocessesthecoretogeneratethecollectiveoutputs.is

function, processCopy() ,istheimpurecontainerthatexecutesthecoreandmanagessideeects.We'veusedahigher-orderfunction

thatacceptstheotherfunctionsasargumentstomaintainthefunctionalstyle.

Functional Programming Takeaways

Immutabledataandstatelessnessmeanthattheprogram'sexistingstateisnotmodied.Instead,newvaluesarereturned.Purefunctions

areusedforcorefunctionality.Inordertoimplementtheprogramandhandlenecessarysideeects,impurefunctionscancallpure

functionsimperatively.

Tolearnmoreaboutfunctionalprogramming,checkoutthefollowingresources:

IntroductiontoImmutable.jsandFunctionalProgrammingConcepts
FunctionalProgrammingForeRestofUs

FunctionalProgrammingwithJavaScript

Don'tbeScaredofFunctionalProgramming

SoYouWanttobeaFunctionalProgrammer
lodash-FunctionalProgrammingGuide

Whatisthedierencebetweenfunctionalandimperativeprogramminglanguages?

EloquentJavaScript,1stEdition-FunctionalProgramming

FunctionalProgrammingbyExample

FunctionalProgramminginJavaScript-VideoSeries

IntroductiontoFunctionalJavaScript
Howtoperformsideeectsinpurefunctionalprogramming

PreventingSideEectsinJavaScript

Observables

Observablesaresimilartoarrays,exceptinsteadofbeingstoredinmemory,itemsarriveasynchronouslyovertime(alsocalledstreams).

Wecansubscribetoobservablesandreacttoeventsemittedbythem.JavaScriptobservablesareanimplementationoftheobserver

pattern.ReactiveExtensions(commonlyknownasRx*)providesanobservableslibraryforJSviaRxJS.

Todemonstratetheconceptofobservables,let'sconsiderasimpleexample:resizingthebrowserwindow.It'seasytounderstand

observablesinthiscontext.Resizingthebrowserwindowemitsastreamofeventsoveraperiodoftimeasthewindowisdraggedtoits
desiredsize.Wecancreateanobservableandsubscribetoittoreacttothestreamofresizeevents:

//createwindowresizestream

//throttleresizeevents

constresize$=
Rx.Observable

.fromEvent(window,'resize')

.throttleTime(350);

//subscribetotheresize$observable

//logwindowwidthxheight

constsubscription=
resize$.subscribe((event)=>{

lett=event.target;

console.log(`${t.innerWidth}pxx${t.innerHeight}px`);

});

eexamplecodeaboveshowsthatasthewindowsizechanges,wecanthrottletheobservablestreamandsubscribetothechangesto

respondtonewvaluesinthecollection.isisanexampleofahotobservable.

Hot Observables
Userinterfaceeventslikebuttonclicks,mousemovement,etc.arehot.Hotobservableswillalwayspushevenifwe'renotspecically

reactingtothemwithasubscription.ewindowresizeexampleaboveisahotobservable:the resize$ observablereswhetherornot

subscription exists.

Cold Observables

Acoldobservablebeginspushingonlywhenwesubscribetoit.Ifwesubscribeagain,itwillstartover.

Let'screateanobservablecollectionofnumbersrangingfrom 1 to 5 :

//createsourcenumberstream

constsource$=Rx.Observable.range(1,5);

//subscribetosource$observable

constsubscription=source$.subscribe(

(value)=>{console.log(`Next:${value}`);},//onNext
(event)=>{console.log(`Error:${event}`);},//onError

()=>{console.log('Completed!');}//onCompleted

);

Wecan subscribe() tothe source$ observablewejustcreated.Uponsubscription,thevaluesaresentinsequencetotheobserver.e

onNext callbacklogsthevalues: Next:1 , Next:2 ,etc.untilcompletion: Completed! .ecold source$ observablewecreated

doesn'tpushunlesswesubscribetoit.

Observables Takeaways

Observablesarestreams.Wecanobserveanystream:fromresizeeventstoexistingarraystoAPIresponses.Wecancreateobservables

fromalmostanything.Apromiseisanobservablewithasingleemittedvalue,butobservablescanreturnmanyvaluesovertime.

Wecanoperateonobservablesinmanyways.RxJSutilizesnumerousoperatormethods.Observablesareoenvisualizedusingpointson

aline,asdemonstratedontheRxMarblessite.Sincethestreamconsistsofasynchronouseventsovertime,it'seasytoconceptualizethisin

alinearfashionandusesuchvisualizationstounderstandRx*operators.Forexample,thefollowingRxMarblesimageillustratesthelter

operator:
Tolearnmoreaboutobservables,checkoutthefollowingresources:

ReactiveExtensions:Observable

CreatingandSubscribingtoSimpleObservableSequences

eintroductiontoReactiveProgrammingyou'vebeenmissing:RequestandResponse

IntroducingtheObservable
RxMarbles

RxBook-Observable

IntroducingtheObservable

Reactive Programming

Reactiveprogrammingisconcernedwithpropagatingandrespondingtoincomingeventsovertime,declaratively(describingwhattodo

ratherthanhow).

ReactiveprogrammingisoenassociatedwithReactiveExtensions,anAPIforasynchronousprogrammingwithobservablestreams.

ReactiveExtensions(abbreviatedRx*)provideslibrariesforavarietyoflanguages,includingJavaScript(RxJS).

In Practice: Reactive Programming with JavaScript

Hereisanexampleofreactiveprogrammingwithobservables.Let'ssaywehaveaninputwheretheusercanenterasix-character

conrmationcodeandwewanttoprintoutthelatestvalidcodeattempt.OurHTMLmightlooklikethis:

<!HTML>

<inputid="confirmationcode"type="text">
<p>

<strong>Validcodeattempt:</strong>

<codeid="attemptedcode"></code>

</p>

We'lluseRxJSandcreateastreamofinputeventstoimplementourfunctionality,likeso:

//JS
constconfCodeInput=document.getElementById('confirmationcode');

constattemptedCode=document.getElementById('attemptedcode');

constconfCodes$=
Rx.Observable

.fromEvent(confCodeInput,'input')

.map(e=>e.target.value)
.filter(code=>code.length===6);

constsubscription=confCodes$.subscribe(

(value)=>attemptedCode.innerText=value,
(event)=>{console.warn(`Error:${event}`);},

()=>{console.info('Completed!');}

);

iscodecanberunatthisJSFiddle:ReactiveProgrammingwithJavaScript.We'llobserveeventsfromthe confCodeInput input

element.enwe'llusethe map operatortogetthe value fromeachinputevent.Next,we'll filter anyresultsthatarenotsix

characterssotheywon'tappearinthereturnedstream.Finally,we'll subscribe toour confCodes$ observableandprintoutthelatest

validconrmationcodeattempt.Notethatthiswasdoneinresponsetoeventsovertime,declaratively:thisisthecruxofreactive

programming.

Reactive Programming Takeaways

ereactiveprogrammingparadigminvolvesobservingandreactingtoeventsinasynchronousdatastreams.RxJSisusedinAngular

andisgainingpopularityasaJavaScriptsolutionforreactiveprogramming.

Tolearnmoreaboutreactiveprogramming,checkoutthefollowingresources:

eintroductiontoReactiveProgrammingyou'vebeenmissing

IntroductiontoRx

eReactiveManifesto

UnderstandingReactiveProgrammingandRxJS
ReactiveProgramming

ModernizationofReactivity

Reactive-ExtensionsRxJSAPICore

Functional Reactive Programming

Insimpleterms,functionalreactiveprogrammingcouldbesummarizedasdeclarativelyrespondingtoeventsorbehaviorsovertime.To

understandthetenetsofFRPinmoredepth,let'stakealookatFRP'sformulation.enwe'llexamineitsuseinrelationtoJavaScript.

What is Functional Reactive Programming?

AmorecompletedenitionfromConalElliot,FRP'sformulator,wouldbethatfunctionalreactiveprogrammingis"denotativeand

temporallycontinuous".Elliotmentionsthathepreferstodescribethisprogrammingparadigmasdenotativecontinuous-time

programmingasopposedto"functionalreactiveprogramming".

Functionalreactiveprogramming,atitsmostbasic,originaldenition,hastwofundamentalproperties:

denotative:themeaningofeachfunctionortypeisprecise,simple,andimplementation-independent("functional"referencesthis)
continuoustime:variableshaveaparticularvalueforaveryshorttime:betweenanytwopointsareaninnitenumberofother

points;providestransformationexibility,eciency,modularity,andaccuracy("reactive"referencesthis)

Again,whenweputitsimply:functionalreactiveprogrammingisprogrammingdeclarativelywithtime-varyingvalues.

Tounderstandcontinuoustime/temporalcontinuity,considerananalogyusingvectorgraphics.Vectorgraphicshaveaninnite

resolution.Unlikebitmapgraphics(discreteresolution),vectorgraphicsscaleindenitely.eyneverpixellateorbecomeindistinctwhen

particularlylargeorsmallthewaybitmapgraphicsdo.

"FRPexpressionsdescribeentireevolutionsofvaluesovertime,representingtheseevolutionsdirectlyasrst-class
values."

ConalElliot

Functionalreactiveprogrammingshouldbe:

dynamic:canreactovertimeortoinputchanges

time-varying:reactivebehaviorscanchangecontinuallywhilereactivevalueschangediscretely

ecient:minimizeamountofprocessingnecessarywheninputschange
historicallyaware:purefunctionsmapstatefromapreviouspointintimetothenextpointintime;statechangesconcernthelocal

elementandnottheglobalprogramstate

ConalElliot'sslidesontheEssenceandOriginsofFRPcanbeviewedhere.eprogramminglanguageHaskelllendsitselftotrueFRP

duetoitsfunctional,pure,andlazynature.EvanCzaplicki,thecreatorofElm,givesagreatoverviewofFRPinhistalkControllingTime

andSpace:UnderstandingtheManyFormulationsofFRP.

Infact,let'stalkbrieyaboutEvanCzapliki'sElm.Elmisafunctional,typedlanguageforbuildingwebapplications.Itcompilesto

JavaScript,CSS,andHTML.eElmArchitecturewastheinspirationfortheReduxstatecontainerforJSapps.Elmwasoriginally

consideredatruefunctionalreactiveprogramminglanguage,butasofversion0.17,itimplementedsubscriptionsinsteadofsignalsinthe

interestofmakingthelanguageeasiertolearnanduse.Indoingso,ElmbidfarewelltoFRP.

In Practice: Functional Reactive Programming and JavaScript

etraditionaldenitionofFRPcanbediculttograsp,especiallyfordeveloperswhodon'thaveexperiencewithlanguageslikeHaskell

orElm.However,thetermhascomeupmorefrequentlyinthefront-endecosystem,solet'sshedsomelightonitsapplicationin

JavaScript.

InordertoreconcilewhatyoumayhavereadaboutFRPinJS,it'simportanttounderstandthatRx*,Bacon.js,Angular,andothersare

notconsistentwiththetwoprimaryfundamentalsofConalElliot'sdenitionofFRP.ElliotstatesthatRx*andBacon.jsarenotFRP.

Instead,theyare"compositionaleventsystemsinspiredbyFRP".

Functionalreactiveprogramming,asitrelatesspecicallytoJavaScriptimplementations,referstoprogramminginafunctionalstylewhile
creatingandreactingtostreams.isisfairlyfarfromElliot'soriginalformulation(whichspecicallyexcludesstreamsasacomponent),

butisneverthelessinspiredbytraditionalFRP.

It'salsocrucialtounderstandthatJavaScriptinherentlyinteractswiththeuserandUI,theDOM,andoenabackend.Sideeectsand

imperativecodeareparforthecourse,evenwhentakingafunctionalorfunctionalreactiveapproach.Withoutimperativeorimpure

code,aJSwebapplicationwithaUIwouldn'tbemuchusebecauseitcouldn'tinteractwithitsenvironment.

Let'stakealookatanexampletodemonstratethebasicprinciplesofFRP-inspiredJavaScript.issampleusesRxJSandprintsoutmouse

movementsoveraperiodoftenseconds:

//createatimeobservablethataddsanitemevery1second
//mapsoresultingstreamcontainseventvalues

consttime$=

Rx.Observable

.timer(0,1000)
.timeInterval()

.map(e=>e.value);

//createamousemovementobservable

//throttletoevery350ms
//mapsoresultingstreampushesobjectswithxandycoordinates
constmove$=

Rx.Observable

.fromEvent(document,'mousemove')
.throttleTime(350)

.map(e=>{return{x:e.clientX,y:e.clientY}});

//mergetime+mousemovementstreams
//completeafter10seconds

constsource$=

Rx.Observable

.merge(time$,move$)
.takeUntil(Rx.Observable.timer(10000));

//subscribetomergedsource$observable
//ifvalueisanumber,createTimeset()

//ifvalueisacoordinatesobject,addPoint()

constsubscription=

source$.subscribe(
//onNext

(x)=>{

if(typeofx==='number'){
createTimeset(x);

}else{

addPoint(x);

}
},

//onError

(err)=>{console.warn('Error:',err);},

//onCompleted
()=>{console.info('Completed');}

);

//addelementtoDOMtolistoutpointstouchedinaparticularsecond

functioncreateTimeset(n){

constelem=document.createElement('div');

constnum=n+1;
elem.id='t'+num;

elem.innerHTML=`<strong>${num}</strong>:`;

document.body.appendChild(elem);
}

//addpointstouchedtolatesttimeinstream

functionaddPoint(pointObj){
//addpointtolastappendedelement

constnumberElem=document.getElementsByTagName('body')[0].lastChild;

numberElem.innerHTML+=`(${pointObj.x},${pointObj.y})`;

}
YoucancheckoutthiscodeinactioninthisJSFiddle:FRP-inspiredJavaScript.Runtheddleandmoveyourmouseovertheresultarea

ofthescreenasitcountsupto10seconds.Youshouldseemousecoordinatesappearalongwiththecounter.isindicateswhereyour

mousewasduringeach1-secondtimeinterval.

Let'sbrieydiscussthisimplementationstep-by-step.

First,we'llcreateanobservablecalled time$ .isisatimerthataddsavaluetothecollectionevery 1000ms (everysecond).Weneedto

map thetimereventtoextractits value andpushitintheresultingstream.

Next,we'llcreatea move$ observablefromthe document.mousemove event.Mousemovementiscontinuous.Atanypointinthesequence,


thereareaninnitenumberofpointsinbetween.We'llthrottlethissotheresultingstreamismoremanageable.enwecan map the

eventtoreturnanobjectwith x and y valuestorepresentmousecoordinates.

Nextwewanttomergethe time$ and move$ streams.isisacombiningoperator.iswaywecanplotwhichmousemovements

occurredduringeachtimeinterval.We'llcalltheresultingobservable source$ .We'llalsolimitthe source$ observablesothatit

completesaertenseconds( 10000ms ).

Nowthatwehaveourmergedstreamoftimeandmovement,we'llcreatea subscription tothe source$ observablesowecanreactto

it.Inour onNext callback,we'llchecktoseeifthevalueisa number ornot.Ifitis,wewanttocallafunctioncalled createTimeset() .If

it'sacoordinatesobject,we'llcall addPoint() .Inthe onError and onCompleted callbacks,we'llsimplylogsomeinformation.

Let'slookatthe createTimeset(n) function.We'llcreateanew div elementforeachsecondinterval,labelit,andappendittothe

DOM.

Inthe addPoint(pointObj) function,we'llprintoutthelatestcoordinatesinthemostrecenttimeset div .iswillassociateeachsetof

coordinateswithitscorrespondingtimeinterval.Wecannowreadwherethemousehasbeenovertime.

Note:esefunctionsareimpure:theyhavenoreturnvalueandtheyalsoproducesideeects.esideeectsare
DOMmanipulations.Asmentionedearlier,theJavaScriptweneedtowriteforourappsfrequentlyinteractswithscope
outsideitsfunctions.

Functional Reactive Programming Takeaways

FRPencodesactionsthatreacttoeventsusingpurefunctionsthatmapstatefromapreviouspointintimetothenextpointintime.FRP

inJavaScriptdoesn'tadheretothetwoprimaryfundamentalsofConalElliot'sFRP,butthereiscertainlyvalueinabstractionsofthe

originalconcept.JavaScriptreliesheavilyonsideeectsandimperativeprogramming,butwecancertainlytakeadvantageofthepower

ofFRPconceptstoimproveourJS.

Finally,considerthisquotefromthersteditionofEloquentJavaScript(thesecondeditionisavailablehere):

"Fu-Tzuhadwrittenasmallprogramthatwasfullofglobalstateanddubiousshortcuts.Readingit,astudentasked'You
warnedusagainstthesetechniques,yetIndtheminyourprogram.Howcanthisbe?'
Fu-Tzusaid'ereisnoneedtofetchawaterhosewhenthehouseisnotonre.'{isisnottobereadasan
encouragementofsloppyprogramming,butratherasawarningagainstneuroticadherencetorulesofthumb.}"

MarijnHaverbeke,EloquentJavaScript,1stEdition,Chapter6

Tolearnmoreaboutfunctionalreactiveprogramming(FRP),checkoutthefollowingresources:

FunctionalReactiveProgrammingforBeginners

eFunctionalReactiveMisconception

WhatisFunctionalReactiveProgramming?

Haskell-FunctionalReactiveProgramming

ComposingReactiveAnimations

Specicationforafunctionalreactiveprogramminglanguage
AmoreelegantspecicationforFRP

FunctionalReactiveProgrammingforBeginners

Elm-AFarewelltoFRP

Earlyinspirationsandnewdirectionsinfunctionalreactiveprogramming

BreakingDownFRP

Rx*isnotFRP

Conclusion

We'llconcludewithanotherexcellentquotefromthersteditionofEloquentJavaScript:

"Astudenthadbeensittingmotionlessbehindhiscomputerforhours,frowningdarkly.Hewastryingtowritea
beautifulsolutiontoadicultproblem,butcouldnotndtherightapproach.Fu-Tzuhithimonthebackofhishead
andshouted'Typesomething!'estudentstartedwritinganuglysolution.Aerhehadnished,hesuddenly
understoodthebeautifulsolution."

MarijnHaverbeke,EloquentJavaScript,1stEdition,Chapter6

econceptsnecessaryforunderstandingfunctionalprogramming,reactiveprogramming,andfunctionalreactiveprogrammingcanbe

diculttograsp,letalonemaster.Writingcodethattakesadvantageofaparadigm'sfundamentalsistheinitialstep,evenifitisn't
entirelyfaithfulatrst.Practiceilluminatesthepathaheadandalsorevealspotentialrevisions.

Withthisglossaryasastartingpoint,youcanbegintakingadvantageoftheseconceptsandprogrammingparadigmstoincreaseyour

JavaScriptexpertise.Ifanythingisstillunclearregardingthesetopics,pleaseconsultthelinksineachsectionforadditionalresources.

You might also like