Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Recursion #1

Open
wboeke opened this issue Nov 18, 2023 · 5 comments
Open

Recursion #1

wboeke opened this issue Nov 18, 2023 · 5 comments

Comments

@wboeke
Copy link

wboeke commented Nov 18, 2023

Recursion does'nt work. E.g:
: fact dup 2 > if dup 1- fact * then ;
5 fact .
allways gives 2
However: very simple recursion is okay:
variable n
0 n !
: tst n @ 10 < if n @ . 1 n +! tst then ;
tst
Any suggestion?

@tcoram
Copy link
Owner

tcoram commented Nov 18, 2023

Right now, toolboxforth only supports tail recursion. Effectively, for a tail recursive call to work it has to be the last word in the flow of execution. It essential compiles to a "goto" (jmp), so * is never executed. I've seen an implementation of Forth that looks ahead to see if there is a terminating word (e.g. ";" "then", etc) and does the optimization, otherwise does a normally recursive call. I've never had a use for normal recursion in Forth, but tail calls can actually be faster than begin again loops.

@tcoram
Copy link
Owner

tcoram commented Nov 18, 2023

One way to do normal recursion would be:
: fact dup 2 > if dup 1- ['] fact exec * then ;

@tcoram
Copy link
Owner

tcoram commented Nov 19, 2023

Added a more traditional recursion capability to util.f:
: recurse lwa @ 1+ count 63 and 2/ + [compile] lit , [compile] exec ; immediate

So, you can now
: fact dup 2 > if dup 1- recurse * then ;

@wboeke
Copy link
Author

wboeke commented Nov 19, 2023

Sorry to reopen, but I tried it:
: fact dup 2 > if dup 1- recurse * then ;
5 fact .
120 ok
Hurrah!
Then double recursion:
: fib dup 1 > if dup 1 - recurse swap 2 - recurse + else drop 1 then ;
10 fib .
line: 1: Huh? >>> fib <<< .
ok

I am using recursion often in forth, but seldom double recursion. So: thank you!

@tcoram
Copy link
Owner

tcoram commented Nov 19, 2023

Ah! My bad. The problem is in my skipping of character packed words. That "fact" worked and "fib" didn't is due to my bad character skipping math (3 vs 4 character words).
So...
: recurse lwa @ 1+ count 63 and 2 /mod + + [compile] lit , [compile] exec ; immediate
does the right thing and should work!

Fix checked into util.f

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants