mutual_recursion 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
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: []