ruff 1.2.0 → 1.3.0

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