Original citation:
Meehan, Gary (1998) The aladin abstract machine. University of Warwick. Department
of Computer Science. (Department of Computer Science Research Report).
(Unpublished) CS-RR-355
Permanent WRAP url:
http://wrap.warwick.ac.uk/61067
Copyright and reuse:
The Warwick Research Archive Portal (WRAP) makes this work by researchers of the
University of Warwick available open access under the following conditions. Copyright ©
and all moral rights to the version of the paper presented here belong to the individual
author(s) and/or other copyright owners. To the extent reasonable and practicable the
material made available in WRAP has been checked for eligibility before being made
available.
Copies of full items can be used for personal research or study, educational, or
not-for-profit purposes without prior permission or charge. Provided that the authors, title and
full bibliographic details are credited, a hyperlink and/or URL is given for the original
metadata page and the content is not changed in any way.
A note on versions:
The version presented in WRAP is the published version or, version of record, and may
be cited as it appears here.For more information, please contact the WRAP Team at:
Gary Meehan
Departmentof Computer Siene University of Warwik
Coventry UK, CV47AL
E-mail: Gary.Meehands.warwik.a.uk
Deember 17,1998
Abstrat
TheAladinAbstratMahine(AAM)providesaompletelyabstratdenitionof afuntionallanguage. TherearenoprimitivesbuiltintoAladin,insteadprimitivesare intendedtobeprogrammed inany language,funtionalor imperativeand imported into the AAM. In this report we develop an eÆient operational semantis for the AAM usingthe original denotational semantisas our starting point. We thenuse thissemantistodevelopanimplementationofAladin,usingtheJavalanguage,with theability to writeprograms inan Aladin sripting language that we develop, and primitiveswritteninC/C++,JavaandGinger.
1 Introdution
The Aladin Abstrat Mahine (AAM) [1℄ provides a ompletely abstrat denition of a funtional language. There areno primitivesbuilt into Aladin, insteadprimitivesare in-tendedtobeprogrammedinany language,funtionalorimperativeandimportedintothe AAM.Theseprimitivesouldbesimplefuntionslikeaddition;moreomplexhigher-order oneslikemap orfold;orevenompleteprogramssuhasgrep orw.
As well as the lak of primitives, Aladin has two more major features not found in the majority of funtional languages: the ability to speify the stritness of afuntion's argumentsand results; and the use of streams for ordered I/Oand real-time operations (whih weshallnotonsiderfurther inthisreport).
Unlikemost otherabstrat mahines forfuntional languages,suh astheG-Mahine [2, 3℄,the SECDmahine [4℄, and the Three InstrutionMahine (TIM) [5℄, theAAM is onernedonlywiththeevaluationofprogramsandnottheironstrution. SineAladinis designedto import its primitivesfrom any language,it would be inappropriateto tiethe abstrat mahinedownto onepartiularwayofonstrutingprograms.
ingfromtheoriginaldenotationalsemantisandgoingvia adenotationalsemantiswhih inludes expliitsharingand updating. Wethen use this semantis to develop an imple-mentation of Aladin, using the Java language, with the ability to write programs in an Aladinsriptinglanguagethat wedevelop,and primitiveswrittenin C[6℄,C++[7℄, Java [8℄andGinger[9℄.
2 The Denotational Semantis of the AAM
An Aladinprogramis designedto be eitheradata objet, afuntion ofanappliation of oneprogramtoanother. DenotingoursetofdataobjetsasD andoursetoffuntions as F thenoursetofprograms,P is:
P::=DjFjP P
Multiple-argumentstofuntionsareurriedandappliationsareleft-assoiative. Henefor p 1 ;p 2 ;p 3
2P wehave:
p 1 p 2 p 3 (p 1 p 2 )p 3
Funtionsmay bewritten inanylanguageoftheuser'shoie. Afuntion f of aritymis denoted asf
m
. Themeta-funtion is used to primitively apply f to itsargumentsby exeutingtheodeassoiatedwithf. Theexpression f
m (p
1 ;:::;p
m
)denotestheresult oftheprimitiveappliation.
Theuserisrequiredtospeifythestritnessofitsargumentandresultwhihgivesthe userompleteontrolovertheevaluationorder ofprograms. Weadopt aslightlydierent denitiontostritnessthatthatusedinotherfuntionallanguages. Wesaythatafuntion isstritinanargumentifitisrequiredthattheargumentisevaluatedbeforethefuntion is applied and lazy otherwise. A funtion returns a strit result if it is not required to evaluatetheresult,alazyresultotherwise. Forafuntion ofaritymweusethenotation:
f :: 1 ::: m !; i
;2fs;lg
to denote a funtion whih is strit in itsith argumentif i
= sand lazy if i
= l, and stritin itsresultif=sandlazyif=l.
2.1 The Original Evaluation Rules
Theoriginalevaluationrulesusedameta-funtion,Eval,toreturntheresultofevaluating aprogram. Ifwehaveadataobjetappliedtoanynumberofprograms,thenEvalsimply returnstheoriginalprogram:
Eval[[(d2D)p 1
::: p n
℄℄=dp 1
::: p n
(1)
Ifwehaveafuntionappliedtotoofewarguments,thenwereturntheoriginalexpression, but weevaluateanystrit arguments:
Eval[[(f:: 1
::: m
!)p 1
::: p n<m
℄℄=f q 1
::: q n where
q i
= Eval[[p i
thatisthefuntionappliedtotheexatnumberofargumentsitneeds,thenapplytheresult ofthisto theremainingarguments.
Eval[[f m
p 1
::: p n>m
℄℄=Eval[[rp m+1
::: p n
℄℄ where r=Eval[[f
m p
1 ::: p
m ℄℄
(3)
Finally wehavethe asewhenwehaveafuntion applied to exatlytherightnumberof arguments. Wehaveto dothree things: evaluateanystrit arguments;applythefuntion using;andevaluatetheresultifneessary.
Eval[[(f:: 1
::: m
!)p 1
::: p m
℄℄=r where r = e; if =s
= Eval[[e℄℄; otherwise e = f(q
1 ;:::;q
m ) q
i
= Eval[[p i
℄℄; if i =s = p i ; otherwise (4)
3 The Denotational Semantis of the AAM with Expliit Updates
Implementationsoffuntionallanguagesusesharingandupdatingtoavoiddoingrepeated work. Our rst step towards an eÆient operational semantis for the AAM is thus a denotationalsemantisoftheAAMwhihmakesexpliitsharingandupdating.
3.1 Variables and the Heap
Weassoiateeahprogramwithavariablev2V,hangingoursyntaxofAladinprograms toaommodatethis:
P::=DjFjV jV V (5)
Appliationsnowinvolvetheappliationofonevariabletoanotherandaprogramanalso beavariable,thatisanindiretiontotheatualvalue. Theexpliitnamingofallpartsof aprogram,inpartiularfuntions,meansweanimplementreursiondiretly.
Theseassoiationsaredenedinamappingofvariablestoprogramswhihweshallall theheap. Aheapprovidestheontextfortheevaluationofaprogram,andthusaprogram evaluatedwithrespettooneheapanyieldadierentresulttothesameprogramevaluated w.r.t. adierentheap. Theexpression
[x 0 7!p 0 ;x 1 7!p 1
;:::;x n
7!p n
℄
denotes that in the heap variable x i
maps to program p i
where i 2 0;:::;n. We may oasionallyusetheheapasalookup-funtion,thatis:
x = p; if [x7!p℄ = ?; otherwise
Sineaprogramouldbeavariableweouldhaveahainof indiretions:
[x 0 7!x 1 ;x 1 7!x 2
;:::;x n
0 thehainouldin fatbeayle:
[x 0
7!x 1
;x 1
7!x 2
;:::;x n
7!x 0
℄
Whih isakinto writingsomethinglike:
foo = x where
x = y y = z z = x
in Haskell. Theresultofevaluatinganyprogramwhihtriestoaess avariablein suha ylewillbe?.
We will allow ourselvesto abuse notation slightly and let [ 0
denote the heap updated with the mappings in heap
0
with any lashes being resolved in the favour of thosedened in
0 : ( [
0
)x = p; if 0
[x7!p℄ = q; if [x7!q℄ = ?; otherwise
In partiular, [fx 7! pg denotes a heap where x is assoiated with p and all other variablesare assoiatedto theprogramsthat theywere in . Theheapis aglobal objet andallhangestoitareuniversal andheneanimplementationofaheapandoupdates destrutively.
Sineallprogramsareevaluatedw.r.t. aheap,itfollowsthatourprimitiveappliation meta-funtion mustalso exeutewithrespetto aheap. The informaltypeof hanges from:
P:::P !P
to:
HeapV :::V !(P Heap) (6)
Notethatwhiletakesaheapandvariablesasargumentsitreturnsaprogramandaheap (weneedtoreturnaheapasthefuntion maywanttoreatenewobjetsintheheap).
3.2 The Evaluation Rules
Ourevaluationphilosophyhangesfromthatusedintheoriginalsemantis.Whereasbefore wereturnedanewexpressionwhihrepresentedtheevaluation,wenowevaluateaprogram by updatingthe heapwhih provides theontext for theprogram. The meta-funtion E providesthetop-levelinterfaetothis proedure:
Ep [x7!p℄=(U x)x (7)
Sowend thevariableassoiatedto theprogram wewantto evaluate 1
, update theheap with respet to thisvariable, and nally look upthevalueof thevariable in the updated heap.
1
1
y
n
x
x
y
1
0
x
n
@
@
p
spine
root
base
Figure1: Angeneriunwound appliation
Theupdatingoftheheapis doneby themeta-funtionUwhihupdatesagivenheap byevaluatingtheprogramreferredtobyagivenvariable,whihweshallrefertoastheroot oftheprogram. Iftherootreferstoanappliationthenweneedtotraverseorunwindthe spine (theshadedpartofthegure)oftheappliationuntilwereahanon-appliation. In theheap
[x 0
7!p;x 1
7!x 0
y 1
;:::;x n 7!x n 1 y n ℄ ifx n
formsthe rootof theprogram thenthe x i
;i20;:::;nform thespine and x 0
forms thebase(seeFigure1).
ThefourrulesforU(8{11)diretlyreetthoseofEval(1{4). Supposewehaveadata objetapplied to anumberofarguments. Then sinenoevaluation needsto be done,no updatingoftheheaphastobedoneeither:
U [x 0
7!d2D;x 1
7!x 0
y 1
;:::;x n 7!x n 1 y n ℄x n = (8)
Ifwehaveafuntionappliedtotoofewargumentsthenwejust needtoevaluatethestrit ones. The A meta-funtion (see rule 13) returns the heap resultingfrom evaluating the stritargumentsofafuntion.
U [x 0 7!f m ;x 1 7!x 0 y 1
;:::;x n 7!x n 1 y n ℄x n<m
=A x n
(9)
Ifwehaveafuntionf m
appliedtotoomanyarguments,x 1
;:::;x m
saywheren>m(see Figure2),thenwerstobtaintheheapresultingfromevaluatingtheinnerappliation(the shaded partofthegure) theroot ofwhihis x
m
. Inthis newheap,x m
willrefer tothe evaluatedversionoff
m x
1 ::: f
m
,rsay(seeFigure3). Thisresultbeomesthenewbase ofourprogram(notethatwemayneedtodosomemoreunwindingifrisanappliation) andweontinueupdating.
U [x 0 7!f m ;x 1 7!x 0 y 1
;:::;x n 7!x n 1 y n ℄x n>m =U 0 x n where 0
=U x m
(10)
y
x
m + 1
x
m
n
1
y
1
x
x
f
0
y
m
x
n
m
y
+ 1
@
@
@
@
m
Figure2: Appliationofafuntionto toomanyarguments
n
y
x
m + 1
x
m
x
n
n
y
+ 1
@
@
r
U [x 0
7!f :: 1
::: m
!;x 1
7!x 0
y 1
;:::;x m 7!x m 1 y m ℄x m = 4 where 4 = 3
; if =s
= U 3 x m ; otherwise 3 = update 2 x m r (r; 2
) = f( 1
;y 1
;:::;y m
) 1
= A x m
(11)
Notethatitistheargumentofeahoftheappliationsthatformtheargumentstof that ispassedto,nottheappliationitself. Thefuntionupdatetakesareoftheupdatingof avariablewithanewvalueandisdened(without short-iruitingindiretionhains)as:
update [x7!v℄xr = update vr; if v2V = [fx7!rg; otherwise
(12)
Notethat ifweareupdatingavariablethatis anindiretionto anothervariable,weneed toupdate thevariablethat isreferredtoreettheupdateinallvariablesthatultimately refertotheprogramthatisbeingupdated,otherwiseweriskdupliationofwork.
FinallyweneedtodenetheAmeta-funtionwhihevaluateseahargument.This pro-eedsbyupdatingeahargumentinturnandpassingtheheapobtainedbyeahevaluation into the reursiveallto U used to evaluatethe nextargument. Although the denition hereimpliesthatargumentsareevaluatedleftto right,thisorderingisarbitraryandonly adopted for syntationvenieneanyordering ould be adopted in pratie. Arguments ouldevenbeevaluatedonurrentlyprovidedappropriatearewastaken.
A [x 0
7!f :: 1
::: m
!;x 1
7!x 0
y 1
;:::;x n 7!x n 1 y n ℄x nm = n where i = U i 1 y i ; if i =s = i 1 ; otherwise (13)
4 The Operational Semantis of the AAM
We representtheoperationalsemantis astransition rulesof the stateofthe AAM. This stateisaquadruple:
(Control;Stak;Heap;Dump)
where
Control isa stak of instrutions. These instrutionsare EVAL,EVALARGS,EVALITH andAPPLY.
Stakisastakofvariables,usedasaworkingspaetostorethespineofanappliation when we are unwinding, with the head of the stak forming the base and the last elementinthestaktheroot.
Heap isamappingfromvariablestoprogramsasinthedenotationalase.
ControlandDumpusedbyAladinservesimilarfuntionsastheirounterpartsintheSECD and Gmahines. TheAladinHeapismorealiketheG-Mahine heap,whih likeAladin's heapisaglobalobjetwherethegraphbeingevaluatedisheld,thantheSECDmahine's Environmentwhihservesaloalmappingbetweenvaluesandvariablesdependantonthe expressionbeingevaluated.
Themeta-funtion F evaluatesa programusing thestate-transition rules (see below) w.r.t. agivenheap(f. E):
Fp [x7!p℄= 0
x where (hi;S;
0
;hi)=T(hEVALi;hxi; ;hi)
(14)
Themeta-funtionTrepeatedlyappliesthestate-transitionrules(rules15{23below)toa stateuntilnomoreapply,returningthenalstate. So,ifwehaveatransitionsequene:
s 1
=)s 2
=):::=)s n andnorulesapplytos
n
thenTs i
=s n
;i21;:::;n.
Wenowhavetogivethetransitionrulesforastate,startingfromtheinitialstateused astheargumentto T . Ifnoneof theserulesapplythenthemahineterminates. Therst aseiswhentheheadofthestakreferenestoadataobjet,thatiswhenwehaveadata objetappliedto anumberofarguments,f. rules 1and8. Weneed tomakeno hanges andnofurtherworkanbedoneinthisstate. Ifthedumpisnon-emptywerestoreit(by virtueofrule23),elseweterminateasnomorerulesapply.
hEVALi hx
0 ;x
1 ;:::;x
n i [x
0
7!d2D℄ =) hi hi (15)
N.B.EVALanonlyourin theontrol stakasthesoleelement.
Iftheheadofthestakisanappliation,weneedtounwindandarryonevaluating: hEVALi x 1 :S [x 1 7!x 0 y 1 ℄ =) hEVALi x 0 :x 1 :S (16)
If the head of the stak refers to a funtion of arity m and there are less than m other elements on the stak, wehavethe ase of a funtion applied to too few arguments, f. rules2and9. Inthisase,weneedtotriggertheevaluationofthestritargumentswhih isdoneusingtheEVALARGSninstrution(rule20),wherenisthenumberofotherelements onthestak.
hEVALi hx
0 ;x
1 ;:::;x
n<m i [x 0 7!f m ;x i 7!x i 1 y i ℄ =) hEVALARGS ni hx 0 ;y 1 ;:::;y
n i
(17)
Notethattheargumentsofthefuntion areextratedfromtheappliationsin whihthey reside.
rest of the arguments whih is doneby saving the ontrol-stakpair that represents this appliationonthedump:
hEVALi hx
0 ;x
1 ;:::;x
n>m i [x 0 7!f m ℄ =) hEVALi hx 0 ;x 1 ;:::;x
m i
(hEVALi;hx m
;:::;x n
i):
(18)
Thenal asefor EVALiswhen wehaveafuntion applied toexatlytherightnumberof arguments(thiswithrule22reetsrules4and11inthedenotationalases). Weneedto evaluateanystritargumentsandapplythefuntion.
hEVALi hx
0 ;x
1 ;:::;x
m i [x 0 7!f m ;x i 7!x i 1 y i ℄ =)
hEVALARGS m;APPLYi hx
0 ;y
1 ;:::;y
m ;x m i (19)
Note that aswell as unpaking the arguments to the funtion, we keepx m
, the root of theprogram,asthelast elementofthestak. It isthisvariablethat willbeupdatedwith theresultof applyingf to itsarguments. Inpartiular, ifm=0,that is f is aConstant AppliativeForm(CAF),thenitisthevariablereferringtothefuntion itselfthatwill be updatedwiththeresult.
Wenowneedtogivethestatetransitionrulesfortheotherinstrutions. First wehave EVALARGS whih triggersthe evaluation of any strit arguments, f. theA meta-funtion (rule13).
EVALARGS n:C x
0 :y
1
:::::y nm
:S [x
0
7!f :: 1 ::: m !℄ =) e 1
++ ::: ++e n
++C x
0 :y
1 :::::y
n :S where e i
= hEVALITH ii; if i
=s = hi; otherwise
(20)
TheEVALITHi triggerstheevaluationtheith elementofthestak(wheretheheadofthe stakisthe0thelement)inanewstate:
EVALITH i:C x
0 :x
1
:::::x i :S =) hEVALi hx i i
(C ;x 0
:x 1
:::::x i
:S):
(21)
updatingtheroot oftheprogramandevaluatingtheresultifneessary.
hAPPLYi hx
0 ;y
1 ;:::;y
m ;x
m i [x
0
7!f :: 1
::: m
!℄
=) C hx
m i update
0 x
m r
where (r;
0
) = f( ;y 1
;:::;y m
)
C = hi; if =s = hEVALi; otherwise
(22)
wherethefuntion update istheonedenedin equation12.
Thenalruleonernstheasewhenthe ontrolstakisemptybut wehaveprevious statesonthedump. Inthisase,werestoretherst previousstateand ontinue. Thisis similarto returningfrom aproedureallinanimperativelanguage.
hi S
0
(C ;S): =)
C S
(23)
Notethat wethrowawaytheoldstak,i.e.,wedon'tin anyway`return'avalue.
4.1 An Example
Supposewehavetwoprimitivefuntions,plusandtimes,bothofstritnessss!sgiving theobviousresult,andafuntion square denedsuhthat:
square::s!l square( ;x)=txx
where [t7!times℄
(24)
So, square returnstheatual appliation,ratherthan theresultof doingthe appliation. Toevaluatesquareplus34,werstneedaninitialheap, :
=fa7!times;b7!square;7!plus;d7!3;e7!4;f 7!d;g7!f e;h7!bgg
andthenneedtoupdatethisheapw.r.t. evaluatingh. Ourinitialmahinestate(i.e.,the onepassedtoT)is:
state=(hEVALi;hhi; ;hi)
andthetransitionsequeneis:
state =) (hEVALi;hb;hi; ;hi)
=) (hEVALARGS 1;APPLYi;hb;g;hi; ;hi) =) (hEVALITH 1;APPLYi;hb;g;hi; ;hi) =) (hEVALi;hgi; ;h(hAPPLYi;hb;g;hi)i) =) (hEVALi;hf;gi; ;h(hAPPLYi;hb;g;hi)i) =) (hEVALi;h;f;gi; ;h(hAPPLYi;hb;g;hi)i)
=) (hEVALi;hdi; ;h(hEVALITH 2;APPLYi;h;d;e;gi);(hAPPLYi;hb;g;hi)i) =) (hi;hi; ;h(hEVALITH 2;APPLYi;h;d;e;gi);(hAPPLYi;hb;g;hi)i) =) (hEVALITH 2;APPLYi;h;d;e;gi; ;h(hAPPLYi;hb;g;hi)i) =) (hEVALi;hei; ;h(hAPPLYi;h;d;e;gi);(hAPPLYi;hb;g;hi)i) =) (hi;hi; ;h(hAPPLYi;h;d;e;gi);(hAPPLYi;hb;g;hi)i) =) (hAPPLYi;h;d;e;gi; ;h(hAPPLYi;hb;g;hi)i) =) (hi;hgi; [fg7!3+4=7g;h(hAPPLYi;hb;g;hi)i) =) (hAPPLYi;hb;g;hi;
0
= [fg7!3+4=7g;hi) =) (hEVALi;hhi;
00 =
0
[fi7!ag;h7!igg;hi) =) (hEVALi;hi;hi;
00 ;hi) =) (hEVALi;ha;i;hi;
00 ;hi)
=) (hEVALARGS 2;APPLYi;ha;g;g;hi; 00
;hi) =) (hEVALITH 1;EVALITH 2;APPLYi;ha;g;g;hi;
00 ;hi) =) (hEVALi;hgi;
00
;h(hEVALITH 2;APPLYi;ha;g;g;hi)i) =) (hi;hi;
00
;h(hEVALITH 2;APPLYi;ha;g;g;hi)i) =) (hEVALITH 2;APPLYi;ha;g;g;hi;
00 ;hi) =) (hEVALi;hgi;
00
;h(hAPPLYi;ha;g;g;hi)i) =) (hi;hi;
00
;h(hAPPLYi;ha;g;g;hi)i) =) (hAPPLYi;ha;g;g;hi;
00 ;hi) =) (hi;hhi;
000
[fh7!77=49g;hi)
In the nal state, the variable whih referredto the root of theoriginal appliation now refersto49,whihistheresultofsquare(plus 34).
5 An Implementation of the AAM
Wehooseto implement aversionoftheAAM, usingtheabovesemantirules, usingthe programminglanguageJava[8℄. Using Javahasseveraladvantages:
Javaisplatformindependent.
Javaaninterfaewithotherlanguages,inpartiularCandC++,usingtheJNI[10℄.
Javahasabuilt-ingarbageolletor.
WehaveaompilerforthelazyfuntionallanguageGinger[9℄whihgeneratesJava lassles[11,12℄.
OurapproahistorepresentthevariousomponentsofanAladinprogramasJavalasses.
5.1 Representation of Aladin Programs
orVetorbut weusean array asitenablesus to perform ertainoperations eÆiently). The Heapisa ombinationof theobjetheapof theJVM plusahash tablein whih we anlookupfuntionsbytheirname. FinallytheDump, whihin thesemantisisusedto simulate reursion,isimplementedbyatualreursioninourimplementation.
Thedenitionofprogramsasgivenindenition5suggeststhatweimplementprograms asalass hierarhyasseenin Figure 4. Note that someofthese lassesareonly usedby theompiler. (seeSetion 8). AllprogramsarerepresentedassublassesoftheProglass:
publi abstrat lass Prog { // ...
}
Variablesarerepresentedusing theVarlass:
publi final lass Var extends Prog { publi Prog value;
// ... }
where the eld value holds the value of the variable. Data objets are represented by instanesofsublassesoftheDatalass:
publi abstrat lass Data extends Prog { // ...
}
In partiular, the ve basitypes | integers, reals, haraters, booleans and strings | are representedbythe lassesInt,Real, Char,Booland Strrespetively. Funtions are representedbyinstanes ofsublassesoftheFuntionlass:
publi abstrat lass Funtion extends Prog { publi String pak = "";
publi String l = "";
publi String short_name = ""; publi int arity = -1;
publi StritnessSig stritness;
publi final boolean stritIn(int i) { // ...
}
publi final boolean hasLazyResult() { // ...
}
publi abstrat Prog primApply(Var[℄ args); }
extends
implements
CompileTimeFunction
CFunction
RunTimeFunction
Let
StrictnessSig
App
Object
Ident
ABSTRACT CLASS
CompileTimeApp
KEY
FINAL CLASS
CLASS
INTERFACE
RuntimeException
EvaluationException
fp.gingerc
Func
AladinFunc
java.lang
Var
fp.aladin
Int
Real
Char
Bool
Str
AAM
Aladin
AladinCompiler
VarStack
Prog
Orderable
Num
Logical
GingerFunction
Function
Data
publi Var funtor; publi Var arg; }
Classeswhoseinstanesanbeombinedinarithmetiexpressions,e.g.,addition, subtra-tion,et., implementtheNuminterfae; lasseswhoseinstanes anbeorderedimplement theOrderableinterfae;whilelasseswhose instanesanbeombinedin logial expres-sions,usingonjuntionanddisjuntionforexample,implementtheLogialinterfae.
Theuserisfreeto had hisorherown types,provided that theyarerepresentedusing lasseswhih are sublasses ofthe Proglass. Inthease ofuser-dened types, theonly waytoonstrutanddeonstrutinstanesofthemisviafuntionalls: thereisnospeial syntaxsuhastheuseof dataand|onstrutsandpattern-mathingin Haskell.
The main evaluation mehanism is ontained in the VarStak lass whih is used to represent theAladinstak. Thefuntion lookup table is held asastati eld of theAAM lasswhih,foronveniene,willbesublassedbythelasseswherewedeneourprimitives. Eah of these primitives will be arepresentedby astati Javamethod (as in our Ginger ompiler [11, 12℄) whih is reeted using the java.lang.refletpakage as a Method objetwhih isstoredasamemberoftheFuntionlass. Thesemethods takeanumber of VarobjetsasargumentsandreturnavalueoftypeProg.
5.2 The Evaluation Mehanism
TheevaluationofaprogramistriggeredbyaalltotheevalmethodoftheVarobjetthat refersto theprogram wewish to evaluate. This method reatesanewstakand triggers thetransformationofthestak(f. themeta-funtionFdenedin equation14)is dened asfollows:
publi Prog eval() {
(new VarStak(this)).transform();
return get(); }
Foronveniene, themethod returnsthe nalvalueof thevariable usingthemethodget (whih short-iruitshainsof Varobjets).
ThemethodtransformintheVarStaklassrepeatedlytransformsthestakusingthe semantirules15{23as aguide. Thismethodstartsasfollows:
publi void transform() throws EvaluationExeption { boolean eval = true;
while (eval) { Var v = head();
Objet head = v.get();
Transformationofthestakwill terminatewhentheevalag issetto false. Themethod headreturns,withoutpopping, theVarat thetopof thestak. Ifthevalueofthis objet isanAppthenwepushitsfuntorontothestakandontinue(f. rule16):
weneedtoevaluateanystritones andterminateevaluation (f. rule17):
else if (head instaneof Funtion) { Funtion f = (Funtion) head; int no_args = ount - 1;
if (no_args < f.arity) { // rearrange the stak rearrange();
// get the atual arguments and evaluate the strit ones eval(f, getArgs());
eval = false; }
Themethod rearrangerearrangesthestakasin rule17(sothat wehavethearguments to theappliation ratherthantheappliationsthemselvesonthestak)whilethemethod getArgs opies these argumentsinto an array. The evaluation ofthe strit argumentsis donebythebinarymethod evaldened as:
private void eval(Funtion f, Var[℄ args) { for (int i = 0; i < args.length; i++)
if (f.stritIn(i + 1)) args[i℄.eval(); }
Thismethodreetsthetransformationsdenedinrules20and21. Evaluationofthestak isnowstoppedbysettingevaltofalse.
Ifwehavetoomanymanyargumentsforthefuntionpresent,asinrule18,weevaluate the inner appliation by popping the appropriate elements from the stak (the funtion itself andtheorret numberof arguments) andforming theseinto anewstakwhih we then transform. One this newstak hasbeenfully evaluated, we ontinuetransforming theoriginalone,theheadofwhih willbetheresultoftheevaluatingthenewone.
else if (no_args > f.arity) {
VarStak inner = partition(f.arity);
inner.transform(); }
Themethodpartitiondoesthejob ofsplittingthestakup.
Ifwehavetheexatnumberofargumentsthatthefuntionrequiresweantriggerthe appliationofthefuntion (f. rules19and22).
else {
// exatly the right number of arguments Var root = elements[0℄;
Var[℄ args = getArgs();
// evaluate the strit arguments eval(f, args);
// lear the stak of all but the root ount = 1;
// apply the funtion and update the root (0th index of elements). Prog res = f.primApply(args);
root.update(res);
// the root is now the sole element of this stak elements[0℄ = root;
ount = 1;
// keep evaluating if f has a lazy result eval = f.hasLazyResult();
} }
The atual arguments of the stak are held in the array elements and the number of elements on the stak is stored in the variable ount; the head of the stak is held in elements[ount - 1℄ and its last element, the root, in elements[0℄. The methods hasLazyResultandprimApplyareexplainedinSetion6.
Themethodupdateof Vardealswiththeupdatingofvariablewith anewvalue. The methodlookstoshort-iruitanyhainsofvariableswhenavariableisupdatedwithanother variable. Ifthevalueat theend ofthehainannotbefurtherevaluated,i. e.,itisadata objetofafuntion ofaritygreaterthanzero,thethevariableweareupdatingisupdated with thisvalue,notthe variablethat referredto it. This issafeassinethevalueannot befurtherevaluatedweareinnodangerofrepliatingwork.
publi final void update(Prog p) {
// find the end of the indiretion hain Var v = this;
while (v.value instaneof Var) v = (Var) v.value;
if (p instaneof Var) {
// might be able to short-iruit any hains Prog p_value = ((Var) p).get();
if (p_value instaneof App) v.value = p_value;
else if (p_value instaneof Funtion)
v.value = (((Funtion) p_value).arity == 0) ? p : p_value; else
v.value = p; }
Notethatitisthevariableattheendoftheindiretionhainthatisupdated(seethetext aompanyingequation12).
6 Primitives
As mentioned above, ourbasimehanismfor implementingprimitivesis the stati Java method. In this setion weshall only dealwith how theuser writes suh primitives and how primitives in written in dierent languages are handled by Java. The mehansim of importing primitives is handled in Setion 7. Sine Aladin is essentially a funtional language,itisexpetedthattheusermakestheprimitivesdenedreferentiallytransparent, that is,depend onlyonthevalueoftheirarguments.
Eah primitive is represented by an instane of a sublass of the Funtion objet. Referring bak to the dention given in Setion 5.1, the elds pak, land shortname representthepakage,lassandshortnameofthefuntion;arityitsarityandstritness its stritnesssignature. The method stritInreturnswhether thefuntion is strit ina ertainargument(indexingstartingat1)andhasLazyResultreturnswhetherthefuntion hasalazyresult. Finally,primApplyprimitivelyappliesthefuntiontothegivenarguments
6.1 Java and Aladin Primitives
EahprimitivethatiswritteninJava(andalsoAladinsineweompileAladindenitionsto Javamethods|seeSetion8)isrepresentedbyaninstaneoftheRunTimeFuntionlass. This has a eld of type java.lang.reflet.Method whih reets the (stati) method wheretheatualodeisstored. Toprimitivelyapplysuhafuntion toanumberof argu-mentsmerelyrequiresapplyingtheinvokemethodfromtheMethodlasstothearguments.
publi lass RunTimeFuntion extends Funtion { publi Method app_rule;
publi Prog primApply(Var[℄ args) {
return (Prog) app_rule.invoke(null, args); }
}
Note thatprimApplyonlyreturnsthe resultrather thantheupdatedheapasin 6asany updatesto theheapwillbedoneglobally.
TheatualwritingoftheJavaodeanbesplitintothree parts:
1. ExtratsomeorallofthevaluesfromtheVarobjets.
2. Dotheatualworkinvolved.
3. WraptheresultinaProgobjetifneessaryandreturn.
Forexample,onsiderthemethod oppluswhihistheprexformof+(seeSetion7.2.2).
return ((Num) a).plus(b); else
throw new EvaluationExeption("Can't add " + a + " to " + b); }
Note that unlike in the semantis we do not have to pass the Aladin heap as the rst parameterasitalreadyavailableasastatipublieldoftheAAMlass.
Werstgetthevaluesof xandywhihareplaedinaandbrespetivelyusingtheget method. This presumes that the funtion has beendelared strit in both itsarguments (seeSetion 7.3);ifnotthenweanusethemethodevalin plaeof get. Ifit ispossible to addsomethingto a,i.e.,aisaninstaneofalasswhihimplementsNum,instanesof lasseswhih implementNum, we allthemethod plus, else wethrowanexeption. The main work isdoneinside theplusmethod. Forexample,in theIntlass, plusis dened asfollows:
publi Prog plus(Prog n) { if (n instaneof Int)
return new Int(value + ((Int) n).value); else if (n instaneof Real)
return new Real(value + ((Real) n).value); else
throw new EvaluationExeption("Can't add " + this + " to " + n); }
Thismethod letsusaddbothIntsandRealsto Ints,givingusmixed-modearithmeti. Asanexampleofafuntiontakingalazyargument,onsider opandwhihistheprex formof &. Thishasadenition similarto op plusbut itisdelaredtohavealazyresult andbelazyinitsseondargument:
publi stati Prog _op_and(Var x, Var y) { Prog a = x.get();
if (a instaneof Logial) return ((Logial) a).and(y); else
throw new EvaluationExeption("Can't take the logial onjuntion of " + a + " and " + y);
}
Note that asthe seondargumentislazy, wepassyasavariable anddon't getitsvalue. Thebulkof theworkisdoneelsewhere;if aisaBoolwehave:
publi Prog and(Var v) {
return (value) ? (Prog) v : (Prog) Bool.FALSE; }
Prog b = v.eval();
if (b instaneof Real) { double v = ((Real) b).value;
return Math.min(value, b); }
else
throw new EvaluationExeption("Can't take the logial onjuntion of " + a + " and " + y);
}
6.2 C Primitives
Implementing primitives in C relies heavily on the Java Native Interfae [10℄. Eah C funtion, whih originates from some shared dynami library, has a orresponding Java method delaration whih is used by Aladin to interfae to that funtion, as with the standarduseofnativemethodsinJava(seeSetions7.4.2and8.5formoredetails). Thus, to Aladin, aCprimitiveis thesameasa JavaorAladinone(there isa CFuntionlass forrepresentingprimitiveswritten inC,butthis isonlyused atompiletime).
TheatualodefortheprimitivesfollowsthepatternforwritingprimitivesinJava. For example,weandene thefatorialfuntionin Casfollows:
JNIEXPORT jobjet JNICALL Java_update_fa (JNIEnv *env, jlass l, jobjet var) {
/* get the value of v */
jlong value = getInt(env, var);
/* do the atual work */ jlong f = 1;
jint i;
for (i = 2; i <= value; i++) f *= i;
/* wrap the answer in an Int */ return makeInt(env, f);
}
Thesomewhatinvolved-lookingprototypeforeahfuntionisgeneratedbyAladinfromits stritnesssignatureusingthejavahutilityandplaedinaCheaderle. Thisanthenbe opiedbyutandpasteintothe.lewheretheodeistomaintainonsistenyandsave typingaompliatedexpression.
argumentsofthefuntion,in thisasewehavejust one.
ThefuntiongetIntgetsthevalueofavariablewhihmustbeaninteger(weareusing Javalongs to representintegers, henewe assign thevalueto ajlongtype). This works byallingtheequivalentmethodin Java:
jlong getInt(JNIEnv *env, jobjet v) { jobjet Var = getVar(env);
jmethodID I = (*env)->GetMethodID(env, Var, "getInt", "()J");
/* get the value of var */
return (*env)->CallLongMethod(env, v, I); }
This odehasto ndthe Varobjet,getan IDfor itsgetIntmethodand nally allit. Itisdenedinaseparatesharedlibrary(libAladin.soinUNIX)whihmustbelinkedin when theuserompiles theirode. There aresimilar methods |getReal,getBool,et. |denedinbothJava(asmethodsoftheVarlass)andinC(asglobalfuntions)aswell asageneralget funtion (whih weused whenwriting primitivesin Java) whih returns thevalueofanvariableasaProg,whihisrepresentedasavalueoftypejobjetinC.If theuserneedstoevaluatethevariable,thentheyanusethefuntionseval,evalInt,et. Afteromputing the fatorialweneed to wrapthe result(a jlong) in an AladinInt objet. ThisisdoneusingthemakeIntfuntion:
jobjet makeInt(JNIEnv *env, jlong val) { jobjet Var = getVar(env);
jmethodID ConsInt = (*env)->GetMethodID(env, Var, "<init>", "(J)V");
/* Invoke and return */
return (*env)->NewObjet(env, Var, ConsInt, val); }
The steps take are similar to thegetInt funtion. We have awhole familyof funtions to makeAladin programs from eah primitiveJava/C type. Forexample, makeReal and makeApponstrutrealsandappliationsrespetively.
6.3 Primitives in Ginger
EahprimitivewritteninGingerisrepresentedbyaninstaneoftheGingerFuntionlass:
publi lass GingerFuntion extends Funtion { private fp.ginger.Fun ginger_funtion; }
InsteadoftheappruleeldfoundintheRunTimeFuntionlasswehaveanobjetofthe Funlass(weexpliitlyqualify eah lassfrom thefp.gingerpakagetomakeitlear where thingsare omingfrom andbeausethere aresomenamelashes betweenobjets) reetingtheJavamethodthattheGingerodehasbeenonvertedto(see[12℄fordetails onhowthisisdone). TheprimApplymethodisimplementedtousethiseld:
gargs[i℄ = args[i℄.toGinger();
Objet g_res = ginger_funtion.apply(gargs); g_res = fp.ginger.Node.eval(g_res);
return fromGinger(g_res); }
Before alling thefuntion with thegivenarguments, theargumentsin questionmust be onvertedtoaformatGingerwillreognise,andsimilarlywemustonverttheresultbak intoAladin. SineAladinandGingerarebothfuntionallanguagesthisonversionisfairly straightforward,withaoupleofaveats.
6.3.1 PreventingUnneessary Conversions
Sine Ginger is lazy, it ispossiblethat anargument, orapart of it, may passthrougha alltoaGingerfuntion ompletelyunaltered. ConvertinganAladinprogramtoaGinger objetinvolvesthereationofanewanddistintobjet,similarlywiththereverseproess. Suppose we havean Aladinprogram a whih is passedto aGinger funtion f; a will be onverted to aGinger funtion g, say. Suppose now that g is passedbak aspartof the result of the Ginger funtion (for instane as part of a list); it will be onverted to an Aladin objet a
0
, say. So,a and a 0
arereally the sameobjet,but during theonversion proess they havebeome divored from eah other. In partiular, if we evaluate a then this evaluation is not reeted in a
0
. This an haveaserious eet onperformane. For instaneonsider thefollowingGinger program.
lists x = [x..℄ : lists (x + 1);
hdlists n = let
ns = map hd (lists 0); in
if n == 0 then ns
else
take n ns endif
endlet;
Althoughhdlistsnormallyrunsin lineartimew.r.t. theparamtern,ifweimport itinto Aladinthentheaboveonversionproblemslowsitdowntoexponentialtime.
AlthoughtheonversionofAladinobjetstoandfromGingerisforthemostpart straight-forward, onverting Aladin funtions to Ginger is slightly more omplex. To solve this problemwerepresentAladinfuntions inGingerusingthelassAladinFun,asublassof theGingerfuntion lass,Fun.
publi lass AladinFun extends Fun { proteted Var al_fun;
publi Objet apply(Objet[℄ as) { Var v = al_fun;
for (int i = 0; i < as.length; i++) v = new Var(v, Prog.fromGinger(as[i℄));
v.eval();
return v.toGinger(); }
}
This lassstoresasamembertheoriginalAladinfuntion (or rather, aVarobjetwhih referstoit). WhenGingerappliessuhafuntion,byallingitsapplymethod, weforma newAladinappliation byonverting thepassedargumentsfrom Gingerto Aladinwhih are given as arguments to the original Aladin funtion. We then evaluate this funtion usingAladin,onverttheresultbaktoGingerandthenreturn.
7 A Sripting Language for Aladin
Toenable us to write programs, we need atop-level languagewhih we anprogram in. Thislanguageshouldletusimportprimitivesfrom avarietyof souresandombine them into programs. We hoose to adopt a subset of the funtional language Ginger [9℄ (we basiallyomitloalfuntiondenitions)whihaddedonstrutsforspeifyingthestritness of funtionsand anenhanedsyntaxfor importingprimitives. The extendedBNFof this languageisasfollows:
hsripti ::= hpakagedei?hdeli
hpakagedei ::= pakagehjavaidi;
hdeli ::= hdefijhimportijhidihstritsigi
himporti ::= himi(hidihstritsigi?);
himi ::= importhlassijimport"hlenamei"jimportghlassi
hdefi ::= hidihidi =hprogi; hprogi ::= hletijhsimpleprogi+
hleti ::= let hidi = hprogi in hprogi endlet hsimpleprogi ::= hjavaidijhdataij(hprogi)
hdatai ::= hintijhoatijhboolijhharijhstringi
hjavaidi ::= (hidi .) hidi hpakagei ::= hjavaidi
hlassi ::= (hpakagei.)?hidi
where id isanyvalid Javaidentierontainingno period (`.')separators,andlename is alegallename,thesyntaxofwhihisdependentontheoperatingsystemwearerunning under. An Aladinsriptis thusan optional pakagedelarationfollowedby anumberof delarations. Thesedelarationsare:
Import delarations usedtoimportprimitivesfrom alass.
Stritness delarations usedtospeifythestritnessofaprimitive.
Denitions usedtospeifyaprimitivefuntionbygivingadenitionwhihonstrutsa graphfromitsargumentsandotherprimitives.
EahsriptlewillbeappenedwiththesuÆx`.as'. AswithourGingerompiler[11,12℄, weompilesriptswritteninthislanguageintoaJavalassle,translatingeahdenition intoastatiJavamethod,andgeneratingJavaodetodealwiththeimportingoffuntions andthesettingoftheirstritnesses.
7.1 Pakage Delarations
A pakagedelaration, whih must be therst statement ofan Aladinsript,followsthe same syntax aspakagedelarations in Java and has the same meaning. All primitives dened inthisle willbeplaedinside alasswithwill bein thepakagedelaredbythe user. Ifnopakagedelarationismadethenthenemptypakageisused. Forinstanethe delaration:
pakage fp.aladin;
plaesallthefollowingdenitionsin thepakagefp.aladin.
7.2 Denitions
fib n =
if n == 0 then 1 else
let
f1 = fib (n - 1); f2 = fib (n - 2); in
f1 + f2; endlet endif;
SeeSetion7.3formoredetails onstritnesssignatures.
Thisdenitionmerelytakesitsargumentsandproduesthegraphdesribedinits left-handside,henewehavetoreturnalazyresultaswewantthegraphto beevaluated. No evaluationorompileroptimisationsareperformed,thesebeinghandledbytheevaluation mehanismdened in the previous setion: the onstrution and evaluation of programs areompletelydivoredinthesriptinglanguage.
7.2.1 Funtion Names
Sine our programs are ultimately represented by Java lasses, it follows that funtion namesin Aladinfollowthesamesyntax astheydoin Java. Inpartiularafuntionname hasthreeparts:itsshortname,itslass,anditspakage. Wemayrefertoafuntioneither by its short name, its lass plus its short name (separated by a period), or its pakage plusitslass plusitsshort name(againseparatedbyperiods). Forexample,thefuntion fooin thelass Barin the pakagefp.aladinanbereferredto aseither foo, Bar.foo orfp.aladin.Bar.foo. Of ourse,funtions in dierentlassesmayhavethesameshort name; todierentiate themweadopt thepoliythat wehoosethelast dened/imported one. Forexample,iffooisalsodened inthelassDoewhihisimportedafter thefooin BarthentheshortnamefooreferstotheoneinDoeandnotinBar. Ifwewishtousethe versionin Barthenweanalwaysqualifythenamefurther bywritingBar.foo. Thishas theobviousextensiontofuntionsandlasseswiththesamenamesbutdierentpakages.
7.2.2 InxOperators
0 ++ oplistat N/A : oplistons N/A
1 | opor Logial.or
2 & opand Logial.and 3 == opeq Objet.equals
~= opne Objet.equals < oplt Orderable.lt <= ople Orderable.le > opgt Orderable.gt >= opge Orderable.ge 4 + opplus Num.plus
- opminus Num.minus 5 * optimes Num.times
/ opdivide Num.div % opmodulus Num.mod 6 ^ opexp Num.exp 7 . opompose N/A 8 ! oplistindex N/A
9 ~ opnot Logial.not
Table1: Aladininxoperatorsandtheirprexform
7.2.3 Conditionals
As with inxoperators,the Gingerstyleifsyntax, whihis adopted to redue exessive braketing,isonvertedtoaprexfuntion appliation. Theexpression:
if a 1
then 1
elsif a 2
then 2
::: elsif a n
then n
else d endif isonvertedintotheprogram:
ifa 1
1
(ifa 2
2
(:::(ifa n
n
d):::))
Wherethelatterifis athree-argumentfuntion whihreturnsitsseond argumentifits rstevaluatesto trueanditsthird otherwise.
7.2.4 Lists
Wealsoallowtheuseofthestandardsquarebrakettodenotelists, withthelist [x
1 , x
2
, :::, x n
℄
beingtranslatedintomultipleappliationsoftheonsfuntion: x
1 : x
2
: ::: : x n
: [℄
[℄ oplistempty [a..℄ froma
[a..b℄ fromToab [a,b ..℄ fromThenab [a,b .. ℄ fromThenToab
Table2: Aladin`dot-dot'listsandtheirprexform
7.3 Stritness Signatures
A stritness delaration delares the stritness of a primitive funtion's arguments and result. Iftheprimitivein questionis denedin thesript, thenthissignature anappear anywhere in the sript but must be given; if the primitive is imported then a stritness signatureanbegivenintheimportdelaration(seeSetion7.4)inwhihaseitoverrides theoriginalsignature(ifthere wasone).
Anargumentorresultis eitherstrit, denoted byans, orlazy, denotedby anl. The argumentsofaprimitivedenedinastritnesssignatureareseparatedusingthesymbol*, and theargumentsareseparatedfrom theresultby thesymbol->, whih ispresenteven iftheprimitiveinquestiontakesnoarguments. Itisanerrorto giveastritnesssignature to a non-funtion, or to a funtion whih is neither imported nor has no denition. As anexample,weangivethestritnessoftheprimitivesimportedfrom thelass List(see Setion 7.4):
import fp.aladin.lib.List
_op_list_ons :: l * l -> s _op_list_empty :: -> s _op_list_index :: s * s -> s _op_list_length :: s -> s isEmpty :: s -> s hd :: s -> l tl :: s -> l
Thus oplistons(theprexformof:,seeabove)takestwolazyargumentsandreturns a strit result; op listempty returns a strit result; oplistindex takes two strit argumentsand returns a strit result; op listlength and isEmpty takea strit result and returnastrit result;and nally hdand tltakeastritargumentandreturn alazy result.
Thenumber of arguments referredto in astritness signature referto thenumber of expliit argumentsgiven,notto anyimpliedby-onversion. Forinstane,ifwedene:
hd1 = hd;
then the stritness signature of hd1 is -> s (sine it takes no arguments and returns a funtion)and notthatof hd(s -> l).
7.4 Import Delarations
usingtheimportgdelaration;andprimitivesfrom C/C++bytheimportdelaration.
7.4.1 ImportingAladin and Java Primitives
As weshallseein Setion 8,weshallompileAladindenitionsinto statiJavamethods, sotheimportproedureforprimitivesdenedinAladinandJavaisthesame. Theimport delarations arewritten aspartof thestati initialiserofthe Javalassgenerated bythe Aladinompiler(seeSetion8.4)andhenethewhenthelassisrstloadeditwilltrigger the import proedure. In partiular, anyimportsdone in thelass weare importing will bedonerst.
The rst ode inside the stati initialiser reates the funtion, setting its stritness signature and inserting it into the heap, but for the moment leaving its app rule (see Setion6.1)nullforthemoment. Asanexample,wehavethefollowingfromstdlib.java the ode generated from stdlib.as where the arithmeti funtions, amongst others, are dened:
stati {
put("fp.aladin.lib", "Operators", "_op_plus", CONST_0); put("fp.aladin.lib", "Operators", "_op_minus", CONST_0); put("fp.aladin.lib", "Operators", "_op_times", CONST_0); put("fp.aladin.lib", "Operators", "_op_divide", CONST_0);
// ... }
Thestatiputmethod(inheritedfromtheAAMlass)reatesanewfuntionfromits argu-mentsand insertsitintotheheap. Therstthree argumentsrepresentthepakage,lass andnameofthefuntiontobereated. Thelastargumentisthestritnesssignature,whih is reatedonly oneand stored asaprivateeld of the generatedlass (see Setion 8.2). HereCONST0representsthestritnesssignaturess!s.
Aftersetting thefuntions up, wehaveto llin their appruleeld. Thisis doneby goingthrougheahlass,inludingthelassthatisdoingitsimportingsineanyfuntions it denes itself are held in that lass, using the getDelaredMethodsmethod from the java.lang.Classlass andllingin eahfuntion with itsappropriateMethodobjet. If weendupwithanyfuntionswhihwehaveastritnesssignatureforbutnoorresponding Methodthenanerrorhasourred.
7.4.2 ImportingC Primitives
Eah primitivethat is written in C and diretly imported will have hada orresponding Java method header generated in the generated lass le, hene these primitives will be imported by thesamemehanismthat imports Javaand Aladinprimitives. However,we alsoneed toloadin thelibrarieswheretheatualobjetodeanbefound. Thisisdone byloadingeahlibraryusingtheSystem.loadLibrarymethod.
7.4.3 ImportingGinger Primitives
The aim of the ompileris to take analadin sript and translateit into a Javaprogram whih will then be ompiled by aJava ompilerinto aJava lass le. Our ompilerhas threejobs:
1. ToprovideastatiJavamethod foreahprimitivedenedin thesript.
2. Tosetthestritnessofeahfuntion denedinthesriptandanyimportedfuntion whosestritnessis redenedin thesript.
3. Toimportallthefuntionsspeiedin thesript.
The lattertwojobs will be aomplishedbyputting the odethat ahievestheobjet in astatiinitialiserofthereatedlass(seeabove). Thismeans thatwhen thelass isrst referened (usuallyby animportdelaration)the rstthing that itwill do isimport the funtions itneedsandset theirstritnesses.
8.1 Compiling Sripts
Toompileasriptweneedthefollowingparameters:
,thelasstoreate(derivedfrom thenameofthesript).
p,thepakagetoplae thereatedlassin,delaredusing pakage(if nosuh de-larationthepis settotheemptystring).
ss,thesetofdistint stritnesssignaturesused inasript. s,thesetofdistintonstantsusedin asript.
fs,theset offuntionsdened in thesriptwiththoseimportedintothe sriptwho havetheirstritnesssignaturesetorover-ridden.
ls, the lasses ontaining primitives dened in Javaand Aladin diretly imported intoasript.
gs,thelassesontainingprimitivesdenedinGingerdiretlyimportedintoasript. ls, the shared objet libraries ontainingprimitivesdened in C/C++ diretly
im-portedinto asript.
ds, the funtions dened in the sript (with their denitions) plus any primitives denedinCwhiharediretlyimported.
TheompilationshemeP reatesaJavaprogramusing theseparameters Ppsss fslsgslsds = pakage p;
import fp.aladin.*;
publi final lass extends AAM f S sss fslsgsls ds
g
Wedonotreateaseparateobjetrepresentingalltheonstantsandstritnesssignatures in alass. Rather foreahdistint onstantwereate just oneinstane and storeitasa privateeldof thelasswearereatingandread thiseld wheneverwewantaninstane ofthepartiularonstantorstritnesssignature.
S (s 1
;:::;s m
)( 1
;:::; n
)fslsgsls ds = stati f
1 1 ::: n
n s (n+1)s
1 :::
s (n+m)s m Dfslsgs lsds where
=
1
7!CONSTi;:::; n
7!CONSTn; s
1
7!CONST(n+1);:::;s m
7!CONST(n+m)
Thefuntionompilesaonstantandplaesitinastatiprivateeldofthelassbeing reated:
i=private stati Var CONSTi=new Var();
The Var lass has a onstrutors to onstrut variables whih point to the appropriate program foreahbasi type. Thefuntion s is similar to but it ompilesastritness signatureinstead.
si( 1
::: n
!)
= private stati StritnessSig CONSTi= new StritnessSig(as, r);
where
as = new boolean[℄ fa 1
, :::, a n
g a
i
= true; if
i =s
= false; otherwise
r = true; if =s
= false; otherwise
8.3 Compiling Stritness Delarations
TheDshemedelaresthestritnesssignatureofeahfuntion. Thenalparameterisan environmentdetailingwhihonstantorstritnesssignatureorrespondstoeaheld. For aonstantorstritnesssignature, itsorrespondingeld is().
D(f 1
;:::;f m
where p
i
= pakage(f i
)
i
= lass(f i ) n i = name(f i ) s i = (stritness(f i ))
8.4 Compiling Imports
TheIshemedealswithreatingtheodeneededtoimportthevariouslassesandlibraries. I( 1 ;:::; n )(g 1 ;:::;g
m )(l
1 ;:::;l
k
)ds = importClass(" 1 "); ::: importClass(" n "); importGinger("g 1 "); ::: importGinger("g m "); System.loadLibrary("l 1 "); ::: System.loadLibrary("l k "); g Hds
Note thatthis shemeinludes thebraewhih terminatesthestatiinitialiserstartedby S.
8.5 Compiling Denitions
TheHompilesallthedenitionsinasriptplusreatesheadersforanyprimitiveswritten in Cinto thesript:
H (f 1
;:::;f n
) = Ff 1 ::: Ff n
TheshemeF ompilesanindividualfuntion. IfthefuntioniswritteninCwejustneed todelareanativemethod:
Ff n
=publi final native stati Progf(Var x 1, :::, Var x n); where xiaredummy parameternamesandnis thearityof thefuntion. Eah denition rsthasallitsvariablesrenamedsothattheyarealldistintand thenompiledusing F: F sheme:
F(f x 1
::: x n
= E)
= publi final stati Progf(Var x 1
, :::, Var x n
) f Var v
1 = CD
1 vs; :::
Var v m
= CD m
return RE vs; g
where (h(v
1 ;D
1 );:::(v
m ;D
m )i;E
0
)=E vs=fx
1 ;:::;x
n ;v
1 ;:::;v
m g
Tosimplify matters, allloalvariablesare `oated' to thetoplevelusing the funtion. Thisfuntionsplitsaprogramintoalistofdelarationsandaprogramontainingnolets:
((let v = D in B endlet)C) = ((v;D 0
):ds ++es;P) where
(ds;P) = (B C) (es;D
0
) = D (C (let v = D in B endlet)) = ((v;D
0
):ds ++es;P) where
(ds;P) = (C B) (es;D
0
) = D (BC) = (ds ++es;B
0 C
0 ) where
(ds;B 0
) = B (es;C
0
) = C P = (hi;P)
Inaonventionalompilerwewouldhavetobearefulabouthowfaroutwardsweoated loalvariabledelarationsaswemightendupunneessarilybuildingthegraphofprograms that ould otherwisebeavoided. Forinstane, in aonditional expressiona onventional ompiler an exploit its knowledge of the onditional primitive to build only the graph relatedtothe`true'branhoftheonditionalandignoringalltherest. SineAladinknows verylittleabouthowitsprimitivesworkweanperformnosuhoptimisation,butthisdoes mean wedon't havetobeasarefulaboutwhere weplaeourloalvariable delarations asinaonventionalompiler.
TheRandC shemeompileasimpleprogram. Theydieronlyinhowtheytreatthe outermostpartofaprogramwhen thatpartisanappliation. Ifwehaveaonstantthen wesimplyhaveto loadtherelevanteld:
Cvs=R=()
If we have an identier then we either have a funtion or a variable. We an tell the dierenebyseeingiftheidentierisin theset ofvariablespassedtoC:
Cid vs = id; if id 2vs = get(id); otherwise
Ifwehaveavariablethentheodetoompileisthus thatvariable,otherwisewepresume itisafuntion nameand lookitupin theheapusingthegetfuntioninherited fromthe AAMsuperlass.
If we havean appliation, then the C sheme ompilesthe funtor and the argument usingtheCshemeandthenformsthenintoanAppwhihispointedtobyaVar(ahieved usingthetwo-argumentonstrutorof Var):
Risdenedas:
R(f a)vs=new App(Cf vs, Cavs)
8.6 Compiling the Target Code and Using the Resultant Classes The ode reatedbythe ompileris plaedin a.javalewhih is ompiled into alass le using the java ompiler. If the sript diretly imports any C/C++funtions then javahisrun overthegenerated lass to reatetheheader le dening theprototypesfor theimportedC/C++funtions.
EahlassinheritsamainmethodfromitsAAMsuperlass. Whenthelassisexeuted, using the java interpreterfor example, this method forms anyargumentspresent into a singlestringwhih itpassesthroughtheparsertoobtainasimpleprogram(i.e.,onewith no loal variable delarations) whih it then evaluates. If no argumentsare present then anattemptismadetondanevaluateaCAFnamedmain. Forexample,supposewehave thefollowingexampleinthesriptfoo.as:
import fp.aladin.stdlib; import fp.aladin.gstdlib;
importg bar
lists :: s -> l hdlists :: s -> l;
main = hdlists 10;
where listsand hdlistsareasdened in Setion 6.3. Thenthis sriptisompiled into theJavalefoo.java:
import fp.aladin.*;
publi lass foo extends AAM {
private stati fp.aladin.Var CONST_2 = new fp.aladin.Var(10); private stati fp.aladin.StritnessSig CONST_0 =
new fp.aladin.StritnessSig(new boolean[℄ {true}, false); private stati fp.aladin.StritnessSig CONST_1 =
new fp.aladin.StritnessSig(new boolean[℄ {}, false);
stati {
putGinger("", "bar", "lists", CONST_0); putGinger("", "bar", "hdlists", CONST_0); put("", "foo", "main", CONST_1);
importClass("fp.aladin.stdlib"); importClass("fp.aladin.gstdlib"); importClass("foo");
importGinger("bar");
return new fp.aladin.App(get("hdlists"), CONST_2); }
}
This is then ompiled into the lass foo.lass. The lass fp.aladin.stdlibontains various standard funtions, while fp.aladin.gstdlibontains import delarations and stritnesssignaturesforGingerprimitivesandfuntionsin itsstandardprelude.
Weannowevaluateprograms. Toevaluatemainwesimply passfooasanargument tojavawithnoextraarguments:
gem:~/Aladin/progs> java foo [0, 1, 2, 3, 4, 5, 6, 7, 8, 9℄
Weanalsoapply hdliststoadierentargument:
gem:~/Aladin/progs> java foo hdlists 20
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19℄
Sine we import stdlib into our sript, we have aess to standard funtions suh as arithmeti and omparison operators, and hene we an evaluate programs using these funtions via thefoolass:
gem:~/Aladin/progs> java foo '(3 < 2) | (2 >= 8 + 5)' false
9 Conlusion and Further Work
WehavegiventhedenotationalandoperationalsemantisoftheAladinAbstratMahine and animplementation of themahine, written in Javaand reatinga Java lass. These semantisdetailaverysimplefuntionallanguage,whereeah primitiveanbewritten in anyof Java,C/C++,GingerortheAladinsriptinglanguagethatwedeveloped,andhas thestritnessofitsargumentsandresultspeiedbytheuser.
TheAAMpresentsuswith many possibleavenuesofinvestigation. Ofpartiular on-ernto usis theinvestigationof theeet ofstritnesson thespae/timeperformane of programsandtheuseofpartialandparallelimplementationmethods. TheuseofAladinis obviouslyofusefortheformer;with thelatter,knowingthestritnessoffuntions means weknowwhihparts ofaprogram anbeevaluatedand henewhih parts anbe evalu-ated inparallel orpartially. Thesimpliityofthemahine alsosavesus fromunneessary ompliationsthat arisefrom patternmathing,onditionals, et.
Other possible future projetsusing the Aladinmodel inlude extending therange of sourelanguagesovered,investingtheuseoftypesystemswithAladin,lookingattheuse of logi languages(for example, Prolog)with Aladin, and the integration of Aladin with ObjettehnologiessuhasCORBA(CommonObjetRequestBrokerArhiteture)[14℄.
Referenes
ACMSymposiumofPriniples of ProgrammingLanguages, pp.58{69,1984.
[3℄ S.L.PeytonJones,TheImplementationofFuntionalProgrammingLanguages. Pren-tieHall,1987.
[4℄ P. Landin, \The Mehanial Evaluation of Expressions," BCS Computing Journal, vol.6,pp.308{320,January1964.
[5℄ J.FairbairnandS.Wray,\TIM:Asimple,lazyabstratmahinetoexeute superom-binators,"inFuntionalProgramming Langauges andComputer Arhiteture,no.274 inLNCS,pp.34{45,Springer-Verlag,1987.
[6℄ B.Kernighanand D.Rithie,The CProgramming Language. PrentieHall,2nd ed., 1988.
[7℄ B.Stroustrup,TheC++ProgrammingLanguage. Addison-Wesley,3rded.,1997.
[8℄ K.ArnoldandJ.Gosling,TheJavaProgrammingLanguage.Addison-Wesley,2nded., 1998.
[9℄ M.Joy,\Ginger|A SimpleFuntionalLanguage,"Teh. Rep.CS-RR-235, Depart-mentofComputerSiene, UniversityofWarwik,Coventry,UK,1992.
[10℄ R.Gordon,EssentialJNI: JavaNative Interfae. PrentieHall,1998.
[11℄ G. Meehan, \Compiling funtional programs to Java byte-ode," Researh Report CS-RR-334,DepartmentofComputerSiene,UniversityofWarwik,Coventry,UK, September1997.
[12℄ G. Meehan and M. Joy, \CompilingLazy Funtional Programs to Java Byte-ode." SubmittedtoSoftware| PratieandExperiene,1998.
[13℄ G.MeehanandM.Joy,\AnimatedFuzzyLogi,"JournalofFuntionalProgramming, vol.8,November1998.