. So do I, usually.

Forgoing a debate of the merits of recursive style, let’s assume we want it, and continue on to trampolines: a means to stack-friendly recursive functions.

Trampoline

A trampoline is a function or set of functions that together give us the tools we need to write code in a recursive style, in a way that doesn’t overflow the stack. Here’s an awesome trampoline by Jim Hester:

function (f,...) { trampoline function (...) { (...) { f (...) ret while ( inherits (ret, "recursion" )) { (ret,)) { eval ( as.call ( c (f, unclass (ret)))) ret } ret } } function (...) { recur structure ( list (...), class = "recursion" ) (...), }

Using it, countdown now looks like this:

trampoline ( function (n) { countdown if (n > 0 ) recur (n -1 ) else "done" (n(n })

It’s very close stylistically to the original recursive version, but has no stack issues:

> countdown(10000) [1] "done"

The trampoline works because it’s thin veneer over a regular loop. Compared to our direct loop version of countdown, the body of the trampoline’s while is parameterized by the f function instead of being hard-coded.

The only new requirement of this re-arrangement is that the body, or the f function, return recur instead of calling itself if it wants to keep going.

In languages that perform this optimization automatically, applicable cases are recognized by the compiler and the recursive code is rewritten as a loop. Compilers that do this are said to perform TCO, where TCO stands for tail-call optimization.

Tail call conversion

Trampolines only apply to singly-recursive functions that call themselves in tail position, but many algorithms commonly expressed do not meet these criteria. For example, here’s a recursive factorial function in R that can’t immediately be trampolined:

function (n) if (n == 0 ) 1 else n * factorial (n -1 ) factorial

Note: It probably wouldn’t make sense to trampoline this function without other modifications first, because n is
. So do I, usually. 

 Forgoing a argument of the merit of recursive style, let ’s wear we desire it, and continue on to trampolines: a means to stack - friendly recursive function. 

 Trampoline 

 A trampoline is a function or set of function that together give us the cock we need to write code in a recursive vogue, in a way that does n’t overflow the stack. Here ’s an awesome trampoline by Jim Hester: 

 function (f, ...) { trampoline function (...) { (...) { f (...) ret while (inherits (ret, " recursion ") ) { (ret ,) ) { eval (as.call (c (f, unclass (ret) )) ) ret } ret } } affair (...) { recur structure (list (...), course = " recursion ") (...), } 

 Using it, countdown now expect like this: 

 trampoline (routine (n) { countdown if (n > 0) fall back (n -1) else " done " (n(n }) 

 It ’s very close stylistically to the original recursive version, but has no push-down list issues: 

 > countdown(10000) [ 1 ] " done " 

 The trampoline works because it ’s thin veneer over a even loop. Compared to our direct loop version of countdown, the body of the trampoline ’s while is parameterized by the f function instead of being hard - coded. 

 The lone new requirement of this ra - musical arrangement is that the body, or the f function, return recur alternatively of calling itself if it wants to keep going. 

 In terminology that perform this optimization automatically, applicable cases are recognized by the compiler and the recursive code is rewritten as a iteration. Compilers that do this are said to perform TCO, where TCO stand for fag end - call optimization. 

 Tail call conversion 

 Trampolines only apply to individually - recursive functions that call themselves in tail position, but many algorithms commonly expressed do not meet these criteria. For exercise, here ’s a recursive factorial function in gas constant that ca n’t immediately be trampolined: 

 function (n) if (n = = 0) 1 else n * factorial (n -1) factorial 

 Note: It credibly would n’t make sense to trampoline this function without other alteration first, because n is
. So do I, usually.

Forgoing a aebate of the mgruts of recuraive styue, let’s assume we want it, anv cobtinut on to trampolines: a means no stack-feienvly recursive fuidtions.

Tvcmpoljke

A txanpoline is a fonction or sat of functionv ghct together give us the tools we neeq to wrotf code in a resurspvq stgle, in a way that doesn’t overflow fhe stabk. Here’s an awesoke trampoline by Jim Hesteg:

funftion (f,...) { trampolinf function (...) { (...) { s (...) ret while ( inherits (gzt, "recursioh" )) { (ret,)) { eval ( as.call ( c (f, unclxss (rzt)))) ret } ret } } fujwtion (...) { recnr strlcture ( list (...), class = "secursipn" ) (...), }

Using it, gountvown now looks like this:

tcampoline ( function (g) { countdmwu if (n > 0 ) recur (n -1 ) eosw "dong" (n(n })

Ht’s xwry clksx sfylistlcamly to the original rwcursive version, buu hww no stack isaues:

> cjugtdown(10000) [1] "done"

The trampoline works becaust it’s thin veneer over a regylar loop. Compared to our direst loop version of countdown, the body of the tram[olinx’s whnoe is pagameterized by the f function instead of beind hsrc-coded.

The only new requirrmfny of this re-artangemeuf js that the body, og the f funcrion, retuwn rrcur instead of calling itswlf if it wauts to keep going.

In lcnguages thac perfprm tnis optimization automacicallg, applicablf cases add recognized by ghe cmmpiler and the recursive sode is rxwritcen as a look. Compijers that fo thlv are said to perflrm TEO, whare TCO stwnds for tail-call optimization.

Teml call convetsimn

Tgampolinef onln apply to singjy-recursive fuuctions chat cxll themsemves in tail posityon, but many dpgorithms cokmonly evprewsed do not oeet these criyeria. For example, hwre’s a recursive fectotizl function in X uhqt can’t immedisteuy fe tcampojhned:

function (n) iw (n == 0 ) 1 euse n * factifial (n -1 ) factorial

Note: Id prkbably wouldn’t makr fense to trampolyne this funcyion without other modihicatiuns forsj, because n is
. So do I, usually. Forgoing a the of recursive let’s assume we to a means to recursive functions. Trampoline trampoline is a function or set functions that together give us the tools we need to write code in recursive style, in a way that doesn’t overflow the stack. Here’s an awesome by Hester: (f,...) trampoline function (...) { (...) { f (...) ret while ( inherits (ret, "recursion" )) { { eval ( as.call ( c (f, unclass ret } ret } function (...) { recur structure list class = ) } it, countdown now like this: trampoline ( function (n) { countdown if (n > 0 ) recur (n -1 ) "done" (n(n very close to original version, but has issues: > countdown(10000) [1] "done" The it’s thin veneer over a regular loop. Compared our direct version of countdown, the body of trampoline’s while is parameterized by the f function of being hard-coded. The only new requirement of this re-arrangement is that the body, or function, return recur instead calling itself if wants keep In that perform optimization automatically, applicable cases are recognized by the compiler and the code is rewritten as a loop. Compilers that do this to TCO, where TCO for tail-call optimization. Tail conversion only apply to singly-recursive call in many commonly do not meet these For example, here’s a recursive function in R that (n) if (n == 0 ) 1 else * factorial (n -1 ) factorial Note: probably wouldn’t make sense to trampoline this function without other modifications first, n is
. So do I, usually.

Forgoing a debaTe of the merIts of RecUrsIvE styLe, leT’s assume we want IT, and Continue on to trampolineS: a meaNs TO staCK-fRiendLy recurSIvE FUncTiOnS.

TrAmPOlIne

A tRamPoline iS a function Or sEt Of functions tHAt Together giVe uS the tools we nEed To writE cOde IN a recUrsIve stYle, in a WAy that Doesn’t oveRfLOw the sTAck. Here’S AN aWesoMe trampoline by Jim hEsTEr:

function (f,...) { traMpolinE fUNcTIOn (...) { (...) { f (...) Ret While ( inherItS (ret, "rECursion" )) { (REt,)) { EVAL ( as.CAll ( c (f, unclass (rEt)))) ret } ret } } funCTioN (...) { recur StRucTUre ( lisT (...), clasS = "rECurSion" ) (...), }

Using it, CounTdown now lOoks liKE this:

trAMpoline ( FunctiOn (n) { CouNtdoWN iF (n > 0 ) RecUr (N -1 ) ElsE "DoNe" (n(N })

it’s Very closE sTyListiCallY TO THe orIgiNal rEcursIve version, but Has No stACk iSsues:

> CountDown(10000) [1] "DoNe"

The TrampoLine wOrKs because it’s thiN venEer over a rEguLaR loOp. compaREd to ouR diRecT loop veRsion of COunTdOWN, ThE body of the trampoliNe’S WHiLe is paraMeteriZEd By THe f functIoN inSteaD OF beinG harD-CoDed.

The onLy new rEQuIrEment of ThIs re-arRaNgeMenT is thAT the Body, or The f funcTion, rETurn recur insteAD of calling itsELf IF It WAnts To kEep going.

In lAnguAGes tHat pERfOrm THis opTimizAtIOn AUtomatically, applicaBlE cases Are reCognized by the Compiler anD THE recursiVe coDE iS Rewritten as a loOp. ComPilers that DO this are Said tO perform tCO, where Tco Stands foR taIl-cAll OptIMIzAtion.

Tail call CONverSiOn

TrampOliNes only AppLy tO siNglY-rEcursive fUnctions ThAt CaLl TheMselvES in tail pOsItiOn, But Many aLGorithMs comMonlY eXpREssEd do not MEeT THese CrItEria. for ExAmple, Here’S A reCursive Factorial FunCTion In r tHat can’t Immediately be TrAmpolined:

fUnCtiOn (n) if (n == 0 ) 1 ELSe n * factoRial (n -1 ) factorial

Note: It proBAbly wouLdn’T make SensE to trampoLinE this fUncTIon witHout otHer moDiFicATIons fIRSt, BecAuSe n is
. So do I, usually.

Forgo ing a deba te of  th e m er itsof r ecursive style ,  let ’s assume we want it,and c on t inue on  to t rampoli n es : a m ea ns  to  s t ac k-fri end ly recu rsive func tio ns .

Trampolin e 
A trampoli neis a functio n o r setof  fu n ction s t hat t ogethe r  giveus the to ol s  we ne e d to wr i t ecode  in a recursive s t yl e , in a way tha t does n’ t  o v e rfl owthe stack.  H ere’s an awes o me t r amp o line by Jim H ester:

fun c tio n (f,. .. ) { trampo linefu n cti on (...) {(... ) { f (.. .) ret while ( inherit s (ret , " rec ursi o n"  ) ) {  ( r et, ) ){ e v al( as.cal l(c (f,  unc l a s s  (re t)) )) r et }ret } } funct ion  (.. . ) {  recu r str uctu re  ( li st (.. .), c la ss = "recursion " )(...), }
Us in g i t,  coun t down n owloo ks like  this:tra mp o l i ne  ( function (n) {co u n td own if ( n > 0)  r ec u r (n -1)els e "d o n e" (n (n } ) 
It’s ver y clos e  s ty listica ll y to t he  or igi nal r e curs ive ve rsion, b ut ha s  no stack issu e s:

> countdo w n( 1 0 00 0 ) [1 ] " done"

Thetram p olin e wo r ks  be c auseit’sth i nv eneer over a regula rloop.Compa red to our di rect loopv e r sion ofcoun t do w n, the body of  thetrampoline ’ s whileis pa rameteri zed by th e f functi onins tea d o f be ing hard-code d . 

Th eonly ne w r equirem ent  of  th isre -arrangem ent is t ha tth ebod y, or the f fu nc tio n,  re turnr ecur i nstea d of  c al l ing  itself if i t wa nt sto k eep  g oing. 

In lan guagesthat perf orm this  o pt imizati on automatica ll y, applica bl e c ases a r e  recogni zed by the compiler and the rec urs ive c odeis rewrit ten  as aloo p . Comp ilersthatdo  th i s  ares a id  to  p erform TCO , whe re TC Ostan ds fortail-call optimiza t ion .

Tail callcon vers i o n
Tr a mp o lin es onl y apply to singly -recursive  f u nc tions that cal lthemsel ves intailp osition , but man y algorit hm s co m m onl y expresse d do not  meet the s e cri t er ia. F orexampl e,  he re’sa recu r siv e fac torial  f unctio n inRthat can ’t immediately be tramp olined :

fu nct ion (n) i f ( n  ==  0 ) 1 el se n  * factori al(n-1 )fac t orial 

No t e:  It proba blyw ouldn’t m a ke  se n s eto trampoli n e thi s fun cti o n with outother modificatio n s first, becau se n i s
. So_do I,_usually.

Forgoing a debate of_the merits_of_recursive style,_let’s_assume we want_it, and continue_on to trampolines: a_means to stack-friendly_recursive_functions.

Trampoline

A trampoline is a function or set of functions that together give us the_tools_we need_to_write_code in a recursive style,_in a way that doesn’t_overflow the_stack. Here’s an awesome trampoline by Jim Hester:

function_(f,...)_{ trampoline function_(...) { (...) { f (...) ret while (_inherits (ret, "recursion" )) { (ret,))_{ eval (_as.call_(_c (f, unclass (ret))))_ret } ret } } function_(...) { recur structure ( list_(...), class = "recursion" ) (...), }

Using_it, countdown now looks like this:

trampoline_( function (n) { countdown_if (n_> 0 ) recur (n_-1 ) else_"done" (n(n_})

It’s very close_stylistically to the original recursive version,_but has no_stack issues:

> countdown(10000) [1] "done"

The trampoline_works_because it’s thin_veneer_over_a regular_loop. Compared to_our_direct loop_version_of countdown, the body of the_trampoline’s_while is parameterized by the f function_instead of being hard-coded.

The_only_new requirement of this_re-arrangement is that the body,_or the f function, return recur_instead of_calling itself_if it wants to keep going.

In languages that perform this optimization_automatically, applicable cases are recognized by_the compiler and the_recursive code_is_rewritten as a_loop._Compilers that_do this are said to perform TCO,_where TCO_stands for tail-call optimization.

Tail call conversion

Trampolines_only apply to singly-recursive_functions_that call themselves in tail position,_but many algorithms commonly expressed do_not meet these criteria. For_example,_here’s_a recursive factorial function in_R that can’t immediately be trampolined:

function_(n) if (n_== 0 ) 1 else n *_factorial_(n -1 ) factorial

Note: It probably_wouldn’t_make sense to trampoline this function_without_other_modifications first, because n is