/
Scalable Component Abstractions Martin Odersky EPFL CH Lausanne martin Scalable Component Abstractions Martin Odersky EPFL CH Lausanne martin

Scalable Component Abstractions Martin Odersky EPFL CH Lausanne martin - PDF document

giovanna-bartolotta
giovanna-bartolotta . @giovanna-bartolotta
Follow
548 views
Uploaded On 2014-11-23

Scalable Component Abstractions Martin Odersky EPFL CH Lausanne martin - PPT Presentation

oderskyep64258ch Matthias Zenger Google Switzerland GmbH Freigutstrasse 12 CH8002 Zrich zengergooglecom ABSTRACT We identify three programming language abstractions for the construction of reusable comp onents abstract typ e memb ers explicit selftyp ID: 15403

oderskyep64258ch Matthias Zenger Google Switzerland

Share:

Link:

Embed:

Download Presentation from below link

Download Pdf The PPT/PDF document "Scalable Component Abstractions Martin O..." 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

Figure1:StandardScalaclasses. iesthatfollow.Scalafusesobject-orientedandfunctionalprogramminginastaticallytypedlanguage.Conceptually,itbuildsonaJava-likecore,eventhoughitssyntaxdiers.Tothisfoundation,severalextensionsareadded.Fromtheobject-orientedtraditioncomesauniformobjectmodel,whereeveryvalueisanobjectandeveryoperationisamethodinvocation.Fromthefunctionaltraditioncometheideasthatfunctionsarerst-classvalues,andthatsomeobjectscanbedecomposedusingpatternmatching.Bothtraditionsaremergedintheconceptionofanoveltypesys-tem,whereclassescanbenested,classescanbeaggregatedusingmixincomposition,andwheretypesareclassmemberswhichcanbeeitherconcreteorabstract.ScalaprovidesfullinteroperabilitywithJava.Itspro-gramsarecompiledtoJVMbytecodes,withthe.NETCLRasanalternativeimplementation.Figure1showshowprim-itivetypesandclassesofthehostenvironmentareintegratedinScala'sclassgraph.AtthetopofthisgraphisclassAny ,whichhastwosubclasses:ClassAnyVal ,fromwhichallvaluetypesarederivedandclassAnyRef ,fromwhichallreferencetypesarederived.Thelatterisidentiedwiththerootclassofthehostenvironment(java.lang.Object fortheJVMorSystem.Object fortheCLR).AtthebottomofthegraphareclassAll ,whichhasnoinstances,andclassAllRef ,whichhasthenull referenceasitsonlyinstance.NotethatvalueclassesdonothaveAllRef asasubclassandconsequentlydonothavenull asaninstance.ThismakesitpossibletomapvalueclassesinScalatotheprimitivetypesofthehostenvironment. SpacedoesnotpermitustopresentScalainfullinthispaper;forthis,thereaderisreferredelsewhere[ 34 ].InthissectionwefocusonadescriptionofScala'slanguagecon-structsthataretargetedtocomponentdesignandcompo-sition.WeconcentrateourpresentationonScala2.0,whichdiersinsomedetailsfrompreviousversions.Thedescrip-tiongivenhereisinformal.AtheorythatformalizesScala'skeyconstructsandprovestheirsoundnessisprovidedbytheObjcalculus[ 35 ].2.1AbstractTypeMembersAnimportantissueincomponentsystemsishowtoab-stractfromrequiredservices.Therearetwoprincipalformsofabstractioninprogramminglanguages:parameterizationandabstractmembers.Therstformistypicalforfunc-tionallanguages,whereasthesecondformistypicallyusedinobject-orientedlanguages.Traditionally,Javasupportsparameterizationforvalues,andmemberabstractionforop-erations.ThemorerecentJava5.0withgenericssupportsparameterizationalsofortypes.Scalasupportsbothstylesofabstractionuniformlyfortypesaswellasvalues.Bothtypesandvaluescanbepa-rameters,andbothcanbeabstractmembers.Therestofthissectiongivesanintroductiontoobject-orientedabstrac-tioninScalaandreviewsatthesametimealargepartofitstypesystem.Wedeferadiscussionoffunctionaltypeab-straction(akagenerics)totheappendix,becausethisaspectofthelanguageismoreconventionalandnotasfundamentalforcompositioninthelarge. Tostartwithanexample,thefollowingclassdenescellsofvaluesthatcanbereadandwritten.abstractclassAbsCell{typeT;valinit:T;privatevarvalue:T=init;defget:T=value;defset(x:T):unit={value=x}} TheAbsCell classdenesneithertypenorvalueparameters.InsteadithasanabstracttypememberT andanabstractvaluememberinit .Instancesofthatclasscanbecreatedbyimplementingtheseabstractmemberswithconcretedef-initionsinsubclasses.ThefollowingprogramshowshowtodothisinScalausingananonymousclass.valcell=newAbsCell{typeT=int;valinit=1}cell.set(cell.get*2) Thetypeofvaluecell isAbsCell{typeT=int} .Here,theclasstypeAbsCell isaugmentedbythere-nement{typeT=int} .Thismakesthetypealiascell.T=int knowntocodeaccessingthecell value.Therefore,operationsspecictotypeT arelegal,e.g.cell.set(cell.get*2) .Path­dependenttypesItisalsopossibletoaccessobjectsoftypeAbsCell withoutknowingtheconcretebindingofitstypemember.Forin-stance,thefollowingmethodresetsagivencelltoitsinitialvalue,independentlyofitsvaluetype.defreset(c:AbsCell):unit=c.set(c.init); Whydoesthiswork?Intheexampleabove,theexpressionc.init hastypec.T ,andthemethodc.set hasfunctiontypec.T�=unit .Sincetheformalparametertypeandtheconcreteargumenttypecoincide,themethodcallistype-correct.c.T isaninstanceofapath-dependenttype.Ingeneral,suchatypehastheformx0:::::xn:t,wheren0,x0denotesanimmutablevalue,eachsubsequentxidenotesanimmutableeldofthepathprexx0:::::xi�1,andtdenotesatypememberofthepathx0:::::xn.Path-dependenttypesrelyontheimmutabilityofthepre-xpath.Hereisanexamplewherethisimmutabilityisviolated.varflip=false;deff():AbsCell={flip=!flip;if(flip)newAbsCell{typeT=int;valinit=1}elsenewAbsCell{typeT=String;valinit=""}}f().set(f().get)//illegal! Inthisexamplesubsequentcallstof() returncellswherethevaluetypeisalternatinglyeitherint orString .Thelaststatementinthecodeaboveiserroneoussinceittriestosetanint celltoaString value.Thetypesystemdoesnotadmitthisstatement,becausethecomputedtypeoff().get wouldbef().T .Thistypeisnotwell-formed,sincethemethodcallf() doesnotconstituteawell-formedpath. TypeselectionandsingletontypesInJava,whereclassescanalsobenested,thetypeofanestedclassisdenotedbyprexingitwiththenameoftheouterclass.InScala,thistypeisalsoexpressible,intheformofOuter#Inner ,whereOuter isthenameoftheouterclassinwhichclassInner isdened.The# operatordenotesatypeselection.Notethatthisisconceptuallydierentfromapathdependenttypep.Inner ,wherethepathpdenotesavalue,notatype.Consequently,thetypeexpressionOuter#t isnotwell-formedift isanabstracttypedenedinOuter .Infact,pathdependenttypescanbeexpandedtotypeselections.Thepathdependenttypep.t istakenasashort-handforp.type#t .Here,p.type isasingletontype,whichrepresentsjusttheobjectdenotedbyp.Singletontypesbythemselvesarealsousefulinothercontexts,forinstancetheyfacilitatechainingofmethodcalls.Asanexample,consideraclassC withamethodincr whichincrementsaprotectedintegereld,andasubclassD ofC whichaddsadecr methodtodecrementthateld.classC{protectedvarx=0;defincr:this.type={x=x+1;this}}classDextendsC{defdecr:this.type={x=x­1;this}} Thenwecanchaincallstotheincr anddecr method,asinvald=newD;d.incr.decr; Withoutthesingletontypethis.type ,thiswouldnothavebeenpossible,sinced.incr wouldbeoftypeC ,whichdoesnothaveadecr member.Inthatsense,this.type issimilarto(covariantusesof)KimBruce'smytypeconstruct[ 5 ].ParameterboundsWenowrenetheCell classsothatitalsoprovidesamethodsetMax whichsetsacelltothemaximumofthecell'scurrentvalueandagivenparametervalue.WewouldliketodenesetMax sothatitworksforallcellvaluetypesadmittingacomparisonoperation ,whichisamethodofclassOrdered .Forthemomentweassumethisclassisde-nedasfollows(amorerenedgenericversionofthisclassisinthestandardScalalibrary).abstractclassOrdered{typeO;def(that:O):boolean;def=(that:O):boolean=thisthat||this==that} ClassOrdered hasatypeO andamethod asabstractmembers.Asecondmethod, ,isdenedintermsof .NotethatScaladoesnotdistinguishbetweenoperatornamesandnormalidentiers.Hence, and arelegalmethodnames.Furthermore,inxoperatorsaretreatedasmethodcalls.Foridentiersmandoperandexpressionse1,e2theexpressione1me2istreatedasequivalenttothemethodcalle1:m(e2).Theexpressionthisthat inclassOrdered isthussimplyamoreconvenientwaytoexpressthemethodcallthis.() . classSymbolTable{ className{...} //namespecificoperations classType{...} //subclassesofTypeandtypespecificoperations classSymbol{...} //subclassesofSymbolandsymbolspecificoperations objectdefinitions{//globaldefinitions} //otherelements } Listing1:scalac'ssymboltablestructure Anothersolutiontotheproblemistouseprogramminglanguagesprovidingconstructsforcomponentcompositionandabstraction.Forinstance,functorsoftheSMLmodulesystem[ 27 ]canbeusedtoimplementcomponent-basedsys-temswherecomponentinteractionsarenothard-coded.Ontheotherhand,functorsareneitherrst-classnorhigher-order.Consequently,theycannotbeusedtocreatenewcompilersfromdynamicallyprovidedcomponents.Othermodulesystems,likeMzScheme'sUnits[ 15 , 14 ],areexpres-siveenoughtoallowthis,buttheyareoftenonlydynam-icallytyped,givingnoguaranteesatcompile-time.Typi-calcomponent-orientedprogramminglanguageslikeArch-Java[ 1 ],Jiazzi[ 30 ],andComponentJ[ 42 ]arestaticallytypedanddoprovidegoodsupportforcreatingandcompos-inggenericsoftwarecomponents,buttheirtypesystemsarenotexpressiveenoughtofullyisolatereentrantsystems.ThemodulesystemofKeris[ 51 ]canenforceastrictseparationofmultiplereentrantinstancesofacompiler,butwithoutsupportforrst-classmodulesitrequiresthatthenumberofsimultaneouslyrunningcompilerinstancesisknownstat-ically.AsimplereentrantcompilerimplementationFortherewriteoftheScalacompilerwefoundanotherso-lution,whichistypesafe,andwhichusesthelanguageele-mentsofScalaitself.Asarststeptowardsthissolution,weintroducenestingofclassestoexpresslocalstructure.AsimpliedversionofthesymboltablecomponentofthescalaccompilertoberenedlaterisshowninListing 1 .Here,classesName ,Symbol ,Type ,andtheobjectDefinitions areallmembersoftheSymbolTable class.Thewholecompiler(whichwouldbestructuredsimilarly)canaccessdenitionsinthisclassbyinheritingfromit:classScalaCompilerextendsSymbolTable{...} Inthatway,wearriveatacompilerwithoutstaticde-nitions.Thecompilerisbydesignre-entrant,andcanbeinstantiatedlikeanyotherclassasoftenasdesired.Further-more,membertypesofdierentinstantiationsareisolatedfromeachother,whichgivesagooddegreeoftypesafety.Considerforinstanceascenariowheretwoinstancesc1 andc2 oftheScalacompilerco-exist. abstractclassTypesrequires(TypeswithNames withSymbols withDefinitions){ classType{...} //subclassesofTypeand //typespecificoperations } abstractclassSymbolsrequires(SymbolswithNames withTypes){ classSymbol{...} //subclassesofSymboland //symbolspecificoperations } abstractclassDefinitionsrequires (DefinitionswithNames withSymbols){ objectdefinitions{...} } abstractclassNames{ className{...} //namespecificoperations } classSymbolTableextendsNames withTypes withSymbols withDefinitions; classScalaCompilerextendsSymbolTable withTrees with...; Listing2:Symboltablecomponentswithrequiredinterfaces valc1=newScalaCompiler;valc2=newScalaCompiler; Namescreatedbythec1compilerinstancehavethepath-dependenttypec1.Name ,whereasnamescreatedbyc2 havetypec2.Name .Sincethesetwotypesareincompatible,aproblematicassignmentsuchasthefollowingwouldberuledout.c1.definitions.AllClass.name=c2.definitions.AllClass.name//illegal! Component­basedimplementationThecodesketchedabovehasaverysevereshortcoming:itisalargemonolithicprogramandthusnotreallycomponent-based!Indeed,thewholesymboltablecode(roughly4000lines)isnowplacedinasinglesourcele.Thisclearlybe-comesimpracticalforlargeprograms.Nevertheless,thepreviousattemptpointsthewaytoasolution.Weneedtoexpressanestedstructureliketheoneabove,butwithitsconstituentsspreadoverseparatesourceles.Theproblemishowtoexpresscross-lereferencesinthissetting.Forinstance,inclassSymbol oneneedstorefertothecorrespondingType classwhichbelongstothesamecompilerinstancebutwhichisdenedinadierentsourcele.Thereareseveralpossiblesolutionstothisproblem.The Figure2:CompositionoftheScalacompiler'ssymboltables. alitytoexistingclasses.E.g.:abstractclassLogSymbolsextendsSymbols{vallog:java.io.PrintStream;overridedefnewTermSymbol(name:Name):TermSymbol={valx=super.newTermSymbol(name);log.println("creating term symbol "+name);x}//similarlyforallothersymbolcreations.} Analogously,onecandeneasubclassLogTypes ofclassTypes tologalltypecreations.Thequestionthenishowtoinjecttheloggingbehaviorintoanexistingsystem.SincethewholeScalacompilerisdenedasasingleclass,thisisastraightforwardapplicationofmixincomposition:classLoggedCompilerextendsScalaCompilerwithLogSymbolswithLogTypes{vallog:PrintStream=System.out} InthemixincompositionthenewimplementationofnewTermSymbol inclassLogSymbols overwritestheimplemen-tationofthesamemethodwhichisdenedinclassSymbol andwhichisinheritedbyclassScalaCompiler .Conversely,theabstractmembersnamedlog inclassesLogSymbols andLogTypes arereplacedbytheconcretedenitionoflog inclassLoggedCompiler .Thisadaptationmightseemtrivial.Butnotethatinaclassicalsystemarchitecturewithstaticcomponentsandhardlinks,itwouldhavebeenimpossible.Forsucharchi-tectures,aspect-orientedprogramming[ 22 ]proposesanal-ternativesolution,whichisbasedoncoderewriting.Infact,ourcomponentarchitecturecanhandlesomeofthescenar-iosforwhichAOPhasbeenproposedasthetechniqueofchoice.Otherexamplesbesidesloggingaresynchronization, securitychecking,orchoiceofdatarepresentation.Moregenerally,ourarchitecturecanhandleallbefore,after,andaroundadviceonmethodreceptionpointcutdesignators.Theserepresentonlyoneinstanceofthepointcutdesigna-torsprovidedbylanguagessuchasAspectJ[ 21 ].Therefore,generalAOPisclearlymorepowerfulthanourscheme.Ontheotherhand,ourschemehastheadvantagethatitisstaticallytyped,andthatscopeandorderofadvicecanbepreciselycontrolledusingthesemanticsofmixincomposi-tion.5.DISCUSSIONWehaveidentiedthreebuildingblocksfortheconstruc-tionofreusablecomponents:abstracttypemembers,ex-plicitselftypes,andsymmetricmixincomposition.ThethreebuildingblockswereformalizedintheObjcalculusandwereimplementedinScala.Scalaisalsothelanguageinwhichallprogrammingexamplesandcasestudiesofthispaperarewritten.Itconstitutesthusaconcreteexperimentwhichvalidatestheconstructionprinciplespresentedhereinarangeofapplicationswrittenbymanydierentpeople.ButScalais,ofcourse,nottheonlypossiblelanguagede-signthatwouldenablesuchconstructions.Inthissection,wetrytogeneralizefromScala'sconcretesetting,inordertoidentifywhatlanguageconstructsareessentialtoachievesystemsofscalableanddynamiccomponents.Weassumeinthewholediscussionastronglyandstaticallytypedobject-orientedlanguage.Thesituationisquitedierentfordy-namicallytypedlanguages,andisdierentagainforfunc-tionallanguageswithML-likemodulesystems.Therstimportantlanguageconstructisclassnesting.Sinceclassnestingisalreadysupportedbymainstreamlan-guages,wehaveomitteditfromourdiscussionsofar,butitisessentialnonetheless.Itistheprimarymeansforaggrega-tionandencapsulation.Withoutit,wecouldonlycomposesystemsconsistingofeldsandmethods,butnotsystemsthatcontainthemselvesclasses.Saidotherwise,everyclasswouldhavetobeeitherabase-classormixinofatop-level system(inwhichcaseitwouldonlyhaveoneinstancepertop-levelinstantiation),oritwouldbecompletelyexternaltothatsystem(inwhichcaseitcannotaccessanythinghid-deninthesystem).Itwouldstillbepossibletoconstructcomponent-basedsystemsasdiscussedbythispaper,butthenecessaryamountofwiringwouldbesubstantial,andonewouldhavetogiveupobject-orientedencapsulationprinciplestoalargeextent.Thesecondlanguageconstructissomeformofmixinortraitcompositionormultipleinheritance.NotalldetailshavetobenecessarilydonethewaytheyweredoneinScala'ssymmetricmixincomposition.Weonlyrequiretwofunda-mentalproperties:First,thatmixinsorclassescancontainthemselvesmixinsorclassesasmembers.Second,thatcon-creteimplementationsinonemixinorclassmayreplaceab-stractdeclarationsinanothermixinorclass,independentoftheorderinwhichthemixinswerecomposed.Thelat-terpropertyisnecessarytoimplementmutuallyrecursivedependenciesbetweencomponents.Thethirdlanguageconstructissomemeansofabstractionovertherequiredservicesofaclass.Suchabstractionhastoapplytoallformsofdenitionsthatcanoccurinsideaclass.Inparticularitmustbepossibletoabstractoverclassesaswellasmethods.WehaveseeninScalatwomeansofabstraction.Oneworkedbyabstractingoverclassmembers,theotherbyabstractingoverthetypeofself.Thesetwotechniquesarelargelycomplementaryinwhattheyachieve.Abstractionoverclassmembersgivesveryne-grainedcontroloverrequiredtypesandservices.Eachrequireden-tityisnamedindividually,andalsocanbegivenatype(ortype-boundinthecaseoftypemembers)whichcap-turesonlywhatisrequiredfromtheentitybythecontain-ingclass.Theentitymaythenbedenedinanotherclasswithastrongertype(ortype-bound)thantherequiredone.Inotherwords,classmemberabstractionintroducestype-slackbetweentherequiredandprovidedinterfacesforthesameservice.Thisinturnallowsustospecifytherequiredinterfaceofaclasswithgreatprecision.Abstractionoverclassmembersalsosupportscovariantspecialization.Infact,thisisaconsequenceofthetype-slackitintroduces.Covariantspecializationisimportantinmanydierentsituations.Onesetofsituationsischaracter-izedbythegenericexpressionproblemexample.Here,thetaskistoextendsystemsoverarecursivedatatypebynewdatavariantsaswellasbynewoperationsoverthatdata[ 45 , 37 ].Relatedtothisisalsotheproductionlineproblemwhereasetoffeatureshastobecomposedinamodularwaytoyieldasoftwareproduct[ 26 ].Familypolymorphismisanotherinstanceofcovariantspecialization.Here,severaltypesneedtobespecializedtogether,asinthesubject/ob-serverexampleofSection 3 .Thedownsideoftheprecisionofclassmemberabstrac-tionisitsverbosity.Listingallrequiredmethods,elds,andtypesincludingtheirtypesandtypeboundscanaddsignicantoverheadtoacomponent'sdescription.Selftypeabstractionisamoreconcisealternativetomemberabstrac-tion.Insteadofnamingandtypingallmembersindividuallyonesimplyattachesatypetothis .Thisissomewhatakintothedierencebetweenstructuralandnominaltyping.Infact,selftypeabstractionsarealmostasconciseastra-ditionalreferencesbetweenstaticcomponents.Toseethis,notethatimportclausesintraditionalsystemscorrespondtosummandsinacompoundselftypeinourscheme.Con- siderforinstanceasystemofthreeJavaclassesA ,B ,andC ,eachofwhichreferstotheothertwo.Assumethatallthreeclassescontainstaticnestedclasses.ThenclassAcouldim-portallnestedclassesinB andC usingcodelikethis:importB.*;importC.*;classA{...} ClassesB andC wouldbeorganizedsimilarly.TranslatingJava'sstaticsettingintoonewherecompo-nentscanbeinstantiatedmultipletimes,weobtainthefol-lowing,slightlymoreconciseScalacode:classArequires(AwithBwithC){...} ClassesB andC areorganizedsimilarly.Theinter-classref-erencesinA ,B ,andC stayexactlythesame.Inparticular,allnestedclassescanbeaccessedwithoutqualication.Theonlypieceofcodethatneedstobewritteninadditionisadenitionofatop-levelapplicationwhichcontainsallthreeclasses:classAllextendsAwithBwithC; Inthecaseofstaticcomponents,thedenitionofthesetofclassesmakingupanapplicationisimplicititisthetransitiveclosureofallclassesreachablefromthemainpro-gram.InScala,thereisasecondadvantageofselftypeabstrac-tionoverclassmemberabstraction.Thishastodowithashortcomingofclassmemberabstractionasitisdenedinthelanguage.Infact,Scalaallowsmemberabstractiononlyovertypes,butlacksthepossibilitytoabstractoverotheraspectsofclasses.Abstracttypescanbeusedastypesformembers,butnoinstancescanbecreatedfromthem,norcantheybeinheritedbysubclasses.Hence,ifsomeoftheclassesdenedinacomponentinheritfromsomeexternalclassinthecomponent'srequiredinterface,selftypeabstrac-tionistheonlyavailablemeanstoexpressthis.Thesameholdsifacomponentinstantiatesobjectsfromanexternal,requiredclassusingnew ratherthangoingthroughafactorymethod.Liftingtherestrictionsonclassmemberabstractionwouldleadusfromabstracttypestovirtualclassesintheirfullgenerality,inthewaytheyaredenedingbeta[ 10 ],forexample.Thiswouldyieldamoreexpressivelanguageforexiblecomponentarchitectures[ 12 ].Ontheotherhand,theresultinglanguagewouldhavetoeitheravoidordetectaccidentaloverrideconictsbetweenpairsofclassesthatdonotstaticallyinheritfromeachother.Neitheriseasytotype-checkortoimplementonstandardplatformssuchasJVMorthe.NETCLR.6.CONCLUSIONWehavepresentedthreebuildingblocksforreusablecom-ponents:abstracttypemembers,explicitselftypes,andmodularmixincomposition.Eachoftheseconstructsex-istsinsomeformalsoinotherformalisms,butwebelievetobethersttocombinetheminonelanguageandtohavedis-coveredtheimportanceoftheircombinationinbuildingandcomposingsoftwarecomponents.Wehavedemonstratedtheiruseintwocasestudies,apublish/subscribeframeworkandtheScalacompileritself.Thecasestudiesshowthatourlanguageconstructsareadequatetoliftanarbitrary assemblyofstaticprogrampartstoacomponentsystemwhererequiredinterfacesaremadeexplicitandhardlinksbetweencomponentsareavoided.Theliftingcompletelypreservesthestructureoftheoriginalprogram.Thisisnottheendofthestory,however.Thescenariowehavestudiedwastheinitialconstructionofastaticallytypedsystemofcomponentsrunningonasinglesite.Wedidnottouchaspectsofdistributionanddynamiccomponentdiscovery,nordidwetreattheevolutionofacomponentsystemovertime.Weintendtofocusonthesetopicsinfuturework.Acknowledgments.TheScaladesignandimplementationhasbeenacollectiveeortofmanypeople.Besidestheauthors,PhilippeAltherr,VincentCremet,IulianDragos,GillesDubochet,BurakEmir,SebastianManeth,StéphaneMicheloud,NikolayMihaylov,MichelSchinz,andErikSten-manhavemadeimportantcontributions.Theworkwaspar-tiallysupportedbygrantsfromtheEuropeanFramework6projectPalCom,theSwissNationalFundunderprojectNFS21-61825,theSwissNationalCompetenceCenterforResearchMICS,MicrosoftResearch,andtheHaslerFounda-tion.WealsothankGiladBracha,StéphaneDucasse,ErikErnst,NastaranFatemi,MatthiasFelleisen,ShriramKrish-namurti,OscarNierstrasz,DidierRémy,andPhilipWadlerforusefuldiscussionsaboutthematerialpresentedinthispaper.7.REFERENCES [1] J.Aldrich,C.Chambers,andD.Notkin.ArchitecturalreasoninginArchJava.InProceedingsofthe16thEuropeanConferenceonObject-OrientedProgramming,Málaga,Spain,June2002. [2] K.Barrett,B.Cassels,P.Haahr,D.A.Moon,K.Playford,andP.T.Withington.AMonotonicSuperclassLinearizationforDylan.InProc.OOPSLA,pages6982.ACMPress,Oct.1996. [3] G.BrachaandW.Cook.Mixin-BasedInheritance.InN.Meyrowitz,editor,ProceedingsofECOOP'90,pages303311,Ottawa,Canada,October1990.ACMPress. [4] K.B.Bruce,M.Odersky,andP.Wadler.AStaticallySafeAlternativetoVirtualTypes.LectureNotesinComputerScience,1445,1998.Proc.ESOP1998. [5] K.B.Bruce,A.Schuett,andR.vanGent.PolyTOIL:AType-SafePolymorphicObject-OrientedLanguage.InProceedingsofECOOP'95,LNCS952,pages2751,Aarhus,Denmark,August1995.Springer-Verlag. [6] P.Canning,W.Cook,W.Hill,W.Oltho,andJ.Mitchell.F-BoundedQuanticationforObject-OrientedProgramming.InProc.of4thInt.Conf.onFunctionalProgrammingandComputerArchitecture,FPCA'89,London,pages273280,NewYork,Sep1989.ACMPres. [7] L.Cardelli,S.Martini,J.C.Mitchell,andA.Scedrov.AnExtensionofSystemFwithSubtyping.InformationandComputation,109(12):456,1994. [8] D.Duggan.Mixinmodules.InACMSIGPLANInternationalConferenceonFunctionalProgramming,1996. [9] ECMA.C#LanguageSpecication.TechnicalReport StandardECMA-334,2ndEdition,EuropeanComputerManufacturersAssociation,December2002. [10] E.Ernst.gBeta:Alanguagewithvirtualattributes,blockstructureandpropagating,dynamicinheritance.PhDthesis,DepartmentofComputerScience,UniversityofAarhus,Denmark,1999. [11] E.Ernst.Familypolymorphism.InProceedingsoftheEuropeanConferenceonObject-OrientedProgramming,pages303326,Budapest,Hungary,2001. [12] E.Ernst.Higher-OrderHierarchies.InL.Cardelli,editor,ProceedingsECOOP2003,LNCS2743,pages303329,Heidelberg,Germany,July2003.Springer-Verlag. [13] K.FisherandJ.H.Reppy.TheDesignofaClassMechanismforMoby.InSIGPLANConferenceonProgrammingLanguageDesignandImplementation,pages3749,1999. [14] M.Flatt.ProgrammingLanguagesforReusableSoftwareComponents.PhDthesis,RiceUniversity,DepartmentofComputerScience,June1999. [15] M.FlattandM.Felleisen.Units:CoolmodulesforHOTlanguages.InProceedingsoftheACMConferenceonProgrammingLanguageDesignandImplementation,pages236248,1998. [16] J.Gosling,B.Joy,G.Steele,andG.Bracha.TheJavaLanguageSpecication.JavaSeries,SunMicrosystems,secondedition,2000. [17] R.HarperandM.Lillibridge.AType-TheoreticApproachtoHigher-OrderModuleswithSharing.InProc.21stACMSymposiumonPrinciplesofProgrammingLanguages,January1994. [18] T.HirschowitzandX.Leroy.MixinModulesinaCall-by-ValueSetting.InEuropeanSymposiumonProgramming,pages620,2002. [19] A.IgarashiandM.Viroli.VariantParametricTypes:AFlexibleSubtypingSchemeforGenerics.InProceedingsoftheSixteenthEuropeanConferenceonObject-OrientedProgramming(ECOOP2002),pages441469,June2002. [20] M.P.Jones.Usingparameterizedsignaturestoexpressmodularstructure.InProceedingsofthe23rdACMSymposiumonPrinciplesofProgrammingLanguages,pages6878.ACMPress,1996. [21] G.Kiczales,E.Hilsdale,J.Hugunin,M.Kersten,J.Palm,andW.G.Griswold.Anoverviewofaspectj.InProceedingsofECOOP2001,SpringerLNCS,pages327353,2001. [22] G.Kiczales,J.Lamping,A.Menhdhekar,C.Maeda,C.Lopes,J.-M.Loingtier,andJ.Irwin.Aspect-orientedprogramming.InProceedingsofthe11thEuropeanConferenceonObject-OrientedProgramming,pages220242,Jyväskylä,Finland,1997. [23] J.L.Knudsen.Aspect-orientedprogramminginbetausingthefragmentsystem.InProceedingsoftheWorkshoponObject-OrientedTechnology,SpringerLNCS,pages304305,1999. [24] X.Leroy.ManifestTypes,ModulesandSeparateCompilation.InProc.21stACMSymposiumonPrinciplesofProgrammingLanguages,pages109122,January1994. defget:T=value;defset(x:T):unit={value=x}}defswap[T](x:GenCell[T],y:GenCell[T]):unit={valt=x.get;x.set(y.get);y.set(t)}defmain(args:Array[String])={valx:GenCell[int]=newGenCell[int](1);valy:GenCell[int]=newGenCell[int](2);swap[int](x,y)} Listing3:Simplegenericclassesandmethods Asasimpleexample,Listing 3 denesagenericclassofcellsofofvaluesthatcanbereadandwritten,togetherwithapolymorphicfunctionswap ,whichexchangesthecontentsoftwocells,aswellasamain functionwhichcreatestwocellsofintegersandthenswapstheircontents.Typeparametersandtypeargumentsarewritteninsquarebrackets,e.g.[T] ,[int] .Scaladenesasophisticatedtypeinferencesystemwhichpermitstoomitactualtypear-guments.Typeargumentsofamethodorconstructorareinferredfromtheexpectedresulttypeandtheargumenttypesbylocaltypeinference[ 39 , 36 ].Hence,thebodyoffunctionmain inListing 3 canalsobewrittenwithoutanytypearguments:valx=newGenCell(1);valy=newGenCell(2);swap(x,y) VarianceThecombinationofsubtypingandgenericsinalanguageraisesthequestionhowtheyinteract.IfCisatypecon-structorandSisasubtypeofT,doesonealsohavethatC[S]isasubtypeofC[T]?Typeconstructorswiththispropertyarecalledcovariant.ThetypeconstructorGenCell shouldclearlynotbecovariant;otherwiseonecouldconstructthefollowingprogramwhichleadstoatypeerroratruntime.valx:GenCell[String]=newGenCell[String];valy:GenCell[Any]=x;//illegal!y.set(1);valz:String=y.get ItisthepresenceofamutablevariableinGenCell whichmakescovarianceunsound.Indeed,aGenCell[String] isnotaspecialinstanceofaGenCell[Any] sincetherearethingsonecandowithaGenCell[Any] thatonecannotdowithaGenCell[String] ;setittoanintegervalue,forinstance.Ontheotherhand,forimmutabledatastructures,co-varianceofconstructorsissoundandverynatural.Forin-stance,animmutablelistofintegerscanbenaturallyseenasaspecialcaseofalistofAny .Therearealsocaseswherecontravarianceofparametersisdesirable.AnexampleareoutputchannelsChan[T] ,withawriteoperationthattakesaparameterofthetypeparameterT .HereonewouldliketohaveChan[S]Chan[T] wheneverTS .Scalaallowstodeclarethevarianceofthetypeparametersofaclassusingplusorminussigns.A+infrontofaparameternameindicatesthattheconstructoriscovariantintheparameter,a�indicatesthatitiscontravariant,andamissingprexindicatesthatitisnon-variant.Forinstance,thefollowingtraitGenList denesasimplecovariantlistwithmethodsisEmpty ,head ,andtail . traitGenList[+T]{defisEmpty:boolean;defhead:T;deftail:GenList[T]} Scala'stypesystemensuresthatvarianceannotationsaresoundbykeepingtrackofthepositionswhereatypepa-rameterisused.Thesepositionsareclassiedascovariantforthetypesofimmutableeldsandmethodresults,andcontravariantformethodargumenttypesanduppertypeparameterbounds.Typeargumentstoanon-varianttypeparameterarealwaysinnon-variantposition.Theposi-tionipsbetweencontra-andco-variantinsideatypeargu-mentthatcorrespondstoacontravariantparameter.Thetypesystemenforcesthatcovarianttypeparametersareonlyusedincovariantpositions,andthatcontravarianttypepa-rametersareonlyusedincontravariantpositions.HerearetwoimplementationsoftheGenList class:objectEmptyextendsGenList[All]{defisEmpty:boolean=true;defhead:All=thrownewError("Empty.head");deftail:List[All]=thrownewError("Empty.tail");}classCons[+T](x:T,xs:GenList[T])extendsGenList[T]{defisEmpty:boolean=false;defhead:T=x;deftail:GenList[T]=xs} AsisshowninFigure 1 ,thetypeAll representsthebottomtypeofthesubtypingrelationofScala(whereasAny isthetop).Therearenovaluesofthistype,butthetypeisnev-erthelessuseful,asshownbythedenitionoftheemptylistobject,Empty .Becauseofco-variance,Empty 'stype,GenList[All] isasubtypeofGenList[T] ,foranyelementtypeT.Hence,asingleobjectcanrepresentemptylistsforeveryelementtype.BinarymethodsandlowerboundsSofar,wehaveassociatedcovariancewithimmutabledatastructures.Infact,thisisnotquitecorrect,becauseofbinarymethods.Forinstance,consideraddingaprepend methodtotheGenList trait.Themostnaturaldenitionofthismethodtakesanargumentofthelistelementtype:traitGenList[+T]{...defprepend(x:T):GenList[T]=//illegal!newCons(x,this)} However,thisisnottype-correct,sincenowthetypeparam-eterT appearsincontravariantpositioninsidetraitGenList .Therefore,itmaynotbemarkedascovariant.Thisisapitysinceconceptuallyimmutablelistsshouldbecovariantintheirelementtype.Theproblemcanbesolvedbygener-alizingprepend usingalowerbound:traitGenList[+T]{...defprepend[S�:T](x:S):GenList[S]=//OKnewCons(x,this)} prepend isnowapolymorphicmethodwhichtakesanar-gumentofsomesupertypeS ofthelistelementtype,T .Itreturnsalistwithelementsofthatsupertype.Thenewmethoddenitionislegalforcovariantlistssincelowerboundsareclassiedascovariantpositions;hencethetypeparameterT nowappearsonlycovariantlyinsidetraitGenList .Itispossibletocombineupperandlowerboundsinthedeclarationofatypeparameter.Anexampleisthefollowingmethodless ofclassGenList whichcomparesthereceiverlistandtheargumentlist.traitGenList[+T]{...defless[S�:T:scala.Ordered[S]](that:List[S])=!that.isEmpty&&(this.isEmpty||this.headthat.head||this.head==that.head&&this.taillessthat.tail)} Themethod'stypeparameterS isboundedfrombelowbythelistelementtypeT andisalsoboundedfromabovebythestandardclassscala.Ordered[S] .Thelowerboundisnec-essarytomaintaincovarianceofGenList .Theupperboundisneededtoensurethatthelistelementscanbecomparedwiththe operation.ComparisonwithwildcardsJava5.0alsohasawaytoannotatevarianceswhichisbasedonwildcards[ 47 ].Theschemeisessentiallyare-nementofIgarashiandViroli'svariantparametrictypes[ 19 ].UnlikeinScala,annotationsinJava5.0applytotypeexpressionsinsteadoftypedeclarations.Asanex-ample,covariantgenericlistscouldbeexpressedbywrit-ingeveryoccurrenceoftheGenList typetomatchtheformGenListextendsT&#x?]TJ;&#x/F63;&#x 7.2;c T; 43;&#x.577;&#x 0 T; [00; .Suchatypeexpressiondenotesin-stancesoftypeGenList wherethetypeargumentisanarbi-trarysubtypeofT.Covariantwildcardscanbeusedineverytypeexpression;however,memberswherethetypevariabledoesnotappearincovariantpositionarethenforgotteninthetype.Thisisnecessaryformaintainingtypesoundness.Forinstance,thetypeGenCellextends&#x?]TJ;&#x/F63;&#x 7.2;c T; 43;&#x.576;&#x 0 T; [00;Number wouldhavejustthesin-glememberget oftypeNumber ,whereastheset method,inwhichGenCell's typeparameteroccurscontravariantly,wouldbeforgotten.InanearlierversionofScalawealsoexperimentedwithusage-sitevarianceannotationssimilartowildcards.Atrst-sight,thisschemeisattractivebecauseofitsexibility.Asingleclassmighthavecovariantaswellasnon-variantfragments;theuserchoosesbetweenthetwobyplacingoromittingwildcards.However,thisincreasedexibilitycomesatprice,sinceitisnowtheuserofaclassinsteadofitsdesignerwhohastomakesurethatvarianceanno-tationsareusedconsistently.Wefoundthatinpracticeitwasquitediculttoachieveconsistencyofusage-sitetypeannotations,sothattypeerrorswerenotuncommon.ThiswasprobablypartlyduetothefactthatweusedtheoriginalsystemofIgarashiandViroli[ 19 ].Java5.0'swildcardimple-mentationaddstothistheconceptofcaptureconversion[ 46 ],whichgivesbettertypingexibility.Bycontrast,declaration-siteannotationsprovedtobea greathelpingettingthedesignofaclassright;forinstancetheyprovideexcellentguidanceonwhichmethodsshouldbegeneralizedwithlowerbounds.Furthermore,Scala'smixincomposition(seeSection 2.2 )makesitrelativelyeasytofac-torclassesintocovariantandnon-variantfragmentsexplic-itly;inJava'ssingleinheritanceschemewithinterfacesthiswouldbeadmittedlymuchmorecumbersome.Forthesereasons,laterversionsofScalaswitchedfromusage-sitetodeclaration-sitevarianceannotations.ModelinggenericswithabstracttypesThepresenceoftwotypeabstractionfacilitiesinonelan-guageraisesthequestionoflanguagecomplexitycouldwehavedonewithjustoneformalism?Inthissectionweshowthatfunctionaltypeabstractioncanindeedbemodeledbyobject-orientedtypeabstraction.Theideaoftheencodingisasfollows.AssumeyouhaveaparameterizedclassCwithatypeparametert(theencodinggeneralizesstraightforwardlytomultipletypeparameters).Theencodinghasfourparts,whichaecttheclassdenitionitself,instancecreationsoftheclass,baseclassconstructorcalls,andtypeinstancesoftheclass. 1. TheclassdenitionofCisre-writtenasfollows.classC{typet;/*restofclass*/} Thatis,parametersoftheoriginalclassaremodeledasabstractmembersintheencodedclass.Ifthetypeparameterthaslowerand/orupperbounds,thesecarryovertotheabstracttypedenitionintheencoding.Thevarianceofthetypeparameterdoesnotcarryover;variancesinuenceinsteadtheformationoftypes(seePoint4below). 2. EveryinstancecreationnewC[T] withtypeargumentTisrewrittento:newC{typet=T} 3. IfC[T] appearsasasuperclassconstructor,theinher-itingclassisaugmentedwiththedenitiontypet=T 4. EverytypeC[T]isrewrittentooneofthefollowingtypeswhicheachaugmentclassCwitharenement. C{typet=T} iftisdeclarednon-variant,C{typetT} iftisdeclaredco-variant,C{typet�:T} iftisdeclaredcontra-variant.Thisencodingworksexceptforpossiblename-conicts.Sincetheparameternamebecomesaclassmemberintheencoding,itmightclashwithothermembers,includingin-heritedmembersgeneratedfromparameternamesinbaseclasses.Thesenameconictscanbeavoidedbyrenaming,forinstancebytaggingeverynamewithauniquenumber.Thepresenceofanencodingfromonestyleofabstractiontoanotherisnice,sinceitreducestheconceptualcomplex-ityofalanguage.InthecaseofScala,genericsbecomesimplysyntacticsugarwhichcanbeeliminatedbyanen-codingintoabstracttypes.However,onecouldaskwhetherthesyntacticsugariswarranted,orwhetheronecouldhave donewithjustabstracttypes,arrivingatasyntacticallysmallerlanguage.TheargumentsforincludinggenericsinScalaaretwo-fold.First,theencodingintoabstracttypesisnotthatstraightforwardtodobyhand.Besidesthelossinconciseness,thereisalsotheproblemofaccidentalnameconictsbetweenabstracttypenamesthatemulatetypepa-rameters.Second,genericsandabstracttypesusuallyservedistinctrolesinScalaprograms.Genericsaretypicallyusedwhenoneneedsjusttypeinstantiation,whereasabstracttypesaretypicallyusedwhenoneneedstorefertotheab-stracttypefromclientcode.Thelatterarisesinparticularintwosituations:Onemightwanttohidetheexactdeni-tionofatypememberfromclientcode,toobtainakindofencapsulationknownfromSML-stylemodulesystems.Oronemightwanttooverridethetypecovariantlyinsubclassestoobtainfamilypolymorphism.Couldonealsogotheotherway,encodingabstracttypeswithgenerics?Itturnsoutthatthisismuchharder,andthatitrequiresatleastaglobalrewritingoftheprogram.Thiswasshownbystudiesinthedomainofmodulesys-temswherebothkindsofabstractionarealsoavailable[ 20 ].Furthermoreinasystemwithboundedpolymorphism,thisrewritingmightentailaquadraticexpansionoftypebounds[ 4 ].Infact,thesedicultiesarenotsurprisingifoneconsidersthetype-theoreticfoundationsofbothsys-tems.Generics(withoutF-bounds)areexpressibleinSys-temF:[ 7 ]whereasabstracttypesrequiresystemsbasedondependenttypes.Thelatteraregenerallymoreexpressivethantheformer;forinstanceObjwithitspath-dependenttypescanencodeF:.