The Heap Lambda Machine
This paper introduces a new machine architecture for evaluating lambda expressions using the normal-order reduction, which guarantees that every lambda expression will be evaluated if the expression has its normal form and the system has enough memor…
Authors: Anton Salikhmetov
ZU064-05-FPR heap 9 September 201 8 12:33 Under considera tion for public ation in J. Functional Pr ogr amming 1 The Heap Lambda Mac hine ANTON SALIKHMETO V R TSoft, P . O. Box 158, 10507 7 Moscow , Russia ( e-mail: salikhmeto v@gmail.c om ) Abstract This paper introduces a ne w machine architecture for ev aluating lamb da expressions using the normal- order reduction, which guarantees that ev ery l ambda exp ression will be ev aluated if the expression has its normal form and the system has enough memory . The architecture consid ered here operates using heap memory only . Lambda expressions are represented as graphs, and all algorithms used in the processing unit of this machine are non-recursi ve. 1 Introduction Automated ev alua tion of lambda expressions h as drawn atten tion of many research ers. A number of dif fe rent approa ches to design m achines that directly deal with lambda ex- pressions h as b een p roposed in the literatu re, and the mo nogra ph (Klug e, 2005) giv es a compreh ensive overview of many such designs. W e have noticed that all such machines relied upon quite complicated memory structure and r equired rather intricate m emory ma nagemen t techn iques. T ypically , the m emory is subdivided into se veral function ally different areas. Amon g such areas c an be stacks, en vironm ents, code areas, he aps, and so on . Such arran gements imply the n eed to specify a separate interface to each memo ry subsystem: a stack po inter r egister to keep track of stack u tilization, a dynam ic memor y alloc ator f or h eaps, g arbage collec tors, etc. Besides, conv entional computer memo ry provides just a linear arr ay of ide ntical memo ry cells, each cell being ad dressable by its index in th is array . For such memo ry , it rem ains un clear as to w hich criter ia should be em ployed for partitionin g th e array into f unctionally different parts. These observations motivated us to in vestigate whether it is possible to con struct a machine po ssessing the follo wing two properties. First, the m emory should be u niform, i.e. no subdi vision of the fo rmer in to f unctionally d ifferent pa rts such as a stack and a dynamic memory are a was allowed. Second, we wanted the mem ory manag ement m echanisms to be super-simple, with their algorithmic implementatio n and the interface bein g as minim al as possible. It appears that it is indeed possible to satisfy the requirements men tioned above. Having started from the idea o f graph r eduction, we d esigned the mach ine wh ere the en tire m emory is a unifor m collectio n of sequen tially add ressable blo cks allo cated on d emand. W e have also implemen ted a portable software emu lator of this machine. ZU064-05-FPR heap 9 September 201 8 12:33 2 A. Salikhmetov The memor y manager in our m achine con sists of a single register and thr ee co mmands only . T akin g into accou nt the similarity of o ur memo ry allocator and heap -based dynam ic memory allocator s, we ha ve decide d to refer th is machine to as the Heap Lambda Mach ine. W o rth mentioning he re is also the fact that careful design of the p rocessing u nit a lgorithms allowed u s to a void using garbage collection. The purp ose o f this paper is to describ e the architecture of our machin e an d to demon - strate all vital parts of the emulator . 2 High-Level Desig n and the User’ s V iew of the System The system consists of several units sh own in Fig. 1, the m ain units being the mem ory and the p rocessor . Th e un its can in teract by transferr ing con trol and data as indicated in the block diagram by the arrows. In some cases, un its use c ommon data of the special state type explain ed in Sectio n 5. Con crete structure of th e units depe nds on a par ticular implementatio n of the m achine: in the abstract machin e, th ese are simply algorithm s de- scribed in later sections o f th is paper ; in our so ftware emulator the u nits are C languag e function s; had this machine b een imp lemented in hard ware, each un it would h av e b een a micropr ogram using a set of inter nal r egisters and co mmunicatin g with its neighb ors by asserting electrical signals. Fig. 1 . The architecture of the Heap Lambda Machin e. In the b lock d iagram, F denotes the freehe ad register , E stands f or the e xpr register , an d the state registers are shown with the S letter . ZU064-05-FPR heap 9 September 201 8 12:33 The Heap Lambda Machine 3 The memory in our machine is externally v isible, i.e. th e u ser c an read and wr ite to it. The entity to govern the m emory usag e is th e me mory man ager, consisting of the Allocator and the free head register . The Alloca tor exports the inter faces to initialize th e mem ory as well as to allocate and free its un its. I n the software emulator, the machine memory is modeled via an array o btained usin g the Standard C Library fun ction calloc ; in the abstract machine, the mem ory is an array of identical sequen tially a ddressable blocks. Th e user has to prepar e th e lambda expression using the internal format explain ed in Section 3, allocate a sufficient amou nt of mac hine m emory , load the expre ssion into mem ory , load the memory ad dress wh ere the expression st arts into th e e xpr register , and transfer co ntrol to the Evaluator . The Evaluator is th e entry point to the machin e. When e valuation is over , the user can read the result from th e machine memory s tarting from the address in expr and option ally conv ert it in to a suitable fo rmat. In our software emulato r , th e Evaluator is implemen ted as a C fun ction, so that when th is fun ction returns, this mean s to the caller th at evaluation is com plete. As fo r the ab stract m achine, we do not spe cify a ny particular mechan isms to signal the end of the computation ; if this m achine were im plemented in hardware, such mechanisms would be defined at the hardware design stage. The W alker, Cleaner , Replacer, and Copier units are help er blocks in the p rocessor, and these units are no t intended to be visible to th e user . Their design an d implem entation are described later on. 3 The Memory Model In our machin e, lamb da expre ssions are rep resented as g raphs—this idea has becom e standard after (W adsworth, 197 1). T he mach ine memory conta ining th e lambd a expr ession under ev aluatio n has linear structure and consists o f b locks, each block r epresenting a single nod e of the lambda e xpression graph. A node in the memory is a rec ord o f f our addr ess cells. The first one called par points to the par ent n ode. The secon d o ne is called copy a nd is used during copying of subexpres- sions as well as in o rder to link f ree blocks (see Sec tion 4 belo w). The two remaining cells called fun c a nd arg ho ld the ad dresses o f the subexp ressions, if any . Add itionally , th eir contents define the type of the nod e. In th e usual manner, we have three ty pes of lambda expr ession node s: an application , an abstraction, and a variable. In the case of an a pplication, th e fun c cell points to the operator subexpression, while th e arg cell points to the op erand subexpression —both func and arg cells are non-z ero. For abstractio ns, the func cell points to the functio n bo dy subexpression, and arg contains the null po inter . Finally , for variables, th e fun c cell is zero, arg points to an abstraction node which it is linked with. For example, the a p pl y combinator λ x . λ y . ( x y ) will be represented in the m achine memory as shown in Fig. 2. The well- known issue with nam e clashes (Baren dregt, 1984) f or the variable names is av o ided in our machine a utomatically thank s to th e fact that d ifferent variables are represented as poin ters to different node s. Effecti vely , numeric block a ddresses in our memory model play the role of variable names. ZU064-05-FPR heap 9 September 201 8 12:33 4 A. Salikhmetov Address Cell Expression par copy func arg 1 0 0 2 0 λ x . λ y . ( x y ) 2 1 0 3 0 λ y . ( x y ) 3 2 0 4 5 ( x y ) 4 3 0 0 1 x 5 3 0 0 2 y . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Fig. 2. The memory dump for the a p pl y combinato r . The free variable n odes are represented with null poin ters in the ad dress cells, i.e. bo th func and arg are zer o. W e think that it is con venient to treat the free m emory b locks as nodes that rep resent fictional free variables: indeed, such b locks formally have the type of a free variable n ode. 4 Storage Management Before the lambda expression can be p rocessed, th e machine memo ry shou ld be in itialized as described b elow . In itially , every memor y block is put into th e linked list o f f ree bloc ks similar to that discussed in Section 16. 2 of (Field and Harrison, 1988). T raversing fro m the last blo ck till the first one , the m achine links them into the free nod es list u sing the copy cell as the po inter to the next node. The register called fre ehead is to hold the h ead node of this list and points to ad dress 1 at the b eginning of th e system lifecycle. T he initial state of the machine mem ory is illustrated in Fig. 3. Our software e mulator implements m emory initialization via the reset com mand shown in App endix C. The m achine allocates and frees nodes b y man ipulating th e linked list of fr ee blocks and chang ing the contents o f the fr eehead register accordin gly v ia the fo llowing tw o command s: ge t an d put . If the fr eehead register contains a n on-zer o value, the get c ommand saves the n ode the freehe ad register p oints to and up dates this register by the value in the co py cell o f the Address Cell Expression par copy func arg 1 0 2 0 0 x 2 0 3 0 0 x . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . N − 1 0 N 0 0 x N 0 0 0 0 x Fig. 3. The initial state o f the machin e memory of size N blocks, each b lock rep resenting a fictional free variable. ZU064-05-FPR heap 9 September 201 8 12:33 The Heap Lambda Machine 5 sa ved node. Then, g et zero es out each cell in the sa ved no de and returns it to th e caller . In the case when th e freehead register contains the zero value, which means that th e system is out of free memor y , ca lling get trigg ers a machine exception and ev alutio n is aborted. In turn, the put command takes o ne operand —the addr ess of the bloc k to b e p ut back into the fr ee block s list. Th is c ommand sets the co py cell o f its op erand to the value kept in the free head r egister , then change s the latter to the address received as the op erand. For more details of the system in itialization and sto rage mana gement, p lease see Ap- pendix C. 5 W alking Through the Expr ession T ree Most of cen tral mech anisms in the machine re ly upon the ability to traverse the tree in normal order , wh ich in o ur case m eans that th e function part of an app lication is pr ocessed first. The algor ithm of tre e trav ersing is facto red out in to a sepa rate unit, the fun damen- tal idea behind this unit b eing that of a state. The state consists of the following three compon ents: th e current node address, the address of the parent node of the subexpression being trav ersed, and the direction (fo rth, i.e. tow a rds the child node, or back, i.e. towards the parent). Based upo n th is state, a comm and called walk decides wh ich path should be followed at a particular step, makes this step and retur ns the type of the step chosen: a variable—direction is set to backward, a fu nction part—the current node is changed to the function part, an ar gumen t part—direction is set to forward and th e c urrent node is changed to the argumen t part, go ing back—the curren t no de is cha nged to th e parent no de, or finish—the state is not changed , but the walk comman d ind icates that w alking is complete. Note th at this mech anism is a mod ification of the poin ter rev ersing appro ach explained in Section 11.3. 2 of (Field and Harrison, 1988). Note also that our walking algorithm is non- recursive, he nce using stacks is a voided. Before walking throu gh th e expression tree, it is necessary to in itialize the state u sing a spe cial co mmand called init . Th e initial state has the directio n for th, th e cu rrent no de address poin ting to the sub expression no de, a nd the parent no de a ddress pointin g to the parent of the subexpression . Appen dix B presents the implementation of this unit. Fig. 4 shows an example of traversing th rough the expr ession tre e. He re th e n ode su b- scripts indicate the step numbe rs at which this particular node is trav ersed. s 3 , 4 s 5 , 6 ✱ ✱ ❧ ❧ ( s s ) 2 , 7 λ s . ( s s ) 1 , 8 s 11 , 12 s 13 , 14 ✚ ✚ ✚ ❩ ❩ ❩ ( s s ) 10 , 15 λ s . ( s s ) 9 , 16 ✏ ✏ ✏ ✏ ✏ ❛ ❛ ❛ ❛ λ s . ( s s ) λ s . ( s s ) 0 , 17 , 18 Fig. 4. T raversal order for the t ree repr esenting the Ω combinator . ZU064-05-FPR heap 9 September 201 8 12:33 6 A. Salikhmetov 6 Clearing Subexpressions Clearing o f sub expressions is nee ded afte r the replacement of bound variables with respec- ti ve subexpressions to pu t now u seless blocks back to the free blocks list. T ree walking is the basic mechanism subexpression clearin g is b ased up on. It can be easily seen that g i ven th e tree traversal strategy d escribed above, freeing the child n odes ev ery time wh en the walker has just gone u p will n ecessarily result in freeing the whole tree. F or instance, for the e x pression tree sho wn in Fig. 4, s teps 7, 8, 15, 16, an d 17 are the places where the child nodes are freed. For mo re details ab out impleme ntation of the cl ear comm and describ ed in this Section, please see Append ix C. 7 Copying Subexpressions While re placing th e b ound variables with respecti ve subexpressions, i.e. with the argument part of an applicatio n whose fun ction part is an ab straction, the machine is copying the argument su bexpression u sing the c ommand called copy . T his command uses the walking mechanism as well as the clear co mmand described in Section 6. In c ontrast to cl ear , c opy con siders every value the walk comman d r eturns in o rder to appropriately construct a copy and move throug h the new exp ression being constructed. Construction itself is made on the steps o f th e f ollowing types: an a rgument part, a f unc- tion p art, and an argument. When going back, the pointer to th e c urrent no de o f a new expression un der con struction is chang ed to its p arent. Ea ch of th e steps listed a bove was described in Section 5. The most co mplicated pro blem within the c opy co mmand is that variables in the new subexpression should point to th e correspon ding abstractio ns. Indeed, if th e abstraction nodes ar e just constructed, the com mand shou ld map the po inter in the variable n odes fro m the o ne in the origin al subexpression to those in the copy . In th e mach ine, this prob lem is solved as described belo w . While walking thro ugh the orig inal sub expression u nder copying, two cases o f walk steps are processed in a special manner: a function part and a variable. In the first case, the paren t of the current node in the origin al subexpression is changed: its cop y cell is set to the ad dress of the correspo nding n ode in the n ew su bexpression. Such way , the map ping of old abstractions to the ne w ones is constructed. In th e case of a variable, the copy comm and searches fo r the abstraction th e original vari- able nod e points to by g oing back thro ugh the whole expr ession. When the corre sponding abstraction nod e is f ound and its copy cell con tains a non- zero value, copy sets the arg cell v alue to the value in th e copy cell of the found node. The imp lementation of the copy c ommand described ab ove can be foun d in Ap pendix D. 8 Replacing Bound V aria bles Evaluation o f lambda expr essions req uires replacem ent o f boun d variables in functio n bodies with the copies of arguments. T o make such a copy the machine uses the copy command described in Section 7. As to sear ching for bo und v ariables in a fun ction body , a ZU064-05-FPR heap 9 September 201 8 12:33 The Heap Lambda Machine 7 special com mand called repl ace , which walks the subexpression tree and lo cates boun d variables, is introduced. The replace com mand takes three ope rands, each operand r epresenting a pointer to a subexpression nod e. The first opera nd means the su bexpression where the comman d should lo ok for th e bo und variable which co rrespond s to the ab straction po inted to by th e second on e. Th e third one con tains the subexpression whose copy should be sub stituted for the bo und v ar iable just foun d. After substitution has finished , replace pu ts the bound variable node back to the free blocks list using the put command discussed in Section 4. For more details of replacement algorithm implementation, please see Appendix E. 9 The Evaluation Algorithm In order to evaluate lambda expression in the memo ry , the machine walks throu gh the expression tree and looks fo r no des that can be redu ced. The redu cibility check for a node is pe rformed b y a separate comm and called isre ducibl e , which return s a boo lean value at a subexpression node. The i sredu cible comma nd examin es wheth er the n ode represents an application. If this is the case, it checks if the function part of the application is an abstraction. In the case when both conditions are satisfi ed, the command returns tr ue, otherwise it return s f alse. Implemen tation of this co mmand can be found in Appendix E. When a reduc ible no de is found, this n ode (which is the current o ne from the vie w- point of the walker) is an application having an abstractio n in its oper ator part. Using the rep lace command (Section 8), the m achine makes o ne step of beta reduction . When this step is co mplete, the ap plication nod e, as well a s th e abstrac tion nod e, ceases to exist as part of the expression. Recall that r eplace makes cop ies of the argumen t f or each entry of the bo und variable—that is, the en tire applicatio n op erand su bexpression is not needed anymo re. Hence the m emory allocated fo r th e applicatio n, the abstrac tion an d th e operan d can and should be freed . This is the place wher e th e c lear command d escribed in Sectio n 6 is used: no te that in o rder to clear all these entities pr operly it suffices to zero out the func cell of the abstra ction node and start clearing f rom the node which repr esents the applicatio n. When the curr ent no de re presents an operator part o f an applicatio n, the algor ithm changes the curren t nod e to the paren t becau se the latter may be now the leftm ost outer most redex—such beh avior is the consequence of the fact tha t th e mach ine makes use of the normal- order reduction. For more details ab out implemen tation o f the normal c ommand describe d above, p lease see Append ix F . 10 Conclusions This paper presented a detailed description of th e machine for automated e valuation of lambda calculus exp ressions. Ma jor featu res of this machine inclu de u sing gra phs to rep - resent lambda expressions, a memory manager of ultimate simp licity , and normal or der ev alua tion. The unifo rm stru cture of th e mach ine mem ory and the idea of “th e entire memory is heap” is what distinguishes our approach fro m the ones previously foun d in the literature . ZU064-05-FPR heap 9 September 201 8 12:33 8 A. Salikhmetov All algorithms of the processing unit w ere expo sed in gr eat detail, and the concep t o f the machine has been proven by implem enting a por table software emu lator; for the latter , this paper in cludes th e source co de of all core parts of it in the form o f a C library . In the simplest case, this library will be linked to an application, which provides a human interface to th e machine . Please note that f ull sou rces of the machin e em ulator in cluding an imp lementation o f the hum an in terface are av ailab le as W eb -accessible accompa nying material for this paper . Our fu rther resear ch will c oncentrate on the following topics. First, we will attempt to implemen t lazy evaluation (W adsworth, 1971). Second , we will explore the design of a more sop histicated I/O model r ather th an u sing the entire memory for infor mation ex- change between the machin e and its ou tside world. Of co urse, all a bove e xtensions o f the Heap Lambda M achine are to be done without sacr ificing th e simplicity of its memor y managem ent. A The Library Interface The following is the h eader file machine.h th at d escribes the library inter face and con tains declaration s of all need ed data types, functions, and global variables. In teresting to the library user are the lambd a data ty pe, which represents a p ointer to a no de in the lambda expression graph, the get fun ction, which s hould be called to allocate memory for a n ode, and the n ormal ro utine, w hich nee ds to be called to start the lambda expression ev aluatio n. In this im plementation , the location of the roo t nod e in the lambd a expression gr aph will be used as the argument to the normal routin e. 1 #ifnde f _MACHINE _H 2 #defin e _MACHINE _H 3 4 typede f struct _lambda { 5 struct _lambd a *par, *copy, *func, *arg; 6 } *lambd a; 7 8 typede f enum { 9 END, UP, FUNC, ARG, VAR 10 } path ; 11 12 type def enum { 13 UNRE D, RED 14 } rede x; 15 16 type def enum { 17 FORT H, BACK 18 } dir; 19 20 type def struct { 21 dir wh ; ZU064-05-FPR heap 9 September 201 8 12:33 The Heap Lambda Machine 9 22 lamb da par, expr; 23 } state; 24 25 extern lambda memory, freehe ad; 26 27 void clear( lambda expr); 28 lambda copy(la mbda expr); 29 lambda get(); 30 state init( lambda expr); 31 redex isred ucible (const lambd a expr); 32 void normal (lambd a *expr ); 33 void put(la mbda node); 34 void replac e(lamb da *exp r, const lambda func, const lambda arg); 35 void reset( int size); 36 path walk(s tate *st); 37 38 #endif B The W alker Unit The walker unit c ontains two comm ands: init , which initializes th e state, an d wal k , which steps throug h the tree countercloc kwise, i.e. the fu nction in applications is processed prior to the argument. 1 #inclu de "machin e.h" 2 3 state init (lambd a exp r) 4 { 5 sta te st = {FORTH, expr->par , exp r}; 6 7 ret urn st; 8 } 9 10 path walk(s tate *st) 11 { 12 la mbda expr = st->expr ; 13 14 if (BA CK == st->wh) { 15 lambda par = expr->p ar; 16 17 if (st->par == par) 18 return END; 19 20 if ((par->fun c == ex pr) && par->arg ) { 21 st->ex pr = par->arg; ZU064-05-FPR heap 9 September 201 8 12:33 10 A. Salikhmetov 22 st->wh = FORTH; 23 return ARG; 24 } 25 26 st->expr = par; 27 return UP; 28 } 29 30 if (ex pr->fu nc) { 31 st->expr = expr->fun c; 32 return FUNC; 33 } 34 35 st-> wh = BACK; 36 retu rn VAR; 37 } C The Storag e Manag er The storage manager unit consists of the put , get , and clear commands implementation as well as the reset ro utine, which resets the memory into its initial state. 1 #inclu de "machin e.h" 2 3 #inclu de 4 #inclu de 5 6 lambda memory , freehead ; 7 8 lambda get() 9 { 10 lamb da new = freehead; 11 12 if (!f reehea d) 13 abort(); 14 15 free head = freehead ->copy ; 16 17 retu rn memset(new , 0, si zeof(s truct _ lambda )); 18 } 19 20 void put(la mbda node) 21 { 22 node ->copy = freehead; 23 free head = node; ZU064-05-FPR heap 9 September 201 8 12:33 The Heap Lambda Machine 11 24 } 25 26 void clear( lambda expr) 27 { 28 stat e st = init(e xpr); 29 path wh; 30 31 whil e ((wh = walk (&st) )) { 32 lambda tmp = st.expr; 33 34 if (UP == wh) { 35 if (tmp->f unc) 36 put(tm p->fu nc); 37 38 if (tmp->a rg) 39 put(tm p->ar g); 40 } 41 } 42 43 put( expr); 44 } 45 46 void reset( int size) 47 { 48 if (me mory) { 49 free(mem ory); 50 memory = freehead = NULL; 51 return; 52 } 53 54 if (si ze > 0) { 55 memory = calloc(si ze, siz eof(st ruct _lambda )); 56 freehead = memory; 57 58 while (--size) 59 memory[s ize - 1 ].copy = &memory [size ]; 60 } 61 } D The Copy Routine The following is the copy comman d im plementation . 1 #inclu de "machin e.h" 2 ZU064-05-FPR heap 9 September 201 8 12:33 12 A. Salikhmetov 3 #in clude 4 5 lam bda copy(lamb da ex pr) 6 { 7 lam bda new = get(); 8 sta te st = init(ex pr); 9 pat h wh; 10 11 whil e ((wh = walk(&st) )) { 12 lambda expr = st.expr; 13 14 if (UP == wh) 15 new = new->pa r; 16 else if (ARG == wh) { 17 new = new->pa r; 18 new->a rg = get(); 19 new->a rg->p ar = new; 20 new = new->ar g; 21 } else if (FUNC == wh) { 22 expr-> par-> copy = new; 23 new->f unc = get(); 24 new->f unc-> par = new; 25 new = new->fu nc; 26 } else if (VAR == wh) { 27 lambda arg = expr->a rg, tmp; 28 29 new->a rg = arg; 30 for (tmp = expr; tmp; tmp = tmp->pa r) { 31 if ((tmp == arg) && tmp-> copy) { 32 new->a rg = tmp->co py; 33 break; 34 } 35 } 36 } 37 } 38 39 retu rn new; 40 } E The Replacement Mechanism The replace ment mecha nism is implemented here, and so is the ro utine that checks if a node can be reduced. 1 #inclu de "machin e.h" ZU064-05-FPR heap 9 September 201 8 12:33 The Heap Lambda Machine 13 2 3 #inclu de 4 5 redex isre ducibl e(con st la mbda expr) 6 { 7 lam bda func = expr->fun c; 8 9 if (ex pr->a rg && fu nc && func-> func && !func-> arg) 10 return RED; 11 12 retu rn UNRED; 13 } 14 15 void replac e(lamb da *exp r, const lambda func, const lambda arg) 16 { 17 stat e st = init(* expr) ; 18 path wh; 19 20 whil e ((wh = walk (&st) )) { 21 lambda tmp = st.expr; 22 23 if ((VAR == wh) && (func == tmp->arg) ) { 24 lambda par = tmp->pa r; 25 26 st.expr = copy(arg ); 27 st.expr- >par = par; 28 29 if (par) { 30 if (par- >func == tmp) 31 par->f unc = st.exp r; 32 else 33 par->a rg = st.expr ; 34 } 35 36 put(tmp) ; 37 } 38 } 39 40 *exp r = st.e xpr; 41 } F The Evaluator Algorithm Giv en belo w is the cor e algorithm of the Heap L ambda Machine. This alg orithm e valuates the lambd a e xpression residing in the machine memory . ZU064-05-FPR heap 9 September 201 8 12:33 14 A. Salikhmetov 1 #in clude "machine. h" 2 3 #in clude 4 5 voi d normal (lamb da *e xpr) 6 { 7 sta te st = init(*e xpr); 8 9 do { 10 while (isreduci ble(st .expr)) { 11 lambda func, arg, par, tmp; 12 13 tmp = st.expr ; 14 func = tmp->f unc; 15 arg = tmp->ar g; 16 par = tmp->pa r; 17 18 replac e(&tm p->func->func, func, arg); 19 20 st.exp r = tmp->fun c->fun c; 21 st.exp r->pa r = par; 22 23 if (st.par == par) 24 *expr = st.ex pr; 25 else if (par->f unc == tmp) { 26 par->f unc = st.exp r; 27 st.exp r = par; 28 } else 29 par->a rg = st.expr; 30 31 tmp->f unc-> func = NULL; 32 clear( tmp); 33 } 34 } whil e (walk(&st )); 35 } References Barendreg t, H. P . (1984) The Lambda Calculus, Its Syntax and Semantics . North-Holland. Field A. J. and Harrison P . G. (1988) Functional Pro gramming . Reading MA: Addison-W esley . Kluge, W . (2005) Abstract Compu ting Machines . Springer-V erlag. W adsworth, C .P . (1971) Semantics and Pragmatics of the Lambda Calculus, PhD t hesis. Oxford Univ ersity .
Original Paper
Loading high-quality paper...
Comments & Academic Discussion
Loading comments...
Leave a Comment