Updates for initial release
This commit is contained in:
parent
120f9c1e78
commit
7d8e4a2d3f
|
@ -1,8 +1,8 @@
|
||||||
# Mutual Recursion
|
# Mutual Recursion
|
||||||
|
|
||||||
Tail call optimization for mutually (and directly) recursive functions in Ruby.
|
Tail call optimization for mutually (indirectly) and directly recursive functions in Ruby.
|
||||||
|
|
||||||
The current design 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.
|
The current design uses a trampoline. However, it is implemented in a way that still allows a tail recursive function to easily return a Proc as its terminal value.
|
||||||
|
|
||||||
### examples
|
### examples
|
||||||
```ruby
|
```ruby
|
||||||
|
|
|
@ -3,10 +3,10 @@
|
||||||
Gem::Specification.new do |s|
|
Gem::Specification.new do |s|
|
||||||
s.name = 'mutual_recursion'
|
s.name = 'mutual_recursion'
|
||||||
s.version = '0.0.1'
|
s.version = '0.0.1'
|
||||||
s.date = '2019-01-26'
|
s.date = '2019-01-27'
|
||||||
s.summary = 'Mutual Recursion for Ruby'
|
s.summary = 'Mutual Recursion for Ruby'
|
||||||
s.description = 'Tail call optimization for mutually (and directly) recursive functions.'
|
s.description = 'Tail call optimization for mutually and directly recursive functions.'
|
||||||
s.authors = ['Mike']
|
s.authors = ['Mike Cifelli']
|
||||||
s.files = ['lib/mutual_recursion.rb']
|
s.files = ['lib/mutual_recursion.rb']
|
||||||
s.homepage = 'https://gitlab.com/mike-cifelli/mutual_recursion'
|
s.homepage = 'https://gitlab.com/mike-cifelli/mutual_recursion'
|
||||||
s.license = 'MIT'
|
s.license = 'MIT'
|
||||||
|
|
|
@ -14,7 +14,7 @@ class InventoryTest < Minitest::Test
|
||||||
tail_call { two(x, y + 1) }
|
tail_call { two(x, y + 1) }
|
||||||
end
|
end
|
||||||
|
|
||||||
def two(x, y)
|
def two(x, y = 0)
|
||||||
tail_call { one(x - 1, y) }
|
tail_call { one(x - 1, y) }
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -34,14 +34,14 @@ class InventoryTest < Minitest::Test
|
||||||
tail_call { proc_returning(x - 1, y + 1) }
|
tail_call { proc_returning(x - 1, y + 1) }
|
||||||
end
|
end
|
||||||
|
|
||||||
def bad_return
|
def inauthentic_tail_call
|
||||||
tail_call do
|
tail_call do
|
||||||
Class.new do
|
Class.new do
|
||||||
attr_reader :value, :block
|
attr_reader :value, :block
|
||||||
|
|
||||||
def initialize
|
def initialize
|
||||||
@value = 99
|
@value = 99
|
||||||
@block = proc { 25 }
|
@block = proc { MutualRecursion.terminal_value(100) }
|
||||||
end
|
end
|
||||||
end.new
|
end.new
|
||||||
end
|
end
|
||||||
|
@ -63,8 +63,10 @@ class InventoryTest < Minitest::Test
|
||||||
end
|
end
|
||||||
|
|
||||||
def test_mutual_tail_recursion
|
def test_mutual_tail_recursion
|
||||||
tail = one(50_000)
|
tail_one = one(50_000)
|
||||||
assert_equal(50_001, tail.invoke)
|
tail_two = two(50_000)
|
||||||
|
assert_equal(50_001, tail_one.invoke)
|
||||||
|
assert_equal(50_000, tail_two.invoke)
|
||||||
end
|
end
|
||||||
|
|
||||||
def test_direct_tail_recursion
|
def test_direct_tail_recursion
|
||||||
|
@ -82,8 +84,8 @@ class InventoryTest < Minitest::Test
|
||||||
assert_kind_of(Proc, tail.invoke)
|
assert_kind_of(Proc, tail.invoke)
|
||||||
end
|
end
|
||||||
|
|
||||||
def test_non_tail_call_detected
|
def test_inauthentic_tail_call_detected
|
||||||
tail = bad_return
|
tail = inauthentic_tail_call
|
||||||
assert_raises(MissingTailCallError) { tail.invoke }
|
assert_raises(MissingTailCallError) { tail.invoke }
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue