/
ASeamless,Client-CentricProgrammingModelforTypeSafeWebApplicationsAnto ASeamless,Client-CentricProgrammingModelforTypeSafeWebApplicationsAnto

ASeamless,Client-CentricProgrammingModelforTypeSafeWebApplicationsAnto - PDF document

faustina-dinatale
faustina-dinatale . @faustina-dinatale
Follow
373 views
Uploaded On 2015-08-05

ASeamless,Client-CentricProgrammingModelforTypeSafeWebApplicationsAnto - PPT Presentation

functionhandshakesocksocksendhelofunctionchatsockmsgsocksendtextmsgwindowonloadfunctionvarlogboxdocumentgetElementByIdlogvarmsgboxdocumentgetElementByIdmessage ID: 100839

functionhandshake(sock){sock.send('helo');}functionchat(sock msg){sock.send('text'+msg);}window.onload=function(){varlogbox=document.getElementById('log');varmsgbox=document.getElementById('message');

Share:

Link:

Embed:

Download Presentation from below link

Download Pdf The PPT/PDF document "ASeamless,Client-CentricProgrammingModel..." 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

ASeamless,Client-CentricProgrammingModelforTypeSafeWebApplicationsAntonEkbladandKoenClaessenChalmersUniversityofTechnologyfantonek,koeng@chalmers.seAbstractWeproposeanewprogrammingmodelforwebapplicationswhichis(1)seamless;oneprogramandonelanguageisusedtoproducecodeforbothclientandserver,(2)client-centric;theprogrammertakestheviewpointoftheclientthatrunscodeontheserverratherthantheotherwayaround,(3)functionalandtype-safe,and(4)portable;everythingisimplementedasaHaskelllibrarythatim-plicitlytakescareofallnetworkingcode.Ouraimistoimprovethepainfulanderror-proneexperienceoftoday'sstandarddevelop-mentmethods,inwhichclientsandserversarecodedindifferentlanguagesandcommunicatewitheachotherusingad-hocproto-cols.WepresentthedesignofourlibrarycalledHaste.App,anex-amplewebapplicationthatusesit,anddiscusstheimplementationandthecompilertechnologyonwhichitdepends.CategoriesandSubjectDescriptorsD.1.3[ProgrammingTech-niques]:DistributedProgramming;D.3.2[LanguageClassica-tions]:Applicative(functional)languages;H.3.5[OnlineInfor-mationServices]:Web-basedservicesKeywordswebapplications;distributedsystems;networkcom-munication1.IntroductionDevelopmentofwebapplicationsisnotaskforthefaintofheart.Theconventionalmethodinvolvessplittingyourprogramintotwologicalparts,writingtheoneinJavaScript,whichisnotoriousevenamongitsproponentsforbeingwonkyanderror-prone,andtheotherinanycompiledorserver-interpretedlanguage.Then,thetwoaregluedtogetherusingwhicheverhome-grownnetworkprotocolseemstottheapplication.However,mostwebapplicationsareconceptuallysingleentities,makingthisforcedsplitanundesir-ablehindrancewhichintroducesnewpossibilitiesfordefects,addsdevelopmentoverheadandpreventscodereuse.Severalsolutionstothisproblemhavebeenproposed,asdiscussedinsection5.1,buttheperfectonehasyettobefound.Inthispaper,Permissiontomakedigitalorhardcopiesofallorpartofthisworkforpersonalorclassroomuseisgrantedwithoutfeeprovidedthatcopiesarenotmadeordistributedforprotorcommercialadvantageandthatcopiesbearthisnoticeandthefullcitationontherstpage.Copyrightsforcomponentsofthisworkownedbyothersthantheauthor(s)mustbehonored.Abstractingwithcreditispermitted.Tocopyotherwise,orrepublish,topostonserversortoredistributetolists,requirespriorspecicpermissionand/orafee.Requestpermissionsfrompermissions@acm.org.Haskell'14,September4–5,2014,Gothenburg,Sweden.Copyrightisheldbytheowner/author(s).PublicationrightslicensedtoACM.ACM978-1-4503-3041-1/14/09...$15.00.http://dx.doi.org/10.1145/2633357.2633367weproposeafunctionalprogrammingmodelinwhichawebappli-cationiswrittenasasingleprogramfromwhichclientandserverexecutablesaregeneratedduringcompilation.Typeannotationsinthesourceprogramcontrolwhichpartsareexecutedontheserverandwhichareexecutedontheclient,andthetwocommunicateus-ingtypesafeRPCcalls.Functionswhicharenotexplicitlydeclaredasserversideorclientsideareusablebyeitherside.RecentadvancesincompilertechnologyfromfunctionallanguagestoJavaScripthaveledtoawealthofcompilerstargetingthewebspace,andhaveenabledthepracticaldevelopmentoffunctionallibrariesandapplicationsforthebrowser.Thisenablesustoim-plementoursolutionasasimpleHaskelllibraryforanycompilercapableofproducingJavaScriptoutput,requiringnofurthermodi-cationtoexistingcompilers.AsourimplementationtargetstheHasteHaskelltoJavaScriptcom-piler[11],thispaperalsogoesintosomedetailaboutitsdesignandimplementationaswellasthealternativesavailableforcompilingfunctionallanguagestoabrowserenvironment.MotivationCodewritteninJavaScript,theonlywidelysupportedlanguageforclientsidewebapplications,isoftenconfusinganderror-prone,muchduetothelanguage'slackofmodularity,encap-sulationfacilitiesandtypesafety.Worse,mostwebapplications,beingintendedtofacilitatecommu-nication,datastorageandothertasksinvolvingsomecentralizedresource,alsorequireasignicantservercomponent.Thiscompo-nentisusuallyimplementedasacompletelyseparateprogram,andcommunicateswiththeclientcodeoversomenetworkprotocol.Thisstateofthingsisnotaconsciousdesignchoice-mostwebapplicationsareconceptuallyasingleentity,nottwoprogramswhichjusthappentotalktoeachotheroveranetwork-butaconsequenceoftherebeingalarge,distributednetworkbetweentheclientandserverparts.However,suchimplementationdetailsshouldnotbeallowedtodictatethewaywestructureandreasonaboutourapplications-clearly,anabstractioniscalledfor.Foramoreconcreteexample,let'ssaythatwewanttoimplementasimple“chatbox”componentforawebsite,toallowvisitorstodis-cussthesite'scontentinrealtime.UsingmainstreamdevelopmentpracticesandrecenttechnologiessuchasWebSockets[15],wemaycomeupwithsomethingliketheprogramingure1forourclientprogram.Inaddition,acorrespondingserverprogramwouldneedtobewrittentohandledistributionofmessagesamongclients.Wewillnotgivesuchanimplementationhere,aswedonotbelieveitnecessarytostatetheproblemathand.Sincethe“chatbox”applicationisverysimple-usersshouldonlybeabletosendandreceivetextmessagesinrealtime-weoptforaverysimpledesign.TwoUIelements,logboxandmsgbox,representthechatlogandthetextareawheretheuserinputstheir functionhandshake(sock){sock.send('helo');}functionchat(sock,msg){sock.send('text'+msg);}window.onload=function(){varlogbox=document.getElementById('log');varmsgbox=document.getElementById('message');varsock=newWebSocket('ws://example.com');sock.onmessage=function(e){logbox.value=e.data+LINE+logbox.value;};sock.onopen=function(e){handshake(sock);msgbox.addEventListener('keydown',function(e){if(e.keyCode==13){varmsg=msgbox.value;msgbox.value='';chat(sock,msg);}});};}; Figure1:JavaScriptchatboximplementationmessagesrespectively.Whenamessagearrives,itisprependedtothechatlog,makingthemostrecentmessageappearatthetopofthelogwindow,andwhentheuserhitsthereturnkeyintheinputtextboxthemessagecontainedthereinissentandtheinputtextboxiscleared.Messagesaretransmittedasstrings,withtheinitialfourcharactersindicatingthetypeofthemessageandtherestbeingtheoptionalpayload.Thereareonlytwomessages:ahandshakeindicatingthatauserwantstojointheconversation,andabroadcastmessagewhichsendsalineoftexttoallconnectedusersviatheserver.Theonlymessagesreceivedfromtheserverarenewchatmessages,deliveredassimplestrings.Thiscodelookssolidenoughbywebstandards,buteventhissim-plepieceofcodecontainsnolessthanthreeasynchronouscall-backs,twoofwhichbothreadandmodifytheapplication'sglobalstate.Thismakestheprogramownon-obvious,andintroducesunnecessaryriskandcomplexitythroughthehaphazardstatemod-ications.Moreover,thiscodeisnotveryextensible.Ifthissimpleapplicationistobeenhancedwithnewfeaturesdowntheroad,thenetworkprotocolwillclearlyneedtoberedesigned.However,ifweweredevelopingthisapplicationforaclient,saidclientwouldlikelynotwanttopaytheaddedcostforthedesignandimplementationoffeaturesshedidnot-andperhapsneverwill-askfor.Shouldtheprotocolneedupdatinginthefuture,howmuchtimewillweneedtospendonensuringthattheprotocolisusedproperlyacrossourentireprogram,andhowmuchextraworkwillittaketokeeptheclientandserverinsync?Howmuchcodewillneedtobewrittentwice,oncefortheclientandoncefortheserver,duetotheunfortunatefactthatthetwopartsareimplementedasseparateprograms,possiblyinseparatelanguages?Aboveall,isitreallynecessaryforsuchasimpleprogramtoinvolveclient/serverarchitecturesandnetworkprotocoldesignatall?2.AseamlessprogrammingmodelTherearemanyconceivableimprovementstothemainstreamwebdevelopmentmodeldescribedintheprevioussection.WeproposeanalternativeprogrammingmodelbasedonHaskell,inwhichwebapplicationsarewrittenasasingleprogramratherthanastwoindependentpartsthatjustsohappentotalktoeachother.Ourproposedmodel,dubbed“Haste.App”,hasthefollowingprop-erties:Theprogrammingmodelissynchronous,givingtheprogram-merasimple,linearviewoftheprogramow,eliminatingtheneedtoprogramwithcallbacksandcontinuations.Side-effectingcodeisexplicitlydesignatedtorunoneithertheclientortheserverusingthetypesystemwhilepurecodecanbesharedbyboth.Additionally,generalIOcomputationsmaybeliftedintobothclientandservercode,allowingforsafeIOcodereusewithintheconnesoftheclientorserverdesignatedfunctions.Client-servernetworkcommunicationishandledthroughstati-callytypedRPCfunctioncalls,extendingthereachofHaskell'stypecheckeroverthenetworkandgivingtheprogrammerad-vancewarningwhensheusesnetworkservicesincorrectlyorforgetstoupdatecommunicationcodeastheapplication'sin-ternalprotocolchanges.Ourmodeltakestheviewthattheclientsideisthemaindriverwhendevelopingwebapplicationsandaccordinglyassignstheservertheroleofacomputationaland/orstorageresource,taskedwithservicingclientrequestsratherthandrivingtheprogram.Whileitisentirelypossibletoimplementaserver-to-clientcommunicationchannelontopofourmodel,webelievethatchoosingonesideoftheheterogenousclient-serverrela-tionasthemasterhelpskeepingtheprogramowlinearandpredictable.TheimplementationisbuiltasalibraryontopoftheGHCandHasteHaskellcompilers,requiringlittletonospecializedcom-pilersupport.Programsarecompiledtwice;oncewithHasteandoncewithGHC,toproducethenalclientandserversidecoderespectively.2.1ArstexampleWhileexplainingthepropertiesofoursolutionisallwellandgood,nothingcomparestoagoodoldHelloWorldexampletoconveytheidea.Webeginbyimplementingafunctionwhichprintsagreetingtotheserver'sconsole.importHaste.ApphelloServer::String!Server()helloServername=liftIO$putStrLn(name++"sayshello!")ComputationsexclusivetotheserversideliveintheServermonad.ThisisbasicallyanIOmonad,ascanbeseenfromtheregularputStrLnIOcomputationbeingliftedintoit,withafewextraoperationsforsessionhandling;itsmainpurposeistopreventtheprogrammerfromaccidentallyattemptingtoperformclient-exclusiveoperations,suchaspoppingupabrowserdialogbox,ontheserver.Next,weneedtomakethehelloServerfunctionavailableasanRPCfunctionandcallitfromtheclient. main::AppDonemain=dogreetings remotehelloServerrunClient$doname prompt"Hithere,whatisyourname?"onServer(greetings.ကname)Themainfunctionis,asusual,theentrypointofourapplication.IncontrasttotraditionalapplicationswhichliveeitherontheclientorontheserverandbeginintheIOmonad,Haste.AppapplicationsliveonbothandbeginexecutionintheAppmonadwhichprovidessomecrucialtoolstofacilitatetypedcommunicationbetweenthetwo.Theremotefunctiontakesanarbitraryfunction,providedthatallitsargumentsaswellasitsreturnvalueareserializablethroughtheSerializetypeclass,andproducesatypedidentierwhichmaybeusedtorefertotheremotefunction.Inthisexample,thetypeofgreetingsisRemote(String!Server()),indicatingthattheidentierreferstoaremotefunctionwithasingleStringargumentandnoreturnvalue.RemotefunctionsallliveintheServermonad.ThepartoftheprogramcontainedwithintheAppmonadisexecutedonboththeserverandtheclient,albeitwithslightlydifferentsideeffects,asdescribedinsection3.Aftertheremotecall,weenterthedomainofclient-exclusivecodewiththeapplicationofrunClient.Thisfunctionexecutescom-putationsintheClientmonadwhichisessentiallyanIOmonadwithcooperativemultitaskingaddedontop,tomitigatethefactthatJavaScripthasnonativeconcurrencysupport.runClientdoesnotreturn,andistheonlyfunctionwithareturntypeofAppDone,whichensuresthateachAppcomputationcontainsexactlyoneclientcomputation.InordertomakeanRPCcallusinganidentierobtainedfromremote,wemustsupplyitwithanargument.Thisisdoneus-ingthe&#x.000;operator.Itmightbeinterestingtonotethatitstype,Serializea)Remote(a!b)!a!Remoteb,isverysimilartothetypeofthe*&#x]TJ ;.31; -1;&#x.434;&#x Td ;&#x[000;operatoroverapplicativefunctors.Thisisnotacoincidence;&#x.000;performsthesamerolefortheRemotetypeas*&#x]TJ ;.31; -1;&#x.435;&#x Td ;&#x[000;performsforapplicativefunctors.ThereasonforusingaseparateoperatorforthisinsteadofmakingRemoteaninstanceofApplicativeisthatsincefunctionsembeddedintheRemotetypeexistonlytobecalledoveranetwork,suchfunctionsmustonlybeappliedtoargumentswhichcanbeserializedandsentoveranetworkconnection.WhenaRemotefunctionisappliedtoanar-gumentusing&#x.000;,theargumentisserializedandstoredinsidetheresultingRemoteobject,awaitingdispatch.Remotecomputationscanthusbeseenasexplicitrepresentationsofclosures.Afterapplyingthevalueobtainedfromtheusertotheremotefunction,weapplytheonServerfunctiontotheresult,whichdispatchestheRPCcalltotheserver.onServerwillthenblockuntiltheRPCcallreturns.Torunthisexample,anaddressandaportmustbeprovidedsothattheclientknowswhichservertocontact.Thereareseveralwaysofdoingthis:usingtheGHCpluginsystem,throughTemplateHaskellorbyslightlyalteringhowprogramentrypointsaretreatedinacompilerorwrapperscript,tonameafew.Anon-intrusivemethodwhenusingtheGHC/Hastecompilerpairwouldbetoadd-main-issetuptobothcompilers'commandlineandaddthesetupfunctiontothesourcecode. main=doremoteref liftServerIO$newIORef0count remote$dor remoterefliftIO$atomicModifyIORefr(v!(v+1,v+1))runClient$dovisitors onServercountalert("Yourarevisitor#"++showvisitors) Figure2:serversidestate:doingitproperlysetup::IO()setup=runApp(mkConfig"ws://localhost:1111"1111)mainThiswillinstructtheserverbinarytolistenontheport1111whenstarted,andtheclienttoattemptcontactwiththatportonthelocalmachine.Theexactmechanismchosentoprovidethehostandportareimplementationspecic,andwillintheinterestofbrevitynotbediscussedfurther.2.2UsingserversidestateWhiletheHelloServerexampleillustrateshowclient-servercom-municationishandled,mostwebapplicationsneedtokeepsomeserversidestateaswell.Howcanwecreatestateholdingelementsfortheserverwhicharenotaccessibletotheclient?Toaccomplishthis,weneedtointroduceawaytoliftarbitraryIOcomputations,butensurethatsaidcomputationsareexecutedontheserverandnowhereelse.ThisisaccomplishedusingamorerestrictedversionofliftIO:liftServerIO::IOa!App(Servera)liftServerIOperformsitsargumentcomputationonceontheserver,intheAppmonad,andthenreturnstheresultofsaidcom-putationinsidetheServermonadsothatitisonlyreachablebyserversidecode.AnyclientsidecodeisthusfreetocompletelyignoreexecutingcomputationsliftedusingliftServerIO;sincetheresultofaserverliftedcomputationisneverobservableontheclient,theclienthasnoobligationtoevenproducesuchavalue.Figure2showshowtomakeproperuseofserversidestate.2.3Thechatbox,revisitedNowthatwehaveseenhowtoimplementbothnetworkcommu-nication,wearereadytorevisitthechatboxprogramfromsection1,thistimeusingourimprovedprogrammingmodel.Sincewearenowwritingtheentireapplication,bothclientandserver,asop-posedtotheclientpartfromourmotivatingexample,ourprogramhasthreenewresponsibilities.Weneedtoaddconnectinguserstoalistofmessagerecipients;usersleavingthesiteneedtoberemovedfromtherecipientlist;andchatmessagesneedtobedistributedtoallusersinthelist. Withthisinmind,webeginbyimportingafewmoduleswearegoingtoneedanddenethetypeforourrecipientlist.importHaste.AppimportHaste.App.ConcurrentimportqualifiedControl.ConcurrentasCCtypeRecipient=(SessionID,CC.ChanString)typeRcptList=CC.MVar[Recipient]WeuseanMVarfromControl.Concurrenttostorethelistofrecipients.ArecipientwillberepresentedbyaSessionID,anidentierusedbyHaste.Apptoidentifyusersessions,andanMVarintowhichnewchatmessagessenttotherecipientwillbewrittenastheyarrive.Next,wedeneourhandshakeRPCfunction.srvHello::ServerRcptList!Server()srvHelloremoteRcpts=dorecipients remoteRcptssid getSessionIDliftIO$dorcptChan CC.newChanCC.modifyMVarrecipients$cs!return((sid,rcptChan):cs,())AnMVarisassociatedwiththeconnectingclient'ssessionidenti-er,andthepairisprependedtotherecipientlist.Noticehowtheapplication'sserverstateispassedinasthefunction'sargument,wrappedintheServermonadinordertopreventclient-sidein-spection.srvSend::ServerRcptList!String!Server()srvSendremoteRcptsmessage=dorcpts remoteRcptsliftIO$dorecipients CC.readMVarrcptsmapM_(flipCC.writeChanmessage)recipientsThesendfunctionisslightlymorecomplex.TheincomingmessageiswrittentotheChancorrespondingtoeachactivesession.srvAwait::ServerRcptList!ServerStringsrvAwaitremoteRcpts=dorcpts remoteRcptssid getSessionIDliftIO$dorecipients CC.readMVarrcptscaselookupsidrecipientsofJustmv!CC.readChanmv_!fail"Unregisteredsession!"Thenalserveroperation,notifyingusersofpendingmessages,ndstheappropriateChantowaitonbysearchingtherecipientlistforthesessionidentierofthecallinguser,andthenblocksuntilamessagearrivesinsaidMVar.Thisisalittledifferentfromtheothertwooperations,whichperformtheirworkasquicklyaspossibleandthenreturnimmediately.Ifthecaller'ssessionidentiercouldnotbefoundintherecipientlist,ithasforsomereasonnotcompleteditshandshakewiththeserver.Ifthisisthecase,wesimplydropthesessionbythrowinganerror;anexceptionwillbethrowntotheclient.Noserversidestateneedstobecleanedupastheverylackofsuchstatewasourreasonfordroppingthesession.Havingimplementedourthreeserveroperations,allthat'sleftistotiethemtotheclient.Inthistying,weseeourmainadvantageovertheJavaScriptversioninsection1inaction:theremotefunctionbuildsastronglytypedbridgebetweentheclientandtheserver,ensuringthatanyfutureenhancementstoourchatboxprogramaremadesafely,inoneplace,insteadofbeingspreadaboutthroughouttwodisjointcodebases.main::AppDonemain=dorecipients liftServerIO$CC.newMVar[]hello remote$srvHellorecipientsawaitMsg remote$srvAwaitrecipientssendMsg remote$srvSendrecipientsrunClient$dowithElems["log","message"]$[log,msgbox]!doonServerhelloNoticethattherecipientslistispassedtoourthreeserverop-erationsbeforetheyareimported;sincerecipientsisamutablereferencecreatedontheserverandinaccessibletoclientcode,itisnotpossibletopassitoverthenetworkasanRPCargument.Evenifitwerepossible,passingserver-privatestatebackandforthoverthenetworkwouldbequiteinappropriateduetoprivacyandsecurityconcerns.ThewithElemsfunctionispartoftheHastecompiler'sbundledDOMmanipulationlibrary;itlocatesreferencestotheDOMnodeswiththegivenidentiersandpassessaidreferencestoafunction.Inthiscasethevariablelogwillbeboundtothenodewiththeidentier“log”,andmsgboxwillbeboundtothenodeidentiedby“message”.ThesearethesameDOMnodesthatwerereferencedinouroriginalexample,andrefertothechatlogwindowandthetextinputeldrespectively.AfterlocatingalltheneededUIelements,theclientproceedstoregisteritselfwiththeserver'srecipientlistusingthehelloremotecomputation.letrecvLoopchatlines=dosetProplog"value"$unlineschatlinesmessage onServerawaitMsgrecvLoop(message:chatlines)fork$recvLoop[]TherecvLoopfunctionperpetuallyaskstheserverfornewmes-sagesandupdatesthechatlogwheneveronearrives.Notethatun-liketheonmessagecallbackoftheJavaScriptversionofthisex-ample,recvLoopisactingasacompletelyself-containedprocesswithlinearprogramow,keepingtrackofitsownstateandonlyreachingouttotheoutsideworldtowriteitsstatetothechatlogwhenevernecessary.AstheawaitMsgfunctionblocksuntilames-sagearrives,recvLoopwillmakeexactlyoneiterationperreceivedmessage.msgbox`onEvent`OnKeyPress$13!domsg getPropmsgbox"value"setPropmsgbox"value"""onServer(sendMsg.ကmsg)Thisisthenalpartofourprogram;wesetupaneventhandlertocleartheinputboxandsenditscontentsofftotheserverwhenevertheuserhitsreturn(charactercode13)whiletheinputboxhasfocus. runClient::Client()!AppDoneliftServerIO::IOa!App(Servera)remote::Remotablea)a!App(Remotea)onServer::Remote(Servera)!Clienta(.က)::Serializea)Remote(a!b)!a!RemotebgetSessionID::ServerSessionID Figure3:TypesoftheHaste.Appcorefunctions Function Purpose runClient LiftasingleClientcomputationintotheAppmonad.MustbeattheveryendofanAppcomputation,whichisen-forcedbythetypesystem. liftServerIO LiftanIOcomputationintotheAppmonad.Thecomputationanditsresultareexclusivetotheserver,asenforcedbythetypesystem,andarenotobserv-ableontheclient. remote Makeaserversidefunctionavailabletobecalledremotelybytheclient. onServer Dispatcharemotecalltotheserverandwaitforitscompletion.Theresultoftheremotecomputationisreturnedontheclientafteritcompletes. &#x.000; Applyanremotefunctiontoaserializ-ableargument. getSessionID Gettheuniqueidentierforthecur-rentsession.Thisisapureconveniencefunction,torelieveprogrammersoftheburdenofsessionbookkeeping. Table1.CorefunctionsofHaste.AppThediscerningreadermaybeslightlyannoyedattheneedtoex-tractthecontentsfromRemotevaluesateachpointofuse.Indeed,inasimpleexamplesuchasthis,thesourcecluttercausedbythisbecomesadisproportionateirritant.Fortunately,mostwebapplica-tionstendtohavemorecomplexclient-serverinteractions,reduc-ingthisoverheadsignicantly.AcompletelistingofthecorefunctionsinHaste.Appisgivenintable1,andtheirtypesaregiveningure3.3.ImplementationOurimplementationisbuiltinthreelayers:thecompilerlayer,theconcurrencylayerandthecommunicationlayer.TheconcurrencyandcommunicationlayersaresimpleHaskelllibraries,portabletoanyotherpairofstandardHaskellcompilerswithminimaleffort.Topassdatabackandforthoverthenetwork,messagesareserial-izedusingJSON,afairlylightweightformatusedbymanywebapplications,andsentusingtheHTML5WebSocketsAPI.Thischoiceiscompletelyarbitrary,guidedpurelybyimplementationconvenience.Itiscertainlynotthemostperformantchoice,butcanbetriviallyreplacedwithsomethingmoresuitableasneeded.Theimplementationdescribedhereisaslightsimplicationofourimplementation,removingsomeperformanceenhancementsanderrorhandlingclutterintheinterestofclarity.Thecom-pleteimplementationisavailablefordownload,togetherwiththeHastecompiler,fromHackageaswellasfromourwebsiteathttp://haste-lang.org.TwocompilersTheprincipaltricktooursolutioniscompilingthesameprogramtwice;oncewithacompilerthatgeneratestheserverbinary,andoncewithonethatgeneratesJavaScript.Conditionalcompilationisusedforaselectfewfunctions,toenableslightlydifferentbehaviorontheclientandontheserverasnecessary.UsingHaskellasthebaselanguageofoursolutionleadsustochooseGHCasourserversidecompilerbydefault.WechosetheHastecompilertoprovidetheclientsidecode,mainlyowingtoourgreatfamiliaritywithitanditshandyabilitytomakeuseofvanillaHaskellpackagesfromHackage.TheAppmonadTheAppmonadiswhereremotefunctionsaredeclared,serverstateisinitializedandprogramowishandedovertotheClientmonad.Itsdenitionisasfollows.typeCallID=InttypeMethod=[JSON]!IOJSONtypeAppState=(CallID,[(CallID,Method)])newtypeAppa=App(StateTAppStateIOa)deriving(Functor,Applicative,Monad)Aswecansee,Appisasimplestatemonad,withunderlyingIOcapabilitiestoallowserversidecomputationstobeforkedfromwithinit.ItsCallIDstateelementcontainstheidentiertobegiventothenextremotefunction,anditsotherstateelementcontainsamappingfromidentierstoremotefunctions.WhatmakesAppinterestingisthatcomputationsinthismonadareexecutedonboththeclientandtheserver;onceonserverstartup,andonceinthestartupphaseofeachclient.Itsoperationsbehaveslightlydifferentlydependingonwhethertheyareexecutedontheclientorontheserver.Executionisdeterministic,ensuringthatthesamesequenceofCallIDsaregeneratedduringeveryrun,bothontheserverandonallclients.Thisisnecessarytoensurethatanyparticularcallidentieralwaysreferstothesameserversidefunctiononallclients.Afterallcommoncodehasbeenexecuted,theprogramowdi-vergesbetweentheclientandtheserver;clientside,runClientlaunchestheapplication'sClientcomputationwhereasontheserver,thiscomputationisdiscarded,andtheserverinsteadgoesintoaneventloop,waitingforcallsfromtheclient.TheworkingsoftheAppmonadbasicallyhingesontheServerandRemoteabstractdatatypes.Serveristhemonadwhereinanyserversidecodeiscontained,andRemotedenotesfunctionswhichliveontheserverbutcanbeinvokedremotelybytheclient.Theimplementationofthesetypesandthefunctionsthatoperateonthemdifferbetweentheclientandtheserver.ClientsideimplementationsWebeginbylookingattheclientsideimplementationforthosetwotypes.dataServera=ServerDummydataRemotea=RemoteCallID[JSON] TheServermonadisquiteuninterestingtotheclient;sinceopera-tionsperformedwithinitcannotbeobservedbytheclientinanyway,suchcomputationsaresimplyrepresentedbyadummyvalue.TheRemotetypecontainstheidentierofaremotefunctionandalistoftheserializedargumentstobepassedwheninvokingit.Inessence,itisanexplicitrepresentationofaremoteclosure.Suchclosurescanbeappliedtovaluesusingthe&#x.000;operator.(.က)::Serializea)Remote(a!b)!a!Remoteb(Remoteidentifierargs).ကarg=Remoteidentifier(toJSONarg:args)TheremotefunctionisusedtobringserversidefunctionsintoscopeontheclientasRemotefunctions.Itisimplementedusingasimplecounterwhichkeepstrackofhowmanyfunctionshavebeenimportedsofarandthuswhichidentiertoassigntothenextremotefunction.remote::Remotablea)a!App(Remotea)remote_=App$do(next_id,remotes) getput(next_id+1,remotes)return(Remotenext_id[])Astheremotefunctionlivesontheserver,theclientonlyneedsanidentiertobeabletocallonit.Theremotefunctionisthusignored,sothatitcanbeoptimizedoutofexistenceintheclientexecutable.Lookingatitstype,wecanseethatremoteacceptsanyargumentinstantiatingtheRemotableclass.Remotableisdenedasfollows.classRemotableawheremkRemote::a!([JSON]!ServerJSON)instanceSerializea)Remotable(Servera)wheremkRemotem=_!fmaptoJSONminstance(Serializea,Remotableb))Remotable(a!b)wheremkRemotef=(x:xs)!mkRemote(f$fromJSONx)xsInessence,anyfunction,overanynumberofarguments,whichreturnsaserializablevalueintheServermonadcanbeimported.ThemkRemotefunctionmakesuseofawell-knowntypeclasstrickforcreatingstaticallytypedvariadicfunctions,andworksverymuchliketheprintffunctionofHaskell'sstandardlibrary.[25]ThenalfunctionoperatingonthesetypesisliftServerIO,usedtoinitializestateholdingelementsandperformothersetupfunc-tionalityontheserver.liftServerIO::IOa!App(Servera)liftServerIO_=App$returnServerDummyAswecansee,theimplementationisassimpleascanbe.SinceServerisrepresentedbyadummyvalueontheclient,wejustreturnsaidvalue.ServersideimplementationsTheserversiderepresentationoftheServerandRemotetypesareinasensetheoppositesoftheirclientsidecounterparts.newtypeServera=Server(ReaderTSessionInfoIOa)deriving(Functor,Applicative,Monad,MonadIO)dataRemotea=RemoteDummyWheretheclientisabletodosomethingusefulwiththeRemotetypebutcan'ttouchServervalues,theserverhasnowaytoinspectRemotefunctions,andthusonlyhasano-opimplementationofthe&#x.000;operator.Ontheotherhand,itdoeshavefullaccesstothevaluesandsideeffectsoftheServermonad,whichisanIOmonadwithsomeadditionalsessiondatafortheconvenienceofserversidecode.ServervaluesareproducedbytheliftServerIOandremotefunc-tions.liftServerIOisquitesimple:thefunctionexecutesitsargu-mentimmediatelyandtheresultisreturned,tuckedawaywithintheServermonad.liftServerIO::IOa!App(Servera)liftServerIOm=App$dox liftIOmreturn(returnx)Theserverversionofremoteisalittlemorecomplexthanitsclientsidecounterpart.Inadditiontokeepingtrackoftheidentierofthenextremotefunction,theserversideremotepairsupremotefunctionswiththeseidentiersinanidentier-functionmapping.remotef=App$do(next_id,remotes) getput(next_id+1,(next_id,mkRemotef):remotes)returnRemoteDummyThisconceptofclientsideidentiersbeingsenttotheserverandusedasindicesintoatablemappingidentierstoremotelyaccessiblefunctionsisanextensionoftheconceptof“staticvalues”introducedbyEpsteinetalwithCloudHaskell[12],whichisdiscussedfurtherinsection5.1.TheserversidedispatcherAftertheAppcomputationnishes,theidentier-functionmappingaccumulatedinitsstateishandedovertotheserver'seventloop,whereitisusedtodispatchtheproperfunctionsforincomingcallsfromtheclient.onEvent::[(CallID,Method)]!JSON!IO()onEventmappingincoming=dolet(nonce,identifier,args)=fromJSONincomingJustf=lookupidentifiermappingresult fargswebSocketSend$toJSON(nonce,result)ThefunctioncorrespondingtotheRPCcall'sidentierislookedupintheidentier-functionmappingandappliedtothereceivedlistofarguments.ThereturnvalueispairedwithanonceprovidedbytheclienttotieittoitscorrespondingRPCcall,sincetheremaybeseveralsuchcallsinprogressatthesametime.Thepairisthensentbacktotheclient.Notethatduringnormaloperation,itisnotpossiblefortheclienttosubmitanRPCcallwithanon-existentcallidentier,hencetheirrefutablepatternmatchonJustf.Shouldthispatternmatchfail,thisisasuresignofmalicioustampering;theresultingexceptioniscaughtandthesessionisdroppedasitisnolongermeaningfultocontinue. TheClientmonadandtheonServerfunctionAssynchronousnetworkcommunicationisoneofourstatedgoals,itisclearthatwewillneedsomekindofblockingprimitive.SinceJavaScriptdoesnotsupportanykindofblocking,wewillhavetoimplementthisourselves.Asolutionisgiveninthepoorman'sconcurrencymonad[4].Mak-inguseofacontinuationmonadwithprimitiveoperationsforfork-ingacomputationandatomicallyliftinganIOcomputationintothemonad,itispossibletoimplementcooperativemultitaskingontopofthenon-concurrentJavaScriptruntime.ThismonadallowsustoimplementMVarsasourblockingprimitive,withthesameseman-ticsastheirregularHaskellcounterpart.[21]Thisconcurrency-enhancedIOmonadisusedasthebasisoftheClientmonad.typeNonce=InttypeClientState=(Nonce,MapNonce(MVarJSON))typeClient=StateTClientStateConcAsidefromtheaddedconcurrencycapabilities,theClientmonadonlyhasasingleparticularlyinterestingoperation:onServer.newResult::Client(Nonce,MVarJSON)newResult=do(nonce,m) getmv liftIOnewEmptyMVarput(nonce+1,insertnoncevarm)return(nonce,mv)onServer::Serializea)Remote(Servera)!ClientaonServer(Remoteidentifierargs)=do(nonce,mv) newResultwebSocketSend$toJSON(nonce,identifier,reverseargs)fromJSON$ကtakeMVarmvThecreateResultMVarfunctioncreatesanewMVar,pairedwithitscorrespondingnonceintheAfteracallisdispatched,onServerblocks,waitingforitsresultvariabletobelledwiththeresultofthecall.Fillingthisvariableistheresponsibilityofthereceivecallback,whichisexecutedeverytimeamessagearrivesfromtheserver.onMessage::JSON!Client()onMessageresponse=dolet(nonce,result)=fromJSONresponse(n,m) getput(n,deletenoncem)putMVar(m!nonce)resultAswecansee,theimplementationofourprogrammingmodelisrathersimpleandrequiresnobothersomecompilermodicationsorlanguageextensions,andisthuseasilyportabletootherHaskellcompilers.4.TheHastecompilerInordertoallowthesamelanguagetobeusedonbothclientandserver,weneedsomewaytocompilethatlanguageintoJavaScript.Tothisend,wemakeuseoftheHastecompiler[11],startedasanMScthesisandcontinuedaspartofthiswork.HastebuildsontheGHCcompilertoprovidethefullHaskelllanguage,includingmostGHC-specicextensions,inthebrowser.AsHastehasnotbeenpublishedelsewhere,wedescribeheresomekeyelementsofitsdesignandimplementationwhicharepertinenttothiswork.4.1ChoosingacompilerHasteisbynomeanstheonlyJavaScript-targetingcompilerforapurelyfunctionallanguage.Inparticular,theGHC-basedGHCJS[17]andUHC[8]compilersarebothcapableofcompilingstandardHaskellintoJavaScript;theFay[10]languagewasdesignedfromthegrounduptotargetthewebspaceusingasubsetofHaskell;andthereexistsolutionsforcompilingErlang[13]andClean[9]toJavaScriptaswell.Whiletheaforementionedcompilersaretheonesmostinterestingforpurelyfunctionalprogramming,thereexistawealthofotherJavaScript-targetingcompilers,forvirtuallyanylanguage.Essentially,ourapproachisportabletoanylanguageorcompilerwiththefollowingproperties:Thelanguagemustprovideastatictypesystem,sinceoneofourprimaryconcernsistoreducedefectratesthroughstatictypingoftheclient-servercommunicationchannel.ThelanguagemustbecompilabletobothJavaScriptandaformatsuitableforserversideexecutionaswewantourwebapplicationstobewrittenandcompiledasasingleprogram.Wewantthelanguagetoprovidedecentsupportforamonadicprogrammingstyle,asourabstractionsforcooperativemul-titaskingandsynchronousclient-servercommunicationareneatlyexpressibleinthisstyle.Asseveraloftheaforementionedcompilersfulllthesecriteria,thechoicebetweenthembecomesalmostarbitrary.Indeed,asHaste.Appiscompileragnostic,thisdecisionboilsdowntoone'spersonalpreference.WechosetobaseoursolutiononHasteaswe,byvirtueofitsauthorship,haveanintimateknowledgeofitsinternalworkings,strengthsandweaknesses.Withoutdoubt,othersmayseemanyreasonstomakeadifferentchoice.4.2ImplementationoverviewHasteofoadsmuchoftheheavyliftingofcompilation-parsing,typechecking,intermediatecodegenerationandmanyoptimiza-tions-ontoGHC,andtakesovercodegenerationaftertheSTGgenerationstep,attheveryendofthecompilationprocess.STG[20]isthelastintermediaterepresentationusedbyGHCbeforethenalcodegenerationtakesplaceandhasseveralbenetsforuseasHaste'ssourcelanguage:STGisstillafunctionalintermediaterepresentation,basedonthelambdacalculus.WhengeneratingcodeforahighleveltargetlanguagesuchasJavaScript,wherefunctionsarerstclassobjects,thisallowsforahigherleveltranslationthanwhendoingtraditionalcompilationtolowerleveltargetslikestackmachinesorregistermachines.Thisinturnallowsustomakemoreefcientuseofthetargetlanguage'sruntime,leadingtosmaller,fastercode.IncontrasttoHaskellitselfandGHC'sintermediateCorelan-guage,STGrepresents`thunks`,theconstructusedbyGHCtoimplementnon-strictevaluation,asclosureswhichareexplic-itlycreatedandevaluated.Closuresaredecoratedwithawealthofinformation,suchastheirsetofcapturedvaribles,anytype informationneededforcodegeneration,andsoon.Whileex-tractingthisinformationmanuallyisnotveryhard,havingthisdoneforusmeanswecangetawaywithasimplercompilationpipeline.Thelanguageisverysmall,essentiallyonlycomprisinglambdaabstractionandapplication,plusprimitiveoperationsandfacil-itiesforcallingouttootherlanguages.Again,thisallowstheHastecompilertobeaverysimplethingindeed.AnyextensionstotheHaskelllanguageimplementedbyGHCwillalreadyhavebeentranslatedintothisverysimpleinter-mediateformat,allowingustosupportbasicallyanyextensionGHCsupportswithouteffort.Applicationofexternalfunctionsisalwayssaturated,asisap-plicationofmostotherfunctions.ThisallowsforcompilingmostfunctionapplicationsintosimpleJavaScriptfunctioncalls,limitingtheuseoftheslowerdynamictechniquesrequiredtohandlecurriedfunctionsinthegeneralcase[16]tocaseswhereitissimplynotpossibletostaticallydeterminethearityofafunction.InlightofitsheavyrelianceonSTG,itmaybemorecorrecttocategorizeHasteasanSTGcompilerratherthanaHaskellcompiler.4.3DatarepresentationTheruntimedatarepresentationofHasteprogramsiskeptasclosetoregularJavaScriptprogramsaspossible.ThenumerictypesarerepresentedusingtheJavaScriptNumbertype,whichisdenedastheIEEE754doubleprecisionoatingpointtype.Thisaddssomeoverheadtooperationsonintegersasoverowandnon-integerdivisionsmustbehandled.However,thisiscommonpracticeinhand-writtenJavaScriptaswell,andisgenerallyhandledefcientlybyJavaScriptengines.Valuesofnon-primitivedatatypesinHaskellconsistofadatacon-structorandzeroormorearguments.InHaste,thesevaluesarerep-resentedusingarrays,withtherstelementrepresentingthedataconstructorandthefollowingvaluesrepresentingitsarguments.Forinstance,thevalue42::Intisrepresentedas[0,42],theleading0representingthezerothconstructoroftheInttypeandthe42representingthe“machine”integer.Itmayseemstrangethatalimitedprecisionintegerisrepresentedusingonelevelofindirec-tionratherthanasasimplenumber,butrecallthattheInttypeisdenedbyGHCasdataInt=I#Int#whereInt#istheprimi-tivetypeformachineintegers.FunctionsarerepresentedasplainJavaScriptfunctions,oneoftheblessingsoftargetingahighlevellanguage,andapplicationcanthereforebeimplementedasitsJavaScriptcounterpartinmostcases.Inthegeneralcase,however,functionsmaybecurried.Forsuchcaseswherethearityofanappliedfunctioncannotbedeter-minedstatically,applicationisimplementedusingtheeval/applymethoddescribedin[16]instead.4.4InterfacingwithJavaScriptWhileHastesupportstheForeignFunctionInterfaceinheritedfromGHC,withitsusualfeaturesandlimitations[21],itisoftenim-practicaltoworkwithintheconnesofaninterfacedesignedforcommunicationonaverylowlevel.ForthisreasonHastesportsitsownmethodforinteractingwithJavaScriptaswell,whichallowstheprogrammertopassanyvaluebackandforthbetweenHaskell importHaste.Foreign--AMutableVariscompletelyopaquetoHaskellcode--andisonlyevermanipulatedinJavaScript.Thus,--weusetheUnpackedtypetorepresentit,--indicatingacompletelyopaquevalue.newtypeMutableVara=MVUnpackedinstanceMarshal(MutableVara)wherepack=MVunpack(MVx)=xnewMutable::Marshala)a!IO(MutableVara)newMutable=ffi"(function(x){return{val:x};})"setMutable::Marshala)MutableVara!a!IO()setMutable=ffi"(function(m,x){m.val=x;})"getMutable::Marshala)MutableVara!IOagetMutable=ffi"(function(m){returnm.val;})" Figure4:MutablevariableswithHaste.ForeignandJavaScript,aslongasshecancomeupwithawaytotrans-latethisvaluebetweenitsHaskellandJavaScriptrepresentations.Notperforminganytranslationatallisalsoavalid“translation”,whichallowsHaskellcodetostoreanyJavaScriptvalueforlaterretrievalwithoutinspectingitandviceversa.Theexamplegiveningure4implementsmutablevariablesusingthiscustomJavaScriptinterface.Thecoreofthisinterfaceconsistsoftheffifunction,whichal-lowstheprogrammertocreateaHaskellfunctionfromarbitraryJavaScriptcode.ThisfunctionexploitsJavaScript'sabilitytoparseandexecutearbitrarystringsatruntimeusingtheevalfunction,coupledwiththefactthatfunctionsinHasteandinJavaScriptsharethesamerepresentation,todynamicallycreateafunctionob-jectatruntime.TheffifunctionistypedusingthesamemethodasthemkRemotefunctiondescribedinsection3.WhenappliedtooneormoreargumentsinstantiatingtheMarshaltypeclass,thepackfunctionisappliedtoeachargument,marshallingthemintotheirrespectiveJavaScriptrepresentations,beforetheyarepassedtothedynamicallycreatedfunction.Whenthatfunctionreturns,theinverseunpackfunctionisappliedtoitsreturnvaluebeforeitispassedbackintotheHaskellworld.Asthemarshallingfunctionschosenforeachargumentandthefor-eignfunction'sreturnvaluedependsonitstype,theprogrammermustexplicitlyspecifythetypeofeachfunctionimportedusingffi;inthis,Haste'scustommethodisnodifferentfromthecon-ventionalFFI.Thereareseveralbenetstothismethod,themostprominentbeingthatnewmarshallabletypescanbeaddedbysimplyinstantiatingatypeclass.ThankstothelazyevaluationemployedbyHaste,eachforeignfunctionobjectisonlycreatedonceandthencached;anyfurthercallstothesame(Haskell)functionwillreusethecachedfunctionobject.Implementation-wise,thismethodisalsoverynon-intrusive,requiringonlytheuseofthenormalFFItoimportJavaScript'sevalfunction;nomodicationofthecompilerisneeded. 5.Discussionandrelatedwork5.1RelatedworkSeveralotherapproachestoseamlessclient-serverinteractionex-ist.Ingeneral,theseproposedsolutionstendtobeofthe“allornothing”variety,introducingnewlanguagesorotherwiserequiringcustomfullstacksolutions.Incontrast,oursolutioncanbeimple-mentedentirelyasalibraryandisportabletoanypairofcompilerssupportingtypedmonadicprogramming.Moreover,Haste.Apphasaquitesimpleandcontrolledprogrammingmodelwithaclearlydenedcontroller,whichstandsincontrasttomostrelatedworkwhichembracesamoreexiblebutalsomorecomplexprogram-mingmodel.Themorenotableapproachestotheproblemarediscussedfurtherinthissection.ConductanceandOpaConductance[6]isanapplicationserverbuiltonStratiedJS,aJavaScriptlanguageextensionwhichaddsafewnicetiessuchascooperativemultitaskingandmoreconcisesyntaxformanycommontasks.ConductanceusesanRPC-basedmodelforclient-servercommunication,muchlikeourown,butalsoaddsthepossibilityfortheservertoindependentlytransmitdatabacktotheclientthroughtheuseofsharedvariablesorcallbackintotheclientbywayoffunctionobjectsreceivedviaRPCcall,aswellasthepossibilityforbothclientandservertoseam-lesslymodifyvariableslocatedontheoppositeendofthenetwork.Conductanceisquitenewandhasnorelevantpublications.Itis,however,usedforseverallargescalewebapplications.WhileConductancegetsridofthecallback-basedprogrammingmodelendemictoregularJavaScript,itstillsuffersfrommanyofitsusualdrawbacks.Inparticular,theweaktypingofJavaScriptposesaprobleminthattheprogrammerisinnowayreprimandedbyhertoolsforusingserverAPIsincorrectlyortryingtotransmitvalueswhichcannotbesensiblyserializedandde-serialized,suchasDOMnodes.Wronglytypedprogramswillthuscrash,orevenworse,gleefullykeeprunningwitherroneousstateduetoimplicittypeconversions,ratherthangivetheprogrammersomeadvancewarningthatsomethingisamiss.Wearealsonotcompletelyconvincedthattheabilitytoimplicitlypassdatabackandforthoverthenetworkisaunilaterallygoodthing;whilethisindeedprovidestheprogrammersomeextracon-venience,italsorequirestheprogrammertoexerciseextracautiontoavoidinadvertentlysendinglargeamountsofdataoverthenet-workorleaksensitiveinformation.TheOpaframework[18],anotherJavaScriptframework,isanim-provementoverConductancebyintroducingnon-mandatorytypecheckingtotheJavaScriptworld.Itscommunicationmodelisbasedonimplicitinformationows,allowingtheservertoreadandupdatemutablestateontheclientandviceversa.Whilethisisaquiteexibleprogrammingmodel,webelievethatthisuncon-trolled,implicitinformationowmakesprogramshardertofollow,debug,secureandoptimize.GoogleWebToolkitGoogleWebToolkit[26],aJavacompilertargetingthebrowser,providesitsownsolutiontoclient-serverin-teroperabilityaswell.Thissolutionisbasedoncallbacks,forcingdeveloperstowritecodeinacontinuationpassingstyle.Italsosuf-fersfromexcessiveboilerplatecodeandanerrorpronecongu-rationprocess.TheprogrammingmodelsharesHaste.App'sclientcentricity,relegatingtheservertoservingclientrequests.DuettoDuetto[22]isaC++compilertargetingtheweb,writtenfromthegrounduptoproducecodeforbothclientandserversimultaneously.ItutilizesthenewattributesmechanismintroducedinC++11[24]todesignatefunctionsanddatatoliveoneitherclientorserverside.Anycallstoafunctionontheothersideofthenetworkandattemptstoaccessremotedataareimplicit,requiringnoextraannotationsorscaffoldingatthecallsite.Duettoisstillahighlyexperimentalproject,itsrstreleasebeingonlyafewmonthsold,andhasnotbeenpublishedinanyacademicvenue.LikeConductance,Duettosufferssomewhatfromitsheritage:whiletheclientsidecodeisnotmemory-unsafe,asitisnotpos-sibletogeneratememory-unsafeJavaScriptcode,itsserversidecounterpartunfortunatelyis.OurreservationsexpressedabouthownetworkcommunicationinDuettocanbeinitiatedimplicitlyapplytoDuettoaswell.SunroofIncontrasttoConductanceandDuetto,Sunroof[2]isanembeddedlanguage.ImplementedasaHaskelllibrary,itallowstheprogrammertouseHaskelltowritecodewhichiscompiledtoJavaScriptandexecutedontheclient.ThelanguagecanbestbedescribedashavingJavaScriptsemanticswithHaskell'stypesystem.Communicationbetweenclientandserverisaccomplishedthroughtheuseof“downlinks”and“uplinks”,allowingfordatatobesenttoandfromtheclientrespectively.Sunroofiscompletelytype-safe,intheDSLitselfaswellasinthecommunicationwiththeHaskellhost.However,thefactthatclientandservermustbewrittenintwoseparatelanguages-anycodeusedtogenerateJavaScriptmustbebuiltsolelyfromtheprimitivesoftheSunrooflanguageinordertobecompilableintoJavaScript,precludinguseofgeneralHaskellcode-makescodereusehard.AstheJavaScriptDSLisexecutedfromanativeHaskellhost,Sunroof'sprogrammingmodelcanbesaidtobesomewhatservercentric,butwithquitesomeexibilityduetoitsbackandforthcommunicationmodel.OcsigenOcsigen[1]enablesthedevelopmentofclient-serverwebapplicationsusingO'Caml.MuchlikeOpa,itaccomplishestyped,seamlesscommunicationbyexposingmutablevariablesacrossthenetwork,givingitmanyofthesamedrawbacksandbenets.WhileOcsigenisafullstacksolution,denyingthedevel-opersomeexibilityinchoosingtheirtools,itshouldbenotedthatsaidstackisrathercomprehensiveandwelltested.AFAXAFAX[19],anF#-basedsolution,takesanapproachquitesimilartoours,usingmonadstoallowclientandserversidetocoexistinthesameprogram.Unfortunately,usingF#asthebaseofsuchasolutionraisestheissueofsideeffects.SinceanyexpressioninF#maybesideeffecting,itisquitepossiblewithAFAXtoperformasideeffectontheclientandthenattempttoperformsomeactionbasedonthissideeffectontheserver.Tocopewiththis,AFAXneedstointroducecumbersomeextensionstotheF#typesystem,makingAFAXexclusivetoMicrosoft'sF#compilerandoperatingsystem,whereasoursolutionisportabletoanypairofHaskellcompilers.HOP,Links,Ur/WebandothersInadditiontosolutionswhichworkwithinexistinglanguages,thereareseverallanguagesspecif-icallycraftedtargetingthewebdomain.Theselanguagestargetnotonlytheclientandservertiersbutthedatabasetieraswell,andincorporateseveralinterestingnewideassuchasmoreexpressivetypesystemsandinclusionoftypedinlineXMLcode.[23][5][3]Asoursolutionaimstobringtyped,seamlesscommunicationintotheexistingHaskellecosystemwithoutlanguagemodications,theselanguagessolveadifferentsetofproblems. AdvantagesofourapproachWebelievethatourapproachhasanumberofdistinctadvantagestotheaforementionedattacksontheproblem.Ourapproachgivestheprogrammeraccesstothesamestronglytyped,general-purposefunctionallanguageonbothclientandserver;anycodewhichmaybeofusetobothclientandserveriseffortlesslyshared,leadingtolessduplicationofcodeandin-creasedpossibilitiesforreusingthirdpartylibraries.Interactivemultiplayergamesareonetypeofapplicationwherethiscodesharingmayhavealargeimpact.Inordertoensurethatplayersarenotcheating,agameservermustkeeptrackoftheentiregamestateandsendupdatestoclientsatregularintervals.However,duetonetworklatency,waitingforserverinputbeforerenderingeachandeveryframeiscompletelyimpractical.Instead,theusualapproachistohaveeachclientcontinuouslycomputethestateofthegametothebestofitsknowledge,rectifyinganydivergencefromthegame's“ofcial”statewheneveranupdatearrivesfromtheserver.Inthisscenario,itiseasytoseehowreusingmuchofthesamegamelogicbetweentheclientandtheserverwouldbeveryimportant.AnyandallcommunicationbetweenclientandserverisbothstronglytypedandmadeexplicitbytheuseoftheonServerfunc-tion,withtheprogrammerhavingcompletecontroloverthese-rializationandde-serializationofdatausingtheappropriatetypeclasses.Asidefromtheobviousadvantagesoftypesafety,makingthecrossingofthenetworkboundaryexplicitaidstheprogram-merinmakinganinformeddecisionastowhenandwhereservercommunicationisappropriate,aswellashelpspreventsaccidentaltransmissionofsensitiveinformationintendedtostayoneithersideofthenetwork.Ourprogrammingmodelisimplementedasalibrary,assumingonlytwoHaskellcompilers,onetargetingJavaScriptandonetar-getingtheprogrammer'sserverplatformofchoice.WhileweuseHasteasourJavaScript-targetingcompiler,modifyingourimple-mentationtouseGHCJSoreventheJavaScriptbackendofUHCwouldbetrivial.Thisimplementationnotonlyallowsforgreaterexibility,butalsoeliminatestheneedtotanglewithcomplexcom-pilerinternals.InspirationandalternativestoremoteOnecrucialaspectofimplementingcross-networkfunctioncallsistheissueofdatarepresentation:theclientsideofthingsmustbeabletoobtainsomerepresentationofanyfunctionitmaywanttocallontheserver.Inoursolution,thisrepresentationisobtainedthroughtheuseoftheremotefunction,whichwhenexecutedontheserverpairsafunctionwithauniqueidentier,andwhenexecutedontheclientreturnssaididentiersothattheclientmaynowrefertothefunc-tion.Whilethishastheadvantageofbeingsimpletoimplement,onemajordrawbackofthismethodisthatallfunctionsmustbeexplicitlyimportedintheAppmonadpriortobeingcalledoverthenetwork.ThisapproachwasinspiredbyCloudHaskell[12],whichintro-ducesthenotionof“staticvalues”;valueswhichareknownatcom-piletime.Codifyingthisconceptinthetypesystem,toenableittobeusedasabasisforremoteprocedurecalls,unfortunatelyrequiressomemajorchangestothecompiler.CloudHaskellhasastopgapmeasureforunmodiedcompilerswhereinaremotetable,pairingvalueswithuniqueidentiers,iskept.Thisexplicitbookkeepingreliesontheprogrammertoassignappropriatetypestobothvaluesthemselvesandtheiridentiers,breakingtypesafety.Theastutereadermaynoticethatthisisexactlywhattheremotefunctiondoesaswell,thedifferencebeingthatremotelinkstheidentiertothevalueitrepresentsonthetypelevel,makingitimpossibletocallnon-existentremotefunctionsandbreaktheprogram'stypesafetyinotherways.Anotherapproachtothisproblemisdefunctionalization[7],apro-gramtransformationwhereinfunctionsaretranslatedintoalgebraicdatatypes.Thisapproachwouldallowtheclientandservertousethesameactualcode;ratherthanpassinganidentieraround,theclientwouldinsteadpasstheactualdefunctionalizedcodetotheserverforexecution.Thiswouldhavetheaddedbenetofallow-ingfunctionstobearbitrarilycomposedbeforebeingremotelyin-voked.Thisapproachalsorequiressignicantchangestothecompiler,makingitunsuitableforourusecase.Moreover,wearenotentirelyconvincedaboutthewisdomofallowingserversideexecutionofwhatisessentiallyarbitrarycodesentfromtheclientwhich,inawebapplicationcontext,iscompletelyuntrustworthy.Whileana-lyzingcodeforimproperbehavioriscertainlypossible,designingandenforcingasecuritypolicysufcientlystricttoensurecorrectbehaviorwhileexibleenoughtobepracticallyusefulwouldbeanunwelcomeburdenontheprogrammer.5.2LimitationsClient-centricityUnlikemostrelatedwork,ourapproachtakesarmstand,regardingtheclientasthedriverintheclient-serverrelationshipwiththeservertakingontheroleofapassivecom-putationalorstorageresource.Theservermaythusnotcallbackintotheclientatarbitrarypointsbutisinsteadlimitedtoreturninganswerstoclientsidequeries.Thisisclearlylessexiblethantheback-and-forthmodelofSunroofandDuettoorthesharedvari-ablesofConductance.However,webelievethatthisrestrictionmakesprogramoweasiertofollowandcomprehend.LiketheimmutabilityofHaskell,thismodelgivesprogrammersanot-so-subtlehintastohowtheymaywanttostructuretheirprograms.ExtendingourexistingmodelwithanonClientcounterparttoonServerwouldbeasimpletask,butwearenotquiteconvincedthatthereisvalueindoingso.EnvironmentconsistencyAsourprogrammingmodelusestwodifferentcompilerstogenerateclientandservercode,itiscrucialtokeepthepackageenvironmentsofthetwoinsync.Asituationwhere,forinstance,amoduleisvisibletoonecompilerbutnottotheotherwillrendermanyprogramsuncompilableuntilthisinconsistencyisxed.Thiskindofdivergencecanbeworkedaroundusingconditionalcompilation,butishighlyproblematicevenso;usingauniedpackagedatabasebetweenthetwocompilers,whileproblematicduetothedifferingnaturesofnativeandJavaScriptcompilationrespectively,wouldbeasignicantimprovementinthisarea.6.FutureworkInformationowcontrolWebapplicationsoftenmakeuseofawiderangeofthirdpartycodeforusertracking,advertising,col-lecitionofstatisticsandawiderangeofothertasks.Anypieceofcodeexecutinginthecontextofaparticularwebsessionmaynotonlyinteractwithanyotherpieceofcodeexecutinginthesamecontext,butmayalsoperformbasicallylimitlesscommunicationwiththirdpartiesandmaythus,inadvertentlyornot,leakinforma-tionabouttheapplicationstate.Thisisofcoursehighlyundesirable formanyapplications,whichiswhythereisongoingworkincon-trollingtheinformationowwithinwebapplications[14].Whilethisdoesindeedprovideaneffectivedefencetowardsattack-ersandprogrammingmistakesalike,thereisvalueinbeingabletotellthetwoapart,aswellasincatchingpolicyviolationsresultingfromprogrammingmistakesasearlyaspossible.Aninterestingvenueofresearchwouldbetoinvestigatewhetherwecantakead-vantageofourstrongtypingtogeneratesecuritypoliciesforsuchaninformationowcontrolscheme,aswellasensurethatthispol-icyisnotviolatedatcompiletime.Thiscouldshortendevelopmentcyclesaswellasgiveareasonablelevelofcondencethatanyruntimepolicyviolationisindeedanattemptedattack.RealworldapplicationsAsHaste.Appisquitenewandexperi-mental,ithasyettobeusedinthecreationoflargescaleapplica-tions.Whilewehaveusedittoimplementsomesmallapplications,suchasaspacedrepetitionvocabularylearningprogramandamorefeaturefulvariantonthechatboxexamplegiveninsection2.3,fur-therinvestigationofitssuitabilityforlargerrealworldapplicationsthroughthedevelopmentofseverallargerscaleexamplesisanim-portantareaoffuturework.7.ConclusionWehavepresentedaprogrammingmodelwhichimprovesonthecurrentstateoftheartinclient-serverwebapplicationdevelop-ment.Inparticular,oursolutioncombinestypesafecommunicationbetweentheclientandtheserverwithfunctionalsemantics,cleardemarcationsastowhendataistransmittedandwhereaparticularpieceofcodeisexecuted,andtheabilitytoeffortlesslysharecodebetweentheclientandtheserver.Ourmodelisclient-centric,inthattheclientdrivestheapplicationwhiletheservertakesontheroleofpassivelyservingclientre-quests,andisbasedonasimpleblockingconcurrencymodelratherthanexplicitcontinuations.ItiswellsuitedforusewithaGUIpro-grammingstylebasedonself-containedprocesseswithlocalstate,andrequiresnomodicationofexistingtoolsorcompilers,beingimplementedcompletelyasalibrary.AcknowledgmentsThisworkhasbeenpartiallyfundedbytheSwedishFoundationforStrategicResearch,undergrantRAWFP.References[1]V.Balat.”Ocsigen:typingwebinteractionwithobjectiveCaml.”Proceedingsofthe2006workshoponML.ACM,2006.[2]J.BrackerandA.Gill.”Sunroof:AMonadicDSLforGeneratingJavaScript.”InPracticalAspectsofDeclarativeLanguages,pp.65-80.SpringerInternationalPublishing,2014.[3]A.Chlipala.”Ur:statically-typedmetaprogrammingwithtype-levelrecordcomputation.”ACMSigplanNotices.Vol.45.No.6.ACM,2010.[4]K.Claessen.”FunctionalPearls:Apoorman'sconcurrencymonad.”JournalofFunctionalProgramming9(1999):313-324.[5]E.Cooper,S.Lindley,P.Wadler,andJ.Yallop.Links:Webprogram-mingwithouttiers.InFormalMethodsforComponentsandObjects(pp.266-296).SpringerBerlinHeidelberg,2007.[6]TheConductanceapplicationserver.RetrievedMarch1,2014,fromhttp://conductance.io.[7]O.DanvyandL.R.Nielsen.”Defunctionalizationatwork.”InProceedingsofthe3rdACMSIGPLANinternationalconferenceonPrinciplesandpracticeofdeclarativeprogramming,pp.162-174.ACM,2001.[8]A.Dijkstra,J.Stutterheim,A.Vermeulen,andS.D.Swierstra.”BuildingJavaScriptapplicationswithHaskell.”InImplementationandApplicationofFunctionalLanguages,pp.37-52.SpringerBerlinHeidelberg,2013.[9]L.Domoszlai,E.Bru¨el,andJ.M.Jansen.”Implementinganon-strictpurelyfunctionallanguageinJavaScript.”ActaUniversitatisSapientiae3(2011):76-98.[10]C.Done.(2012,September15).“Fay,JavaScript,etc.”,RetrievedMarch1,2014,fromhttp://chrisdone.com/posts/fay.[11]A.Ekblad.”Towardsadeclarativeweb.”MasterofScienceThesis,UniversityofGothenburg(2012).[12]J.Epstein,A.P.Black,andS.Peyton-Jones.”TowardsHaskellinthecloud.”InACMSIGPLANNotices,vol.46,no.12,pp.118-129.ACM,2011.[13]G.Guthrie.(2014,January1).”YourtranspilertoJavaScripttoolbox”.RetrievedMarch1,2014,fromhttp://luvv.ie/2014/01/21/your-transpiler-to-javascript-toolbox/.[14]D.Hedin,A.Birgisson,L.Bello,andA.Sabelfeld.”JSFlow:TrackinginformationowinJavaScriptanditsAPIs.”InProc.29thACMSymposiumonAppliedComputing.2014.[15]P.LubbersandF.Greco.”Html5websockets:Aquantumleapinscalabilityfortheweb.”SOAWorldMagazine(2010).[16]S.Marlow,andS.PeytonJones.”Makingafastcurry:push/entervs.eval/applyforhigher-orderlanguages.”InACMSIGPLANNotices,vol.39,no.9,pp.4-15.ACM,2004.[17]V.Nazarov.”GHCJSHaskelltoJavaScriptCompiler”.RetrievedMarch1,2014,fromhttps://github.com/ghcjs/ghcjs.[18]TheOpaframeworkforJavaScript.RetrievedMay2,2014,fromhttp://opalang.org.[19]T.Petricek,andDonSyme.”AFAX:Richclient/serverwebapplica-tionsinF#.”(2007).[20]S.PeytonJones.”Implementinglazyfunctionallanguagesonstockhardware:theSpinelessTaglessG-machine.”J.Funct.Program.2,no.2(1992):127-202.[21]S.PeytonJones.”Tacklingtheawkwardsquad:monadicinput/output,concurrency,exceptions,andforeign-languagecallsinHaskell.”Engineeringtheoriesofsoftwareconstruction180(2001):47-96.[22]A.Pignotti.(2013,October31).”Duetto:aC++compilerfortheWebgoingbeyondemscriptenandnode.js”.RetrievedMarch1,2014,fromhttp://leaningtech.com/duetto/blog/2013/10/31/Duetto-Released/.[23]M.Serrano,E.Gallesio,andF.Loitsch.”Hop:alanguageforprogrammingtheweb2.0.”OOPSLACompanion.2006.[24]B.Stroustrup.(2014,January21).”C++11-thenewISOC++standard.”RetrievedMarch1,2014,fromhttp://www.stroustrup.com/C++11FAQ.html.[25]C.Taylor.(2013,March1).”PolyvariadicFunctionsandPrintf”.RetrievedMarch1,2014,fromhttp://chris-taylor.github.io/blog/2013/03/01/how-haskell-printf-works/.[26]S.Wargolet.”GoogleWebToolkit.Technicalreport12.”UniversityofWisconsin-PlattervilleDepartmentofComputerScienceandSoftwareEngineering,2011.