Update readme
This commit is contained in:
parent
caf0a7c80c
commit
5959e9dc8d
46
README.md
46
README.md
|
@ -0,0 +1,46 @@
|
||||||
|
# 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|"
|
||||||
|
```
|
|
@ -8,6 +8,6 @@ Gem::Specification.new do |s|
|
||||||
s.description = 'Tail call optimization for mutually (and directly) recursive functions using a trampoline.'
|
s.description = 'Tail call optimization for mutually (and directly) recursive functions using a trampoline.'
|
||||||
s.authors = ['Mike']
|
s.authors = ['Mike']
|
||||||
s.files = ['lib/mutual_recursion.rb']
|
s.files = ['lib/mutual_recursion.rb']
|
||||||
s.homepage = ''
|
s.homepage = 'https://gitlab.com/mike-cifelli/mutual_recursion'
|
||||||
s.license = 'MIT'
|
s.license = 'MIT'
|
||||||
end
|
end
|
||||||
|
|
|
@ -37,7 +37,7 @@ class InventoryTest < Minitest::Test
|
||||||
end
|
end
|
||||||
|
|
||||||
def test_recursive_function_can_return_proc
|
def test_recursive_function_can_return_proc
|
||||||
tail = proc_returning
|
tail = proc_returning(20)
|
||||||
assert_kind_of(Proc, tail.invoke)
|
assert_kind_of(Proc, tail.invoke)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -76,8 +76,10 @@ def lambda_returning
|
||||||
terminal_value(-> { 24 })
|
terminal_value(-> { 24 })
|
||||||
end
|
end
|
||||||
|
|
||||||
def proc_returning
|
def proc_returning(x, y = 0)
|
||||||
terminal_value(proc { 24 })
|
return terminal_value(proc { puts "|#{y}|" }) if x.negative?
|
||||||
|
|
||||||
|
tail_call { proc_returning(x - 1, y + 1) }
|
||||||
end
|
end
|
||||||
|
|
||||||
def bad_return
|
def bad_return
|
||||||
|
|
Loading…
Reference in New Issue