HaskellServerPagesOld.pdf

(165 KB) Pobierz
355477802 UNPDF
1
HaskellServerPages
FunctionalProgrammingandtheBattlefortheMiddleTier
ErikMeijer a andDannyvanVelzen b
a mailto:emeijer@microsoft.com
b mailto:danny@shopmontages.nl
HaskellServerPages(HSP)provideaneasywaytocreatedynamicwebpagesandsimplifythetaskofbuilding
middletiercomponents.ThisarticlegivesanoverviewofHSPfromaprogrammer’sperspective.Itincludes
examplesofHSPinactionandgivesaprecisedescriptionoftranslatingHSPscriptsintoplainHaskell.
1.Overview
•Distributedtransactionmanagement.
Overthenextfewyears,virtuallyeverymajor
applicationwillbecompletelyweb-based,orata
minimumhaveawebfrontend.Suchdistributed
applicationsareoftenstructuredusingathree-
tiermodel,whichconsistsof:
•Securityservicestocontrolobjectcreation
anduse.
•Managementandpoolingofprocessesand
threads,objectinstances,databaseconnec-
tions,andotherresources.
•User-ServicesTier:Thefront-endclient
thatcommunicateswiththeuserthrough
someuserinterface,egtextual,graphical,
telephone-orvoice-driven.
InternetcompaniessuchaseBay,Amazon,
BarnesandNoble,andAOLmusthavetheirbusi-
nessupandrunning24hoursaday,365daysa
year.ForinstancewhentheeBaysitewentdown
for48hoursrecently,theylostoverfivemillion
dollars.
Viewedinthislightitisremarkablethatmiddle
tiercomponentsarewrittenusingweaklytyped
languagessuchasVisualBasic[28],JavaScript[4]
orPerl[13].Suchlanguagesprovidenoguaran-
teesthatprogramsdon’tcrashorgiveincorrect
answers.Serverredundancy,processprotection
etc.arejustband-aidmeasuresthatdon’tsolve
therealproblem.
Ourresearchprogramistargetedatproviding
languages,toolsandlibrariesforfastandsafe
constructionofmiddletiercomponents.Tocom-
municatebetweenthemiddletierandthedata
accesslayerwehavedevelopedHaskellDB[15].
Tomakeeectiveuseofthemiddletierruntime
wehaveaddedsupportforaccessingclassicCOM
•Business-ServicesTier:Acollectionof
softwarecomponentsthatencodebusiness
logic,andprocesstheinformationflowbe-
tweentheuser-anddata-servicestiers.
•Data-ServicesTier:Theback-enddatabase
serverthatstoresbusinessdata.
Fromanapplicationprogrammer’spointofview
alltheactionisinencodingthebusinesslogicand
providingthegluebetweentheuser-servicestier
andthedata-servicestier.
Thebusiness-servicesormiddletierisusually
builtfromsoftwarecomponentsthatliveinaspe-
cialruntimeenvironment(suchasCOM+,EJB,
orCorbaComponentServices)[29]thatprovides
servicesfor:
2
[14]andJava[22]toHaskell,andwearecur-
rentlybuildinganewscriptinglanguagecalled
Mondrian[25]andanewbackendforGHCthat
compilestoJavaandthenewMicrosoft.NET
runtime.
Tocommunicatebetweenthepresentationlayer
andthemiddletierwehaveimplemented
HaskellScript[23]forwritingclient-sideDHTML
scriptsandHaskellCGI[21],alibraryforwriting
server-sideCGIscripts.ExperiencewiththeCGI
libraryhowever,showedthatembeddingHTML
orXMLfragmentsusingcombinatorsinHaskell
isratherawkward.Thereasonisthatdocuments
oftencontainmoreplaintextthanmarkupel-
ements.WritinglongstringliteralsinHaskell
usingquotesandliteralgaps 1 isnotthemost
convenientwaytodenotestringcontentinXML
fragments.
InthispaperwepresentHaskellServerPages
(HSP)asanewwaytogeneratedynamiccontent
usingHaskell.Themostimportantcontributions
ofHSParethat
creteXMLsyntax,PCDATAstringsneed
notbequoted.Thissimplifiestheconstruc-
tionoflargedocuments.
•Haskellvaluescanberecursivelyembedded
insideXMLfragments:Wecanescapefrom
theXMLlevelbacktoHaskellandembed
anyHaskellthatisaninstanceoftheclass
IsChild (orforattribute IsValue ).Since
IO isaninstanceoftheseclasses,itiseven
possibletoembedcommandsinsidedocu-
ments.
•HSPiseasilytranslatedintopureHaskell:
Asweshowinthispaper,HSPcanbe
implementedasasimplepreprocessorto
Haskell.Theamountofsyntacticsugaris
comparabletothatofthe do -notationor
list-comprehensions,andisdefinedbyjust
ahandfulofrules.
Apopularroutetoimplementingdomain-specific
languagesisbyembeddingintoHaskell[10],and
HSPisnoexception.However,anecessarycon-
ditionforthistoworkisthatallthefeaturesof
thedomain-specificlanguagecanbemappedtoa
correspondingfeatureofHaskell.Inthecaseof
HSP,Haskellfallsshortintwoareas[24,31]:
•XMLfragmentsarefirstclassvalues:XML
fragmentshavethesamestatusasordinary
Haskellexpressions,sowecanputthemin
lists,passthemasargumentstoandre-
turnthemasresultsfromfunctions,etc.
Thisallowsmanycommondocumentpro-
cessingpatternstobecapturedinsmall
highlyreusablelibraries[11].
•Properpattern-matchingonXMLfrag-
mentsrequirestheuseofaGlushkovau-
tomatontodirectthematchingofregular
expressions[31].Becausewearepiggyback-
ingonHaskell’smoreprimitivepattern-
matchingmechanisms,weareforcedtoin-
troducesomeoverspecificationincertain
places.
•XMLfragmentscanbepattern-matched:
ConstructingXMLfragmentsisjustone
sideofthecoin. Inmanycasesweneed
totransformoneXMLdocumentintoan-
other.Beingabletodothisinahigher-
order,polymorphicfunctionallanguageis
muchmoreconvenientthanusingseparate
languagessuchasXSL[35]orframeworks
liketheDocumentObjectModel(DOM)
[6].
•GuaranteeingvalidityofXMLdocuments
againsttheirDTDsrequiresasophisticated
typesystemthatsupportstypeindexedrows
[31].HSPdoesguaranteewell-formedness
ofXMLfragments,butunfortunatelythe
typesystemneededforvalidatingXML
cannotbesimulatedinHaskell.
•PCDATAfragmentsneednotbequoted:
SincewewriteXMLfragmentsusingcon-
1 AlittleknowfeatureoftheHaskelllanguage,formedby
twobackslashesenclosingwhitespace.Literalgapsallow
longstringstobespreadacrossdierentlines.
Evenwell-formednessandsimplepattern-
matchingondocumentsaloneisalreadyamuch
3
strongerpropertythanmostothercompetinglan-
guagescanoer,buttherearemanyoccasions
wherewedowanttomatchandtypearbitrary
XML.Forthiswearedevelopinganewlanguage
XMLambda[24]whichhasXMLdocumentsas
itsbasicdatatypes.
Inthemeantime,HSPremainsanexcellentex-
ampleoftheParetoprinciple 2 ;weget80percent
ofthefunctionalityofXMLambdafor20percent
ofthecost.
Intherestofthispaperwewillfirstgivean
overviewofthecurrentstateofaairsingenerat-
ingdocumentsinthemiddletier(section2)and
explainwhytheyfallshort.Nextwegiveanin-
formalintroductiontoHSP(section3)andshow
indetailhowHSPscriptscanbetranslatedinto
pureHaskell(section4).Weendthepaperbyde-
scribinghowHSPapplicationsareintegratedinto
themiddletierruntimeenvironment(section5).
JSP(JavaServerPages)[26],PSP(Python
ServerPages)[1],PHP(PHP:HypertextPrepro-
cessor)[17],XSP(ExtensibleServerPages)[20],
andASP(ActiveServerPages)[9].Thelatteris
quiteinterestingasitisalanguageindependent
framework.Anyscriptinglanguagethatsupports
theActiveXScriptingArchitecturecanbeusedto
writeASPscripts[16,3].
Hereistheinevitable“HelloWorld”exam-
plewrittenasaserverpageinVisualBa-
sic. The Response.Write"HelloWorld!"
statementwritesthestring "HelloWorld" on
the Response outputstreamthatissenttothe
client:
<HTML>
<HEAD>
<TITLE>Example</TITLE>
</HEAD>
<BODY>
<%Response.Write"HelloWorld!"%>
</BODY>
</HTML>
2.Web-basedapplications
Inmost3-tierapplicationstheworkofthemid-
dletierisusuallysplitrecursivelyintothreetiers
again.Clientapplicationsruninsideabrowser
andsubmitrequeststoawebserverusingHTTP.
The‘presentationlayer’ontheservertransforms
therequestandpassesitontothe‘businesslayer’
whichwillperformsomecomputationbyinter-
actingwiththe‘datalayer’.Theresultsfromthe
‘businesslayer’arethentransformedintoHTML
orXMLbythe‘presentationlayer’andreturned
astheresponsetotheclient.
Sometimes <%= e %> isusedasanabbreviationfor
<%Response.Write e %> .Thechoiceofprimi-
tivefunctionsandthetagsthatdelimitcodedier
forthevariousflavorsofserverpages.Forexam-
plePHPuses echo insteadof Response.Write ,
and <?php and ?> astagsbutalsosupports <%
and %> .
Serverpagesaretypicallyimplementedusinga
processcalledpagecompilation,whichtransforms
ahybridHTML/scriptpageintoasinglescript
thatwillgeneratetherequiredHTML.Forin-
stance,theexampleabovewouldbetranslated
intoascriptthatwriteseachlineoftheoriginal
serverpagetothe Response stream:
2.1.ServerPages
ThemostpopularwayofgeneratingHTML(or
XML)responsesinthemiddletierisbyusing
socalledserverpages.Aserverpageisaspe-
cialHTMLpagethatcontainsembeddedscripts.
Serverpagesexistformanylanguages,suchas
Response.Write"<HTML>"
Response.Write"<HEAD>"
Response.Write"<TITLE>Example</TITLE>"
Response.Write"</HEAD>"
Response.Write"<BODY>"
Response.Write"HelloWorld!"
Response.Write"</BODY>"
Response.Write"</HTML>"
2 Dr.JosephJuran(oftotalqualitymanagementfame)
formulatedtheParetoPrincipleafterexpandingonthe
workofWilfredoPareto,anineteenthcenturyeconomist
andsociologist. Itisashorthandnameforthephe-
nomenonthatinanypopulationwhichcontributestoa
commoneect,arelativefewofthecontributorsaccount
forthebulkoftheeect
4
Itisimportanttonotethatthetranslationisnot
appliedrecursivelyinsidecodefragments.
Thissimplesemanticscanmakeserverpages
ratherconfusing,especiallyifcontrolstructures
areusedtogenerateHTML.Asthenextexample
shows,codefragmentsembeddedinside <% and %>
neednotbesyntacticallycompletephrasesthem-
selves:
notmakeHTMLfragmentsintofirstclasscit-
izens.HencetheybreakTennent’sprincipleof
abstraction[32,27]thatsaysthatvaluesofasyn-
tacticallyrelevantdomaincanbegivenaname.
Anabstractionmechanismthatdoesnotsatisfy
thisbasicprincipleisratheruseless!
Asanexampleserverpagethatshowsthelackof
abstraction,wewillgenerateanHTMLtableof
16x16cells,wherethebackgroundcolorofeach
cellisdeterminedbythecell’scoordinatesviathe
(unspecified)function Color .
TheASPpagecontainstwonestedloops,the
outeronegeneratesthetablerowsandtheinner
generatesthecells:
<HTML>
<HEAD>
<TITLE>Example</TITLE>
</HEAD>
<BODY>
<%IfDomain="nl"%>
HalloWereld!
<%Else%>
HelloWorld!
<%EndIf%>
</BODY>
</HTML>
<TABLEborder="1">
<%Forx=1To16%>
<TR>
<%Fory=1To16%>
<TDbgcolor=<%=Color(x,y)%>>
(<%=x%>,<%=y%>)
</TD>
<%Next%>
</TR>
<%Next%>
</TABLE>
Serverpagesforceyoutothinkbackwardsfrom
thefullyexplicitgeneratedcodetosomelevelof
HTMLmixedwithscripttomakesurethatthe
generatedcodeissyntacticallycorrect:
Response.Write"<HTML>"
Response.Write"<HEAD>"
Response.Write"<TITLE>Example</TITLE>"
Response.Write"</HEAD>"
Response.Write"<BODY>"
IfDomain="nl"
Response.Write"HalloWereld!"
Else
Response.Write"HelloWorld!"
EndIf
Response.Write"<BODY>"
Response.Write"</HTML>"
Notethatitispossibletousescriptinsideat-
tributesaswell.
Supposewewanttoliftouttheinnerloopinto
aseparateprocedure GenData tomakethepage
moreorderly.
<TABLEborder="1">
<%Forx=1To16%>
<TR>
<%CallGenData(x)%>
</TR>
<%Next%>
</TABLE>
2.2.ServerPagesbreaktheprincipleof
Abstraction
Thesemanticsofserverpagesisnotcomposi-
tional,thatis,tounderstandwhataserverpage
means,weneedtodoacompletepagetransla-
tionandinspecttheresultingcode.Naiveserver
pagesprovidejustaverythinlayerofveneerthat
hidesafewcallsto Response.Write ,buttheydo
Todoso,wecannotmerelycopyandpastethe
innerloopintothebodyofthe GenData proce-
dure.Wehavetokeepinmindthatweareinside
anASPpageandenclosetheprocedureheader
andfooterinside <% and %> braces.
<%SubGenData(x)%>
5
<%Fory=1To16%>
<TDbgcolor=<%=Color(x,y)%>>
(<%=x%>,<%=y%>)
</TD>
<%Next%>
<%EndSub%>
3.InformalintroductiontoHaskellServer
Pages
ThemainideaofHaskellServerPagesistotreat
HTML(orinfactXML)fragmentsasordinary
expressions.InsideHTMLfragments,stringsare
notescaped,soweneedtoescapecodefragments
instead.Forthiswereusethe <% and %> tags.In-
sideembeddedexpressionswecanofcourseagain
introduceHTMLfragments,andinsidethosewe
canagainembednormalexpressionsbyescaping
theminside <% and %> ,etc.etc.Themeaning
ofHSPscriptsiscompositional,andthuseasyto
understand.Justreplacetheexpressionbetween
the <% and %> byitsvalue.
Attributevaluesneedtobesurroundedbydouble
quotesalready,hencewecanallowanyatomic
expressiontooccurinanattributevalueposition
withouttheneedforanescapemechanism.
ThefollowingHSPcodegeneratesthesame16x16
tableastheASPcodewehaveseenabove(the
types TABLE , TR and TD areallsynonymsfor
Element ):
Thedownsideofthisisthatwecannottakethis
fragmentoutoftheASPpageandreuseitinside
anordinaryVisualBasicmodule.InsideVisual
Basic,theonlywaytoproduceHTMLisbyusing
Response.Write towritetheHTMLasastring.
Hencetotrulyabstracttheinnerloop,wemust
firstmanuallyapplythepagecompilationalgo-
rithm(inVisualBasic & denotesstringconcatena-
tion),andturnthingsinsideouttowriteHTML
stringsto Response object.Insteadofcodeem-
beddedinsideHTML,wenowhaveunstructured
stringsthatrepresentHTMLembeddedinside
code:
<%
SubGenData(x)
Fory=1To16
Response.Write"<TDbgcolor="
Response.WriteColor(x,y)
Response.Write">"
Response.Write"("&x&","&y&")"
Response.Write"</TD>"
Next
EndSub
%>
table::TABLE
table=
<TABLEborder="1">
<%mkRowscells%>
</TABLE>
cells::[[(Int,Int)]]
cells=
[[(x,y)|x<-[1..16]]
|y<-[1..16]
]
TheweaknessofASPandalmostallothernaive
serverpageframeworksbasedonpagetranslation
isthattheydon’treallymixHTMLandscript;
theydon’tmakeHTMLintoafirstclasscitizen.
Asaresultitbecomeshardtousetheprocedural
abstractionmechanismsofthescriptinglanguage
tostructureapage.Beforewecandoso,wefirst
needtotranslatetheserverpageintoitsunderly-
ingsequenceof Response.Write statementsand
thenuseproceduralabstractiontonamethatse-
quenceofstatements.
mkRows::[[(Int,Int)]]->[TR]
mkRows=map$\cs->
<TR><%mkColumscs%></TR>
mkColumns::[(Int,Int)]->[TD]
mkColums=map$\c->
<TDbgcolor=(colorc)>
<%c%>
</TD>
Inthisexample,andinmanyoftheexamplesthat
follow,weuseright-associativefunctionapplica-
Zgłoś jeśli naruszono regulamin