mutual_recursion 0.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +7 -0
- data/lib/mutual_recursion.rb +57 -0
- metadata +43 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: 8a4c0a9a38c64fd85d25ee1c73b1d0d07bcd486c2ffaea8a01dbc8b92c065b03
|
4
|
+
data.tar.gz: a203fef1268cab2514f265807076438aa3f7d7fa674040c4a6f1f7eeb3c3d41b
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: ff971a69bd8d9a57b7582c1997b00d2060e09375cd3ae15bf9b227b3d2bf54b2fd28b00a9638215a7b97419a88511875602a4d5827a559c436f90774c03aeef6
|
7
|
+
data.tar.gz: efde63fb39477caa440ef01f153a19aedbe6e023c263bab1265c7fae560e64df798eff6e270d3569c2dd0fa8798bb2774fe11812f86b3ce3347cc38bca4003c6
|
@@ -0,0 +1,57 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module MutualRecursion
|
4
|
+
class TailCall
|
5
|
+
attr_reader :value, :block
|
6
|
+
|
7
|
+
def initialize(value = nil, &block)
|
8
|
+
@value = value
|
9
|
+
@block = block
|
10
|
+
end
|
11
|
+
|
12
|
+
##
|
13
|
+
# Invoke this tail call. Only the returned value from the initial call to
|
14
|
+
# the recursive function should be invoked.
|
15
|
+
#
|
16
|
+
# @return [Object] the terminal_value of this tail call
|
17
|
+
|
18
|
+
def invoke
|
19
|
+
self.then do |tail|
|
20
|
+
while tail.block
|
21
|
+
tail = tail.block.call
|
22
|
+
raise MissingTailCallError unless tail.is_a?(TailCall)
|
23
|
+
end
|
24
|
+
|
25
|
+
tail.value
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
class MissingTailCallError < StandardError
|
31
|
+
def initialize(msg = 'expected a tail call')
|
32
|
+
super
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
module_function
|
37
|
+
|
38
|
+
##
|
39
|
+
# Make a direct or indirect recursive call in tail position.
|
40
|
+
#
|
41
|
+
# @yieldreturn [MutualRecursion::TailCall] a tail call
|
42
|
+
# @return [MutualRecursion::TailCall] a non terminal tail call
|
43
|
+
|
44
|
+
def tail_call
|
45
|
+
TailCall.new { yield }
|
46
|
+
end
|
47
|
+
|
48
|
+
##
|
49
|
+
# Indicates that the recursion has ended with the provided value.
|
50
|
+
#
|
51
|
+
# @param [Object] value the terminal value
|
52
|
+
# @return [MutualRecursion::TailCall] a terminal tail call that will return the given value
|
53
|
+
|
54
|
+
def terminal_value(value)
|
55
|
+
TailCall.new(value)
|
56
|
+
end
|
57
|
+
end
|
metadata
ADDED
@@ -0,0 +1,43 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: mutual_recursion
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.0.1
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Mike Cifelli
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2019-01-27 00:00:00.000000000 Z
|
12
|
+
dependencies: []
|
13
|
+
description: Tail call optimization for mutually and directly recursive functions.
|
14
|
+
email:
|
15
|
+
executables: []
|
16
|
+
extensions: []
|
17
|
+
extra_rdoc_files: []
|
18
|
+
files:
|
19
|
+
- lib/mutual_recursion.rb
|
20
|
+
homepage: https://gitlab.com/mike-cifelli/mutual_recursion
|
21
|
+
licenses:
|
22
|
+
- MIT
|
23
|
+
metadata: {}
|
24
|
+
post_install_message:
|
25
|
+
rdoc_options: []
|
26
|
+
require_paths:
|
27
|
+
- lib
|
28
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
29
|
+
requirements:
|
30
|
+
- - ">="
|
31
|
+
- !ruby/object:Gem::Version
|
32
|
+
version: '0'
|
33
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
34
|
+
requirements:
|
35
|
+
- - ">="
|
36
|
+
- !ruby/object:Gem::Version
|
37
|
+
version: '0'
|
38
|
+
requirements: []
|
39
|
+
rubygems_version: 3.0.1
|
40
|
+
signing_key:
|
41
|
+
specification_version: 4
|
42
|
+
summary: Mutual Recursion for Ruby
|
43
|
+
test_files: []
|