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.
Files changed (3) hide show
  1. checksums.yaml +7 -0
  2. data/lib/mutual_recursion.rb +57 -0
  3. 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: []