ruff 1.2.0 → 1.3.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.
@@ -6,7 +6,7 @@
6
6
  <title>
7
7
  Top Level Namespace
8
8
 
9
- &mdash; Ruff 1.1.0 Documentation
9
+ &mdash; Ruff 1.3.0 Documentation
10
10
 
11
11
  </title>
12
12
 
@@ -100,7 +100,7 @@
100
100
  </div>
101
101
 
102
102
  <div id="footer">
103
- Generated on Fri Oct 4 21:12:21 2019 by
103
+ Generated on Sun Oct 6 23:09:11 2019 by
104
104
  <a href="http://yardoc.org" title="Yay! A Ruby Documentation Tool" target="_parent">yard</a>
105
105
  0.9.20 (ruby-2.6.5).
106
106
  </div>
@@ -1,13 +1,13 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require 'ruff/version'
4
- require 'ruff/objects'
5
- require 'ruff/effect'
6
- require 'ruff/handler'
7
- require 'securerandom'
8
-
9
3
  module Ruff
10
4
  class << self
5
+ require 'ruff/version'
6
+ require 'ruff/objects'
7
+ require 'ruff/effect'
8
+ require 'ruff/handler'
9
+ require 'securerandom'
10
+
11
11
  # is alias for `Effect.new`
12
12
  # @see Effect.initialize Effect.initialize
13
13
  #
@@ -1,7 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require 'securerandom'
4
-
5
3
  # In algebraic effects, handler is an first-class object.
6
4
  class Ruff::Handler
7
5
  include Ruff::Throws
@@ -23,3 +23,4 @@ require 'ruff/standard/current_time'
23
23
  require 'ruff/standard/measure_time'
24
24
  require 'ruff/standard/defer'
25
25
  require 'ruff/standard/state'
26
+ require 'ruff/standard/async'
@@ -0,0 +1,177 @@
1
+ # frozen_string_literal: true
2
+
3
+ # `Async` provides effects `Async.async`, `Async.yield` and `Async.await`, and the implementation async/await.
4
+ # This implementation is based on the tutorial for Multicore OCaml.
5
+ # @see https://github.com/ocamllabs/ocaml-effects-tutorial/blob/master/sources/solved/async_await.ml
6
+ #
7
+ # The module has an instance of `Instance` and provides its methods as module method.
8
+ # @see Standard::Async::Instance
9
+ # @example
10
+ # Async.with do
11
+ # task = lambda { |name|
12
+ # lambda {
13
+ # puts "Starting #{name}"
14
+ # v = (Random.rand * (10**3)).floor
15
+ # puts "Yielding #{name}"
16
+ # Async.yield
17
+ # puts "Eidnig #{name} with #{v}"
18
+ #
19
+ # v
20
+ # }
21
+ # }
22
+ #
23
+ # pa = Async.async(task.call('a'))
24
+ # pb = Async.async(task.call('b'))
25
+ # pc = Async.async lambda {
26
+ # Async.await(pa) + Async.await(pb)
27
+ # }
28
+ #
29
+ # puts "sum is #{Async.await pc}"
30
+ # end
31
+ # #==>
32
+ # # Starting a
33
+ # # Yielding a
34
+ # # Eidnig a with 423
35
+ # # Starting b
36
+ # # Yielding b
37
+ # # Eidnig b with 793
38
+ # # sum is 1216
39
+ module Ruff::Standard::Async
40
+ class Instance
41
+ require 'ostruct'
42
+ require 'ruff/standard/util'
43
+
44
+ # are ADT-like classes which have only getter method.
45
+ # These are used internally.
46
+ #
47
+ # type 'a promise =
48
+ # | Waiting of ('a, unit) continuation list
49
+ # | Done of 'a
50
+ _Waiting = Util::ADT.create
51
+ _Done = Util::ADT.create
52
+
53
+ # makes a new instance.
54
+ def initialize
55
+ # delegates effect instances.
56
+ @eff = OpenStruct.new(
57
+ async: Ruff.instance,
58
+ yield: Ruff.instance,
59
+ await: Ruff.instance
60
+ )
61
+
62
+ # is a proc queue.
63
+ @q = Util::FnStack.new
64
+ end
65
+
66
+ # is a smart method to invoke the effect operation `Async.async` .
67
+ # @param [Proc<(), A>] th
68
+ # is a thunk asynchronously computed.
69
+ # @return [Promise<A>]
70
+ # with `with` , returns `Promise<A>` with running concurrently .
71
+ def async(th)
72
+ @eff.async.perform th
73
+ end
74
+
75
+ # is a smart method to invoke the effect operation `Async.yield` .
76
+ # @return [()]
77
+ # with `with` , yields the control to another task.
78
+ def yield
79
+ @eff.yield.perform
80
+ end
81
+
82
+ # is a smart method to invoke the effect operation `Async.await` .
83
+ # @param [Promise<A>] p
84
+ # is a promise to run.
85
+ # @return [A]
86
+ # with `with` returns the result of *promise* computation.
87
+ def await(p)
88
+ @eff.await.perform p
89
+ end
90
+
91
+ # @method with
92
+ # @param [Proc<(), _A!{Async.async, Async.yield, Async.await, e}>] th
93
+ # is a thunk returning `_A` with te possibility to invoke effects,
94
+ # including `Async.async` , `Async.yield` and `Async.await` .
95
+ # @return [()!{e}]
96
+ # returns unit but still has the possibility to invoke effects `e` .
97
+ define_method :with do |&th|
98
+ fork(Util::Ref.new(_Waiting.new([])), th)
99
+ end
100
+
101
+ # You can reimplement the handler using these effect instances
102
+ # with accessing `Async.async` , `Async.yield` , and `Async.await` .
103
+ attr_reader :eff
104
+
105
+ private
106
+
107
+ define_method :fork do |pr, th|
108
+ Ruff.handler
109
+ .to do |v|
110
+ pp = pr.get
111
+ l = case pp
112
+ when _Waiting
113
+ pp.get
114
+ else
115
+ raise 'impossible'
116
+ end
117
+
118
+ l.each do |k|
119
+ @q.enqueue(-> { k[v] })
120
+ end
121
+
122
+ pr.set(_Done.new(v))
123
+ @q.dequeue
124
+ end
125
+ .on(@eff.async) do |k, f|
126
+ pr_ = Util::Ref.new(_Waiting.new([]))
127
+ @q.enqueue(-> { k[pr_] })
128
+ fork(pr_, f)
129
+ end
130
+ .on(@eff.yield) do |k|
131
+ @q.enqueue(-> { k[] })
132
+ @q.dequeue.call
133
+ end
134
+ .on(@eff.await) do |k, pr|
135
+ pp = pr.get
136
+
137
+ return case pp
138
+ when _Done
139
+ k[pp.get]
140
+ when _Waiting
141
+ pr.set(_Waiting.new(@q.cons(k)))
142
+ @q.dequeue.call
143
+ end
144
+ end
145
+ .run { th[] }
146
+ end
147
+ end
148
+
149
+ # ---
150
+ @inst = Instance.new
151
+ @eff = @inst.eff
152
+
153
+ # @see Instance#async
154
+ def async(asynth)
155
+ @inst.async asynth
156
+ end
157
+
158
+ # @see Instance#await
159
+ def await(p)
160
+ @inst.await p
161
+ end
162
+
163
+ # @see Instance#yield
164
+ def yield
165
+ @inst.yield
166
+ end
167
+
168
+ # @see Instance#with
169
+ def with(&th)
170
+ @inst.with(&th)
171
+ end
172
+
173
+ module_function :async, :await, :yield, :with
174
+
175
+ # @see Instance#eff
176
+ attr_reader :eff
177
+ end
@@ -1,7 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require 'ostruct'
4
-
5
3
  # `State` provides effects `State.get` and `State.modify` ,
6
4
  # and the implementation of the mutable cell or so-called *state* .
7
5
  #
@@ -16,22 +14,24 @@ require 'ostruct'
16
14
  # puts s #==> 30
17
15
  # 0
18
16
  # }
19
- #
17
+ #
20
18
  # puts State.get #==> 0
21
- #
19
+ #
22
20
  # State.put 11
23
21
  # }
24
- #
22
+ #
25
23
  # puts r #==> 11
26
24
  module Ruff::Standard::State
27
25
  class Instance
26
+ require 'ostruct'
27
+
28
28
  # makes new instances.
29
29
  def initialize
30
- get = Ruff.instance
31
- modify = Ruff.instance
32
-
33
- # delegates effect instances
34
- @eff = OpenStruct.new(get: get, modify: modify)
30
+ # delegates effect instances.
31
+ @eff = OpenStruct.new(
32
+ get: Ruff.instance,
33
+ modify: Ruff.instance
34
+ )
35
35
  end
36
36
 
37
37
  # is a smart method to invoke the effect operation `State.get` .
@@ -105,33 +105,33 @@ module Ruff::Standard::State
105
105
  @inst = Instance.new
106
106
  @eff = @inst.eff
107
107
 
108
- # @see Ruff::Standard::State::Instance#get
108
+ # @see Instance#get
109
109
  def get
110
110
  @inst.get
111
111
  end
112
112
 
113
- # @see Ruff::Standard::State::Instance#modify
113
+ # @see Instance#modify
114
114
  def modify(&fn)
115
115
  @inst.modify(&fn)
116
116
  end
117
117
 
118
- # @see Ruff::Standard::State::Instance#put
118
+ # @see Instance#put
119
119
  def put(s)
120
120
  @inst.put s
121
121
  end
122
122
 
123
- # @see Ruff::Standard::State::Instance#with_init
123
+ # @see Instance#with_init
124
124
  def with_init(init, &task)
125
125
  @inst.with_init init, &task
126
126
  end
127
127
 
128
- # @see Ruff::Standard::State::Instance#with
128
+ # @see Instance#with
129
129
  def with(&task)
130
130
  @inst.with(&task)
131
131
  end
132
132
 
133
133
  module_function :get, :put, :modify, :with, :with_init
134
134
 
135
- # @see Ruff::Standard::Instance#eff
135
+ # @see Instance#eff
136
136
  attr_reader :eff
137
137
  end
@@ -0,0 +1,53 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Util end
4
+
5
+ class Util::FnStack
6
+ def initialize
7
+ @queue = []
8
+ end
9
+
10
+ def enqueue(fn)
11
+ @queue.push fn
12
+ end
13
+
14
+ def dequeue
15
+ hd = @queue.pop
16
+ hd[] unless hd.nil?
17
+ end
18
+
19
+ def cons(hd)
20
+ queue_ = @queue.dup
21
+ queue_.push hd
22
+ end
23
+ end
24
+
25
+ class Util::Ref
26
+ def initialize(v)
27
+ @v = v
28
+ end
29
+
30
+ def get
31
+ @v
32
+ end
33
+
34
+ def set(v_)
35
+ @v = v_
36
+ end
37
+ end
38
+
39
+ module Util::ADT
40
+ def create
41
+ Class.new do
42
+ def initialize(v)
43
+ @value = v
44
+ end
45
+
46
+ def get
47
+ @value
48
+ end
49
+ end
50
+ end
51
+
52
+ module_function :create
53
+ end
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Ruff
4
- VERSION = '1.2.0'
4
+ VERSION = '1.3.0'
5
5
  end
data/version CHANGED
@@ -1 +1 @@
1
- 1.2.0
1
+ 1.3.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.2.0
4
+ version: 1.3.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-04 00:00:00.000000000 Z
11
+ date: 2019-10-06 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
@@ -57,6 +57,8 @@ files:
57
57
  - docs/Ruff/Effect.html
58
58
  - docs/Ruff/Handler.html
59
59
  - docs/Ruff/Standard.html
60
+ - docs/Ruff/Standard/Async.html
61
+ - docs/Ruff/Standard/Async/Instance.html
60
62
  - docs/Ruff/Standard/CurrentTime.html
61
63
  - docs/Ruff/Standard/CurrentTime/Instance.html
62
64
  - docs/Ruff/Standard/Defer.html
@@ -68,6 +70,10 @@ files:
68
70
  - docs/Ruff/Throws.html
69
71
  - docs/Ruff/Throws/Eff.html
70
72
  - docs/Ruff/Throws/Resend.html
73
+ - docs/Util.html
74
+ - docs/Util/ADT.html
75
+ - docs/Util/FnStack.html
76
+ - docs/Util/Ref.html
71
77
  - docs/_index.html
72
78
  - docs/class_list.html
73
79
  - docs/css/common.css
@@ -87,10 +93,12 @@ files:
87
93
  - lib/ruff/handler.rb
88
94
  - lib/ruff/objects.rb
89
95
  - lib/ruff/standard.rb
96
+ - lib/ruff/standard/async.rb
90
97
  - lib/ruff/standard/current_time.rb
91
98
  - lib/ruff/standard/defer.rb
92
99
  - lib/ruff/standard/measure_time.rb
93
100
  - lib/ruff/standard/state.rb
101
+ - lib/ruff/standard/util.rb
94
102
  - lib/ruff/version.gen.sh
95
103
  - lib/ruff/version.rb
96
104
  - ruff.gemspec