47 lines
971 B
Markdown
47 lines
971 B
Markdown
# Mutual Recursion
|
|
|
|
Tail call optimization for mutually (and directly) recursive functions in Ruby.
|
|
|
|
The current desing uses a trampoline. However, it is implemented in a way that still allows a tail recursive function to return a Proc as its terminal value without it being called prematurely by accident.
|
|
### examples
|
|
```ruby
|
|
require 'mutual_recursion'
|
|
|
|
def mutual_one(x, y = 0)
|
|
return terminal_value(y) if x.negative?
|
|
|
|
tail_call { mutual_two(x, y + 1) }
|
|
end
|
|
|
|
def mutual_two(x, y)
|
|
tail_call { mutual_one(x - 1, y) }
|
|
end
|
|
|
|
mutual_one(50_000).invoke
|
|
# => 50001
|
|
```
|
|
```ruby
|
|
require 'mutual_recursion'
|
|
|
|
def direct(x, y = 0)
|
|
return terminal_value(y) if x.negative?
|
|
|
|
tail_call { direct(x - 1, y + 1) }
|
|
end
|
|
|
|
direct(50_000).invoke
|
|
# => 50001
|
|
```
|
|
```ruby
|
|
require 'mutual_recursion'
|
|
|
|
def proc_returning(x, y = 0)
|
|
return terminal_value(proc { "|#{y}|" }) if x.negative?
|
|
|
|
tail_call { proc_returning(x - 1, y + 1) }
|
|
end
|
|
|
|
proc_returning(20).invoke.call
|
|
# => "|21|"
|
|
```
|