Thanks for that.  I look forward to the day that I can
understand it :)

 --- Maarten Koopmans <[EMAIL PROTECTED]> wrote: > 
> > Another quick question: does Rebol optimise tail
> end
> > recursion like Lisp and Scheme?
> > 
> 
> No, but I wrote a function that does this. Only for
> tail recursive
> functions though. And gives you good insight in
> cracking some REBOL nuts
> ;-)
> 
> See below....
> ----------------------------------------
> 
> REBOL []
> 
> 
> tail-func: func 
> [ 
>   {Returns a function that handles tail-recursion
> transparently.}
>   args [block!] body [block!]
>   /local _*meta-func _*meta-spec _*meta-body
> _*statement _*comm _*p1
> _*p2 _*r _*w
> ]
> [
>   _*meta-spec: append/only copy [] args
>   _*meta-body: append/only copy [] body
>       
>   ;matches refinements and copies refinements to our
> command
>   _*p1: [ set _*r refinement! 
>   (either get bind to-word _*r '_*comm [append
> _*comm mold _*r
> _*ref-mode: on][ _*ref-mode: off ])]
>   ;matches words and copies their values to the
> statement if ref-mode =
> on
>   _*p2: [ set _*w word! (if _*ref-mode [ append/only
> _*statement get
> bind to-word _*w '_*comm])]
>       
>       
>   _*meta-func: copy 
>   [
>   ;The use context is accessible from the wrapper
> function that
>   ;eliminates tail recursion. It plays the role of a
> stack frame
>   ;it implements a goto like behaviour in case of
> tail recursion
>   use [ _*loop-detected _*myself _*innerfunc _*loops
> _*myspec _*myspec2
> _*mycall]
>   [
>     ;some static initialization of the use context
> varaiables
>     _*loops: 0
>     _*loop-detected: false
>     _*mycall: copy []
>     _*innerfunc: func (_*meta-spec) (_*meta-body)
>     _*myspec: copy first :_*innerfunc
>     _*myspec2: either found? find _*myspec /local
>     [append copy _*myspec [_*ref-mode _*p1 _*p2 _*r
> _*w _*comm
> _*statement _*ret]]
>     [append copy _*myspec [/local _*ref-mode _*p1
> _*p2 _*r _*w _*comm
> _*statement _*ret]]
>     insert/only _*myspec2 [catch]     
> 
>     ;The function that is returned from the use
> context
>     _*myself: func _*myspec2
>     [ 
>       ;How deep in a loop am I?
>       _*loops: _*loops + 1
> 
>       ;These parse rules extract how I am called
>       ;(which refinements and so)
>       _*p1: [(_*p1)]
>       _*p2: [(_*p2)]
>       _*ref-mode: on
> 
>       ;Our initial call
>       _*comm: copy {_*innerfunc}
>       ;Our initial statement
>       _*statement: copy []
>                               
>       ;Generate our statement and call
>       parse _*myspec [ any [ _*p1 | _*p2 ]]
>       insert _*statement to-path _*comm
> 
>       ;Copy it in the use context so it survives
>       ;a loop (_*mycall is the 'goto args)
>       _*mycall: copy _*statement
>                               
>       if _*loops = 2 
>       [
>         _*loops: 1
>         _*loop-detected: true
>         return
>       ]
> 
>       ;Until we are no longer in loop-detection mode
>       until
>       [
>         _*loop-detected: false
>         set/any '_*ret do bind _*mycall '_*loops 
>         not _*loop-detected
>       ]
>                               
>       ;Use context cleanup
>       _*loops: 0
>       _*loop-detected: false
>       _*mycall: copy []
> 
> 
>       ;return our value
>       return get/any '_*ret
>     ];_*myself: func ...
> 
>     ];use context
> 
>   ];meta-func
> 
>   ;return our function....    
>   do compose/deep _*meta-func
> ]
> 
> ;example usage
> f: tail-func [x][x: x + 1 print x f x]
> 
> -- 
> To unsubscribe from this list, just send an email to
> [EMAIL PROTECTED] with unsubscribe as the
> subject.
>  

________________________________________________________________________
Want to chat instantly with your online friends?  Get the FREE Yahoo!
Messenger http://mail.messenger.yahoo.co.uk
-- 
To unsubscribe from this list, just send an email to
[EMAIL PROTECTED] with unsubscribe as the subject.

Reply via email to