[REBOL] Re: tail-func: for the gurus
From: lmecir:mbox:vol:cz at: 17-Nov-2001 17:47
Hi Maarten,
interesting. There are some other "tricks" that can be applied in this case.
1) your implementation uses "keywords": [ref-mode p1 p2 r w comm statement
ret either get bind to-word append mold on off refinement! word! copy parse
_*loops _*myspec insert to-path _*mycall if _*loop-detected true return
until false set do not]. The need to have keywords can be eliminated.
2) Why did you use the CATCH function attribute?
3) Refinements can be passed more transparently.
4) Other simplifications/generalizations were possible. I have "stolen" some
ideas from my
CFUNC implementation:
exec: func [body] [do body]
tail-func: function [
{Transparently creates a tail-recursive function.}
[catch]
spec [block!] body [block!]
] [
ic icb i item
] [
use [new-locals loop] [
loop: 0
locals: copy []
icb: copy []
i: 1
parse spec [
any [
set-word! | set item any-word! (
append locals to word! :item
append icb compose [
error? set/any pick new-locals (i) get/any pick
locals (i)
]
i: i + 1
) | skip
]
]
set [new-locals body] use locals copy/deep reduce [
reduce [locals body]
]
append icb compose/deep [
either loop > 0 [
loop: 2
] [
until [
loop: 1
error? set/any 'result exec (reduce [body])
loop = 1
]
loop: 0
return get/any 'result
]
]
ic: func [
{do body with locals in new context}
[throw]
locals
] icb
throw-on-error [
func spec reduce [:ic locals]
]
]
]
fib: tail-func [first second n] [
print [first second n]
either n = 2 [second] [
fib second first + second n - 1
]
]
Cheers
Ladislav