ruff 1.4.0 → 2.0.0

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 (42) hide show
  1. checksums.yaml +4 -4
  2. data/.rubocop.yml +1 -1
  3. data/Gemfile +2 -1
  4. data/Gemfile.lock +16 -12
  5. data/README.md +35 -58
  6. data/Rakefile +2 -1
  7. data/docs/Ruff.html +7 -7
  8. data/docs/Ruff/Effect.html +165 -23
  9. data/docs/Ruff/Handler.html +45 -50
  10. data/docs/Ruff/Standard.html +6 -6
  11. data/docs/Ruff/Standard/Async.html +26 -26
  12. data/docs/Ruff/Standard/Async/Instance.html +8 -8
  13. data/docs/Ruff/Standard/Call1cc.html +6 -6
  14. data/docs/Ruff/Standard/CurrentTime.html +6 -6
  15. data/docs/Ruff/Standard/CurrentTime/Instance.html +7 -7
  16. data/docs/Ruff/Standard/Defer.html +6 -6
  17. data/docs/Ruff/Standard/Defer/Instance.html +6 -6
  18. data/docs/Ruff/Standard/MeasureTime.html +6 -6
  19. data/docs/Ruff/Standard/MeasureTime/Instance.html +8 -8
  20. data/docs/Ruff/Standard/State.html +6 -6
  21. data/docs/Ruff/Standard/State/Instance.html +6 -6
  22. data/docs/Ruff/Throws.html +6 -11
  23. data/docs/Ruff/Throws/Eff.html +6 -6
  24. data/docs/Ruff/Throws/Resend.html +6 -6
  25. data/docs/_index.html +7 -7
  26. data/docs/class_list.html +2 -2
  27. data/docs/css/style.css +2 -2
  28. data/docs/file.README.html +39 -56
  29. data/docs/file_list.html +2 -2
  30. data/docs/frames.html +2 -2
  31. data/docs/index.html +39 -56
  32. data/docs/js/app.js +14 -3
  33. data/docs/method_list.html +71 -63
  34. data/docs/top-level-namespace.html +6 -6
  35. data/lib/ruff/effect.rb +32 -3
  36. data/lib/ruff/handler.rb +43 -18
  37. data/lib/ruff/standard/async.rb +10 -7
  38. data/lib/ruff/standard/current_time.rb +1 -1
  39. data/lib/ruff/standard/measure_time.rb +2 -2
  40. data/lib/ruff/version.rb +1 -1
  41. data/version +1 -1
  42. metadata +3 -3
@@ -6,15 +6,15 @@
6
6
  <title>
7
7
  Top Level Namespace
8
8
 
9
- &mdash; Ruff 1.3.1 Documentation
9
+ &mdash; Ruff 1.4.0 Documentation
10
10
 
11
11
  </title>
12
12
 
13
- <link rel="stylesheet" href="css/style.css" type="text/css" charset="utf-8" />
13
+ <link rel="stylesheet" href="css/style.css" type="text/css" />
14
14
 
15
- <link rel="stylesheet" href="css/common.css" type="text/css" charset="utf-8" />
15
+ <link rel="stylesheet" href="css/common.css" type="text/css" />
16
16
 
17
- <script type="text/javascript" charset="utf-8">
17
+ <script type="text/javascript">
18
18
  pathId = "";
19
19
  relpath = '';
20
20
  </script>
@@ -100,9 +100,9 @@
100
100
  </div>
101
101
 
102
102
  <div id="footer">
103
- Generated on Wed Oct 30 01:51:52 2019 by
103
+ Generated on Thu Jan 2 19:46:22 2020 by
104
104
  <a href="http://yardoc.org" title="Yay! A Ruby Documentation Tool" target="_parent">yard</a>
105
- 0.9.20 (ruby-2.6.5).
105
+ 0.9.22 (ruby-2.6.5).
106
106
  </div>
107
107
 
108
108
  </div>
@@ -2,7 +2,10 @@
2
2
 
3
3
  # This class provides an effect instance.
4
4
  class Ruff::Effect
5
- # Each instance must be unique so they have unique id with UUID
5
+ # Each instance must be unique so they have unique id with an annonymous class instance.
6
+ #
7
+ # The class instance may have subtyping relation.
8
+ # @see <<
6
9
  attr_reader :id
7
10
 
8
11
  # instaciates an effect setting `id`.
@@ -10,13 +13,39 @@ class Ruff::Effect
10
13
  # @example
11
14
  # Log = Effect.new #==> it _might_ be Effect<string, nil>
12
15
  def initialize
13
- @id = SecureRandom.uuid
14
- @id.freeze
16
+ @id = Class.new.new
17
+ end
18
+
19
+ # instanciates an effect, which has an relation `self <: parent`
20
+ # from the subtyping of `id` object.
21
+ #
22
+ # @param [Effect<Arg, Ret>] parent
23
+ # @return [Effect<Arg, Ret>] with an relation `it <: parent`
24
+ #
25
+ # @example
26
+ # Exception = Ruff::Effect.new
27
+ # RuntimeException = Ruff::Effect << Exception
28
+ #
29
+ # Ruff::Handler.new
30
+ # .on(Exception){
31
+ # puts "catch"
32
+ # }
33
+ # .run {
34
+ # RuntimeException.perform
35
+ # }
36
+ # # ==> prints "catch"
37
+ def self.<<(parent)
38
+ inst = new
39
+ parent_id = parent.instance_variable_get('@id')
40
+ inst.instance_variable_set('@id', (Class.new parent_id.class).new)
41
+ inst
15
42
  end
16
43
 
17
44
  # sends an effect ID and its arguments to a nearmost handler.
45
+ #
18
46
  # @param [Arg] a of the object `Effect<Arg, Ret>`
19
47
  # @return [Ret] of the object `Effect<Arg, Ret>`
48
+ #
20
49
  # @example
21
50
  # Log.perform "hello"
22
51
  def perform(*a)
@@ -2,17 +2,41 @@
2
2
 
3
3
  # In algebraic effects, handler is an first-class object.
4
4
  class Ruff::Handler
5
- include Ruff::Throws
6
-
7
5
  # makes a new handler, internally having fresh empty hash.
8
6
  #
9
7
  # This is a effect-handler store and when handliong it is looked up.
10
- # Value handler is set `id` function to by default.
11
- #
8
+ # Value handler is set an identity function to by default.
9
+
10
+ class Store
11
+ # is a private class to manage registered handlers
12
+ def initialize
13
+ @handler = {}
14
+ end
15
+
16
+ def []=(r, e)
17
+ @handler[r.id] = e
18
+ end
19
+
20
+ def [](eff)
21
+ # get a set {(eff', f) | forall (eff', f) in store. eff <: eff'}
22
+ fns = @handler.filter do |effky, _fun|
23
+ eff.id.is_a? effky.class
24
+ end
25
+
26
+ # pick a function with *smallest* effect class
27
+ return fns.min_by { |effky, _| effky.class }[1] unless fns.empty?
28
+
29
+ # if found nothing
30
+ nil
31
+ end
32
+ end
33
+
34
+ private_constant :Store
35
+
12
36
  # @example
13
37
  # handler = Handler.new
14
38
  def initialize
15
- @handlers = {}
39
+ @handlers = Store.new
16
40
  @valh = ->(x) { x }
17
41
  end
18
42
 
@@ -56,7 +80,10 @@ class Ruff::Handler
56
80
  self
57
81
  end
58
82
 
59
- # sets effec handler `&fun` for `eff`
83
+ # sets or updates effec handler `&fun` for `eff`
84
+ #
85
+ # Note that `eff` can be a supertype of an effect to be caught.
86
+ # @see Effect.<<
60
87
  #
61
88
  # @param [Effect<Arg, Ret>] eff
62
89
  # the effect instance to be handled
@@ -73,7 +100,7 @@ class Ruff::Handler
73
100
  # k[]
74
101
  # }
75
102
  def on(eff, &fun)
76
- @handlers[eff.id] = fun
103
+ @handlers[eff] = fun
77
104
 
78
105
  self
79
106
  end
@@ -107,13 +134,13 @@ class Ruff::Handler
107
134
  continue(co).call(nil)
108
135
  end
109
136
 
110
- # is also private method.
137
+ protected
138
+
139
+ # receives `handlers` as new handlers.
111
140
  def handlers=(handlers)
112
141
  @handlers = handlers.dup
113
142
  end
114
143
 
115
- private
116
-
117
144
  def continue(co)
118
145
  ->(*arg) { handle(co, co.resume(*arg)) }
119
146
  end
@@ -121,20 +148,20 @@ class Ruff::Handler
121
148
  # rubocop:disable Metrics/AbcSize
122
149
  def handle(co, r)
123
150
  case r
124
- when Eff
125
- if (effh = @handlers[r.id])
151
+ when Ruff::Throws::Eff
152
+ if (effh = @handlers[r])
126
153
  effh[continue(co), *r.args]
127
154
  else
128
- Fiber.yield Resend.new(r, continue(co))
155
+ Fiber.yield Ruff::Throws::Resend.new(r, continue(co))
129
156
  end
130
- when Resend then
157
+ when Ruff::Throws::Resend then
131
158
  eff = r.eff
132
159
  next_k = rehandles(co, r.k)
133
160
 
134
- if (effh = @handlers[eff.id])
161
+ if (effh = @handlers[eff])
135
162
  effh.call(next_k, *eff.args)
136
163
  else
137
- Fiber.yield Resend.new(eff, next_k)
164
+ Fiber.yield Ruff::Throws::Resend.new(eff, next_k)
138
165
  end
139
166
  else
140
167
  @valh.call(r)
@@ -153,6 +180,4 @@ class Ruff::Handler
153
180
  .run { k.call(*args) }
154
181
  }
155
182
  end
156
-
157
- private :handlers=
158
183
  end
@@ -89,7 +89,7 @@ module Ruff::Standard::Async
89
89
  @eff.await.perform p
90
90
  end
91
91
 
92
- # @method with
92
+ # @method with(&th)
93
93
  # @param [Proc<(), _A!{Async.async, Async.yield, Async.await, e}>] th
94
94
  # is a thunk returning `_A` with te possibility to invoke effects,
95
95
  # including `Async.async` , `Async.yield` and `Async.await` .
@@ -108,8 +108,8 @@ module Ruff::Standard::Async
108
108
  # rubocop:disable Metrics/AbcSize
109
109
  # rubocop:disable Metrics/BlockLength
110
110
  define_method :fork do |pr, th|
111
- Ruff.handler
112
- .to do |v|
111
+ h = Ruff::Handler.new
112
+ h.to do |v|
113
113
  pp = pr.get
114
114
  l = case pp
115
115
  when Waiting then pp.get
@@ -123,16 +123,18 @@ module Ruff::Standard::Async
123
123
  pr.set(Done.new(v))
124
124
  @q.dequeue
125
125
  end
126
- .on(@eff.async) do |k, f|
126
+
127
+ h.on(@eff.async) do |k, f|
127
128
  pr_ = Util::Ref.new(Waiting.new([]))
128
129
  @q.enqueue(-> { k[pr_] })
129
130
  fork(pr_, f)
130
131
  end
131
- .on(@eff.yield) do |k|
132
+ h.on(@eff.yield) do |k|
132
133
  @q.enqueue(-> { k[] })
133
134
  @q.dequeue.call
134
135
  end
135
- .on(@eff.await) do |k, ppr|
136
+
137
+ h.on(@eff.await) do |k, ppr|
136
138
  pp = ppr.get
137
139
 
138
140
  return case pp
@@ -142,7 +144,8 @@ module Ruff::Standard::Async
142
144
  @q.dequeue.call
143
145
  end
144
146
  end
145
- .run { th[] }
147
+
148
+ h.run { th[] }
146
149
  end
147
150
  # rubocop:enable Metrics/BlockLength
148
151
  # rubocop:enable Metrics/AbcSize
@@ -30,7 +30,7 @@ module Ruff::Standard::CurrentTime
30
30
  # returns `A` , without modification by value handler.
31
31
  # But it still has the possibility to invoke effects(`e`).
32
32
  def with(&th)
33
- @handler.run(&th)
33
+ @handler.run(&th)
34
34
  end
35
35
 
36
36
  # You can reimplement the handler using this effect instance.
@@ -22,13 +22,13 @@ module Ruff::Standard::MeasureTime
22
22
  def initialize
23
23
  @eff = Ruff.instance
24
24
  @handler = Ruff.handler
25
- .on(@eff) do |k, label|
25
+ @handler.on(@eff) do |k, label|
26
26
  t1 = Time.now
27
27
  result = k[]
28
28
  t2 = Time.now
29
29
  result + [{ label: label, time: t2 - t1 }]
30
30
  end
31
- .to { |x| [x] }
31
+ @handler.to { |x| [x] }
32
32
  end
33
33
 
34
34
  # is a smart method to invoke the effect operation.
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Ruff
4
- VERSION = '1.4.0'
4
+ VERSION = '2.0.0'
5
5
  end
data/version CHANGED
@@ -1 +1 @@
1
- 1.4.0
1
+ 2.0.0
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: ruff
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.4.0
4
+ version: 2.0.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - nymphium
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2019-10-29 00:00:00.000000000 Z
11
+ date: 2020-01-02 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
@@ -126,7 +126,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
126
126
  - !ruby/object:Gem::Version
127
127
  version: '0'
128
128
  requirements: []
129
- rubygems_version: 3.0.6
129
+ rubygems_version: 3.1.2
130
130
  signing_key:
131
131
  specification_version: 4
132
132
  summary: ONE-SHOT Algebraic Effects for Ruby!