fear 2.0.1 → 3.0.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (85) hide show
  1. checksums.yaml +4 -4
  2. data/.github/workflows/spec.yml +1 -5
  3. data/CHANGELOG.md +8 -0
  4. data/Gemfile +14 -2
  5. data/Gemfile.lock +48 -61
  6. data/LICENSE.txt +1 -1
  7. data/README.md +18 -70
  8. data/Rakefile +32 -119
  9. data/benchmarks/dry_do_vs_fear_for.txt +7 -6
  10. data/benchmarks/dry_some_fmap_vs_fear_some_map.txt +7 -6
  11. data/benchmarks/factorial.txt +7 -9
  12. data/benchmarks/fear_gaurd_and1_vs_new.txt +7 -6
  13. data/benchmarks/fear_gaurd_and2_vs_and.txt +8 -7
  14. data/benchmarks/fear_gaurd_and3_vs_and_and.txt +7 -6
  15. data/benchmarks/fear_pattern_matching_construction_vs_execution.txt +7 -6
  16. data/benchmarks/pattern_matching_dry_vs_qo_vs_fear_try.txt +8 -10
  17. data/fear.gemspec +4 -19
  18. data/lib/fear/either/left_projection.rb +237 -0
  19. data/lib/fear/either/pattern_match.rb +49 -0
  20. data/lib/fear/either.rb +20 -11
  21. data/lib/fear/either_api.rb +2 -4
  22. data/lib/fear/empty_partial_function.rb +1 -1
  23. data/lib/fear/failure/pattern_match.rb +14 -0
  24. data/lib/fear/failure.rb +1 -1
  25. data/lib/fear/for_api.rb +0 -2
  26. data/lib/fear/future.rb +1 -1
  27. data/lib/fear/future_api.rb +0 -5
  28. data/lib/fear/left/pattern_match.rb +15 -0
  29. data/lib/fear/left.rb +1 -1
  30. data/lib/fear/none.rb +0 -87
  31. data/lib/fear/none_class/pattern_match.rb +16 -0
  32. data/lib/fear/none_class.rb +85 -0
  33. data/lib/fear/option/pattern_match.rb +47 -0
  34. data/lib/fear/option.rb +1 -5
  35. data/lib/fear/option_api.rb +1 -3
  36. data/lib/fear/partial_function/empty.rb +3 -5
  37. data/lib/fear/partial_function/guard.rb +0 -4
  38. data/lib/fear/partial_function/or_else.rb +0 -2
  39. data/lib/fear/partial_function.rb +0 -9
  40. data/lib/fear/partial_function_class.rb +1 -1
  41. data/lib/fear/pattern_match.rb +3 -2
  42. data/lib/fear/pattern_matching_api.rb +0 -3
  43. data/lib/fear/right/pattern_match.rb +15 -0
  44. data/lib/fear/right.rb +1 -1
  45. data/lib/fear/right_biased.rb +2 -0
  46. data/lib/fear/some/pattern_match.rb +15 -0
  47. data/lib/fear/some.rb +1 -1
  48. data/lib/fear/success/pattern_match.rb +16 -0
  49. data/lib/fear/success.rb +1 -1
  50. data/lib/fear/try/pattern_match.rb +29 -0
  51. data/lib/fear/try.rb +3 -7
  52. data/lib/fear/try_api.rb +0 -2
  53. data/lib/fear/version.rb +1 -1
  54. data/lib/fear.rb +3 -14
  55. data/spec/fear/awaitable_spec.rb +0 -2
  56. data/spec/fear/either/left_projection_spec.rb +289 -0
  57. data/spec/fear/{either_pattern_match_spec.rb → either/pattern_match_spec.rb} +1 -1
  58. data/spec/fear/{option_pattern_match_spec.rb → option/pattern_match_spec.rb} +1 -1
  59. data/spec/fear/partial_function/empty_spec.rb +1 -1
  60. data/spec/fear/{try_pattern_match_spec.rb → try/try_pattern_match_spec.rb} +1 -1
  61. data/spec/support/.keep +0 -0
  62. metadata +29 -255
  63. data/benchmarks/fear_pattern_extracting_with_vs_without_cache.txt +0 -11
  64. data/benchmarks/pattern_matching_qo_vs_fear_pattern_extraction.txt +0 -11
  65. data/benchmarks/pattern_matching_qo_vs_fear_try_execution.txt +0 -11
  66. data/lib/dry/types/fear/option.rb +0 -125
  67. data/lib/dry/types/fear.rb +0 -8
  68. data/lib/fear/either_pattern_match.rb +0 -52
  69. data/lib/fear/failure_pattern_match.rb +0 -12
  70. data/lib/fear/left_pattern_match.rb +0 -11
  71. data/lib/fear/none_pattern_match.rb +0 -14
  72. data/lib/fear/option_pattern_match.rb +0 -50
  73. data/lib/fear/right_pattern_match.rb +0 -13
  74. data/lib/fear/some_pattern_match.rb +0 -13
  75. data/lib/fear/struct.rb +0 -237
  76. data/lib/fear/success_pattern_match.rb +0 -14
  77. data/lib/fear/try_pattern_match.rb +0 -32
  78. data/spec/dry/types/fear/option/constrained_spec.rb +0 -22
  79. data/spec/dry/types/fear/option/core_spec.rb +0 -77
  80. data/spec/dry/types/fear/option/default_spec.rb +0 -21
  81. data/spec/dry/types/fear/option/hash_spec.rb +0 -58
  82. data/spec/dry/types/fear/option/option_spec.rb +0 -97
  83. data/spec/struct_pattern_matching_spec.rb +0 -36
  84. data/spec/struct_spec.rb +0 -194
  85. data/spec/support/dry_types.rb +0 -6
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 478065fc6d889020eb722d84eed56c46187431bb500a359985ee6e2fcb3277a2
4
- data.tar.gz: 9a92582747a64d9525967dec128f8d4cf7e36a32cfc184b6a06ffe1dbc71cf8f
3
+ metadata.gz: 1fa7f6ac3aad235456d308554fccd82ea9c8d7ed5cbb1774047976bed3bd8278
4
+ data.tar.gz: c2dbd3ad5dd6b1780034598d6ca9ea91f55f5dfaa3bf0ba7852b7ebebb9f7944
5
5
  SHA512:
6
- metadata.gz: 9c2ac3a10810f8916efd3dffaa5b71fc57d2c08689ece14dc0fd7e29e9563703221b02f8f482c890cd4c87db784c0459a83395fb2e97acf4cc24a0ca299e5bf4
7
- data.tar.gz: 25f4758ea5c8cb2953e6942e2c64414d135c93f1ffa79f3850dcfe813a4d0b61efc68bb3b6292a3a16f1b76b07e81351393d608728297bdc877ef6b8368db371
6
+ metadata.gz: 164aeb41d3d210239adf73743fcdc3dd472fda922f7a23b6f08960700b3b1cc4dac838bce130cf979100e0f80de4616b5f9baeb2234d943d255228c7fd22ec80
7
+ data.tar.gz: 72b3372bc24b607adfb71b40f65fd2c71b59ba9a2487e7e297ab6bad3452c502ab0b8d39d7ae8b7ada59f2a3bb8d327cc91a75ac8c1c69a139dc4acbf10d78f5
@@ -7,7 +7,7 @@ jobs:
7
7
  runs-on: ubuntu-latest
8
8
  strategy:
9
9
  matrix:
10
- ruby: ['2.7' , '3.0', '3.1', "3.2", "truffleruby+graalvm-head"]
10
+ ruby: ['3.1', "3.2", "3.3", "truffleruby+graalvm-head"]
11
11
  name: ${{ matrix.ruby }}
12
12
 
13
13
  steps:
@@ -19,10 +19,6 @@ jobs:
19
19
  - name: Install dependencies
20
20
  run: bundle install
21
21
  - name: Test
22
- if: ${{ contains(matrix.ruby, 'truffleruby') }}
23
- run: bundle exec rspec --exclude-pattern "**/*_pattern_matching_spec.rb"
24
- - name: Test
25
- if: ${{ !contains(matrix.ruby, 'truffleruby') }}
26
22
  run: bundle exec rspec
27
23
  - name: Coveralls
28
24
  uses: coverallsapp/github-action@v1.1.2
data/CHANGELOG.md CHANGED
@@ -1,3 +1,11 @@
1
+ ## 3.0.0
2
+
3
+ See full changelog here: https://github.com/bolshakov/fear/releases/tag/v3.0.0
4
+
5
+ ## 2.0.1
6
+
7
+ * Fix Fear.option yard signature ([@bolshakov])
8
+
1
9
  ## 2.0.0
2
10
 
3
11
  * Added `Fear::Option#present?` and `Fear::Option#empty?` methods ([@Lokideos][])
data/Gemfile CHANGED
@@ -5,5 +5,17 @@ source "https://rubygems.org"
5
5
  # Specify your gem's dependencies in functional.gemspec
6
6
  gemspec
7
7
 
8
- gem "irb"
9
- gem "qo", github: "baweaver/qo"
8
+ gem "benchmark-ips"
9
+ gem "concurrent-ruby"
10
+ gem "dry-matcher"
11
+ gem "dry-monads"
12
+ gem "dry-types"
13
+ gem "fear-rspec"
14
+ gem "rake", "~> 13.0"
15
+ gem "rspec", "~> 3.1"
16
+ gem "rubocop", "1.32.0"
17
+ gem "rubocop-rspec", "1.34.0"
18
+ gem "ruby_coding_standard"
19
+ gem "simplecov"
20
+ gem "simplecov-lcov"
21
+ gem "yard"
data/Gemfile.lock CHANGED
@@ -1,76 +1,65 @@
1
- GIT
2
- remote: https://github.com/baweaver/qo.git
3
- revision: 8951ce899559118eb60321014b43cf4211730bd0
4
- specs:
5
- qo (0.99.0)
6
- any (= 0.1.0)
7
-
8
1
  PATH
9
2
  remote: .
10
3
  specs:
11
- fear (2.0.1)
4
+ fear (3.0.0)
5
+ zeitwerk
12
6
 
13
7
  GEM
14
8
  remote: https://rubygems.org/
15
9
  specs:
16
- any (0.1.0)
17
10
  ast (2.4.2)
18
- benchmark-ips (2.12.0)
19
- concurrent-ruby (1.2.2)
20
- diff-lcs (1.5.0)
11
+ benchmark-ips (2.13.0)
12
+ bigdecimal (3.1.7)
13
+ concurrent-ruby (1.2.3)
14
+ diff-lcs (1.5.1)
21
15
  docile (1.4.0)
22
- dry-configurable (0.12.1)
23
- concurrent-ruby (~> 1.0)
24
- dry-core (~> 0.5, >= 0.5.0)
25
- dry-container (0.7.2)
26
- concurrent-ruby (~> 1.0)
27
- dry-configurable (~> 0.1, >= 0.1.3)
28
- dry-core (0.5.0)
16
+ dry-core (1.0.1)
29
17
  concurrent-ruby (~> 1.0)
30
- dry-equalizer (0.3.0)
31
- dry-inflector (0.2.0)
32
- dry-logic (1.1.0)
18
+ zeitwerk (~> 2.6)
19
+ dry-inflector (1.0.0)
20
+ dry-logic (1.5.0)
33
21
  concurrent-ruby (~> 1.0)
34
- dry-core (~> 0.5, >= 0.5)
35
- dry-matcher (0.8.0)
36
- dry-core (>= 0.4.7)
37
- dry-monads (1.3.5)
22
+ dry-core (~> 1.0, < 2)
23
+ zeitwerk (~> 2.6)
24
+ dry-matcher (1.0.0)
25
+ dry-core (~> 1.0, < 2)
26
+ dry-monads (1.6.0)
38
27
  concurrent-ruby (~> 1.0)
39
- dry-core (~> 0.4, >= 0.4.4)
40
- dry-equalizer
41
- dry-types (1.5.1)
28
+ dry-core (~> 1.0, < 2)
29
+ zeitwerk (~> 2.6)
30
+ dry-types (1.7.2)
31
+ bigdecimal (~> 3.0)
42
32
  concurrent-ruby (~> 1.0)
43
- dry-container (~> 0.3)
44
- dry-core (~> 0.5, >= 0.5)
45
- dry-inflector (~> 0.1, >= 0.1.2)
46
- dry-logic (~> 1.0, >= 1.0.2)
33
+ dry-core (~> 1.0)
34
+ dry-inflector (~> 1.0)
35
+ dry-logic (~> 1.4)
36
+ zeitwerk (~> 2.6)
47
37
  fear-rspec (0.3.0)
48
38
  fear (>= 1.0.0)
49
39
  rspec (~> 3.0)
50
- irb (1.1.0)
51
- reline (>= 0.0.1)
52
- json (2.6.2)
53
- parallel (1.22.1)
54
- parser (3.1.2.0)
40
+ json (2.7.1)
41
+ parallel (1.24.0)
42
+ parser (3.3.0.5)
55
43
  ast (~> 2.4.1)
44
+ racc
45
+ racc (1.7.3)
56
46
  rainbow (3.1.1)
57
47
  rake (13.1.0)
58
- regexp_parser (2.5.0)
59
- reline (0.0.7)
60
- rexml (3.2.5)
61
- rspec (3.12.0)
62
- rspec-core (~> 3.12.0)
63
- rspec-expectations (~> 3.12.0)
64
- rspec-mocks (~> 3.12.0)
65
- rspec-core (3.12.0)
66
- rspec-support (~> 3.12.0)
67
- rspec-expectations (3.12.0)
48
+ regexp_parser (2.9.0)
49
+ rexml (3.2.6)
50
+ rspec (3.13.0)
51
+ rspec-core (~> 3.13.0)
52
+ rspec-expectations (~> 3.13.0)
53
+ rspec-mocks (~> 3.13.0)
54
+ rspec-core (3.13.0)
55
+ rspec-support (~> 3.13.0)
56
+ rspec-expectations (3.13.0)
68
57
  diff-lcs (>= 1.2.0, < 2.0)
69
- rspec-support (~> 3.12.0)
70
- rspec-mocks (3.12.0)
58
+ rspec-support (~> 3.13.0)
59
+ rspec-mocks (3.13.0)
71
60
  diff-lcs (>= 1.2.0, < 2.0)
72
- rspec-support (~> 3.12.0)
73
- rspec-support (3.12.0)
61
+ rspec-support (~> 3.13.0)
62
+ rspec-support (3.13.1)
74
63
  rubocop (1.32.0)
75
64
  json (~> 2.3)
76
65
  parallel (~> 1.10)
@@ -81,11 +70,11 @@ GEM
81
70
  rubocop-ast (>= 1.19.1, < 2.0)
82
71
  ruby-progressbar (~> 1.7)
83
72
  unicode-display_width (>= 1.4.0, < 3.0)
84
- rubocop-ast (1.19.1)
85
- parser (>= 3.1.1.0)
73
+ rubocop-ast (1.31.2)
74
+ parser (>= 3.3.0.4)
86
75
  rubocop-rspec (1.34.0)
87
76
  rubocop (>= 0.60.0)
88
- ruby-progressbar (1.11.0)
77
+ ruby-progressbar (1.13.0)
89
78
  ruby_coding_standard (0.4.0)
90
79
  rubocop (~> 1.32.0)
91
80
  simplecov (0.22.0)
@@ -95,23 +84,21 @@ GEM
95
84
  simplecov-html (0.12.3)
96
85
  simplecov-lcov (0.8.0)
97
86
  simplecov_json_formatter (0.1.4)
98
- unicode-display_width (2.2.0)
99
- yard (0.9.34)
87
+ unicode-display_width (2.5.0)
88
+ yard (0.9.36)
89
+ zeitwerk (2.6.13)
100
90
 
101
91
  PLATFORMS
102
92
  ruby
103
93
 
104
94
  DEPENDENCIES
105
95
  benchmark-ips
106
- bundler
107
96
  concurrent-ruby
108
97
  dry-matcher
109
98
  dry-monads
110
99
  dry-types
111
100
  fear!
112
101
  fear-rspec
113
- irb
114
- qo!
115
102
  rake (~> 13.0)
116
103
  rspec (~> 3.1)
117
104
  rubocop (= 1.32.0)
@@ -122,4 +109,4 @@ DEPENDENCIES
122
109
  yard
123
110
 
124
111
  BUNDLED WITH
125
- 2.1.4
112
+ 2.5.7
data/LICENSE.txt CHANGED
@@ -1,4 +1,4 @@
1
- Copyright (c) 2015-2019 Tema Bolshakov
1
+ Copyright (c) 2015-2024 Tëma Bolshakov
2
2
 
3
3
  MIT License
4
4
 
data/README.md CHANGED
@@ -632,6 +632,20 @@ Fear.left('left').swap #=> Fear.right('left')
632
632
  Fear.right('right').swap #=> Fear.left('left')
633
633
  ```
634
634
 
635
+ #### Either#left
636
+
637
+ Projects this `Fear::Either` as a `Fear::Left`.
638
+ This allows performing right-biased operation of the left
639
+ side of the `Fear::Either`.
640
+
641
+ ```ruby
642
+ Fear.left(42).left.map(&:succ) #=> Fear.left(43)
643
+ Fear.right(42).left.map(&:succ) #=> Fear.left(42)
644
+
645
+ Fear.left(42).left.select(&:even?) #=> Fear.left(42)
646
+ Fear.right(42).left.select(&:odd?) #=> Fear.right(42)
647
+ ```
648
+
635
649
  #### Either#reduce
636
650
 
637
651
  Applies `reduce_left` if this is a `Left` or `reduce_right` if this is a `Right`.
@@ -1179,76 +1193,7 @@ end
1179
1193
 
1180
1194
  ### Dry-Types integration
1181
1195
 
1182
- #### Option
1183
-
1184
- NOTE: Requires the dry-tyes gem to be loaded.
1185
-
1186
- Load the `:fear_option` extension in your application.
1187
-
1188
- ```ruby
1189
- require 'dry-types'
1190
- require 'dry/types/fear'
1191
-
1192
- Dry::Types.load_extensions(:fear_option)
1193
-
1194
- module Types
1195
- include Dry.Types()
1196
- end
1197
- ```
1198
-
1199
- Append .option to a Type to return a `Fear::Option` object:
1200
-
1201
- ```ruby
1202
- Types::Option::Strict::Integer[nil]
1203
- #=> Fear.none
1204
- Types::Option::Coercible::String[nil]
1205
- #=> Fear.none
1206
- Types::Option::Strict::Integer[123]
1207
- #=> Fear.some(123)
1208
- Types::Option::Strict::String[123]
1209
- #=> Fear.some(123)
1210
- Types::Option::Coercible::Float['12.3']
1211
- #=> Fear.some(12.3)
1212
- ```
1213
-
1214
- 'Option' types can also accessed by calling '.option' on a regular type:
1215
-
1216
- ```ruby
1217
- Types::Strict::Integer.option # equivalent to Types::Option::Strict::Integer
1218
- ```
1219
-
1220
-
1221
- You can define your own optional types:
1222
-
1223
- ```ruby
1224
- option_string = Types::Strict::String.option
1225
- option_string[nil]
1226
- # => Fear.none
1227
- option_string[nil].map(&:upcase)
1228
- # => Fear.none
1229
- option_string['something']
1230
- # => Fear.some('something')
1231
- option_string['something'].map(&:upcase)
1232
- # => Fear.some('SOMETHING')
1233
- option_string['something'].map(&:upcase).get_or_else { 'NOTHING' }
1234
- # => "SOMETHING"
1235
- ```
1236
-
1237
- You can use it with dry-struct as well:
1238
-
1239
- ```ruby
1240
- class User < Dry::Struct
1241
- attribute :name, Types::Coercible::String
1242
- attribute :age, Types::Coercible::Integer.option
1243
- end
1244
-
1245
- user = User.new(name: 'Bob', age: nil)
1246
- user.name #=> "Bob"
1247
- user.age #=> Fear.none
1248
-
1249
- user = User.new(name: 'Bob', age: 42)
1250
- user.age #=> Fear.some(42)
1251
- ```
1196
+ To use `Fear::Option` as optional type for `Dry::Types` use the [dry-types-fear] gem.
1252
1197
 
1253
1198
  ## Testing
1254
1199
 
@@ -1272,3 +1217,6 @@ provides a bunch of rspec matchers.
1272
1217
  * [maybe](https://github.com/bhb/maybe)
1273
1218
  * [ruby-possibly](https://github.com/rap1ds/ruby-possibly)
1274
1219
  * [rumonade](https://github.com/ms-ati/rumonade)
1220
+
1221
+
1222
+ [dry-types-fear]: https://github.com/bolshakov/dry-types-fear
data/Rakefile CHANGED
@@ -2,15 +2,16 @@
2
2
 
3
3
  require "bundler/gem_tasks"
4
4
  require "benchmark/ips"
5
+ require "dry/monads"
5
6
  require_relative "lib/fear"
6
7
 
8
+ include Dry::Monads[:maybe]
9
+
7
10
  namespace :perf do
8
11
  # Contains benchmarking against Dry-rb
9
12
  namespace :dry do
10
13
  task :some_fmap_vs_fear_some_map do
11
- require "dry/monads/maybe"
12
-
13
- dry = Dry::Monads::Some.new(42)
14
+ dry = Some(42)
14
15
  fear = Fear.some(42)
15
16
 
16
17
  Benchmark.ips do |x|
@@ -23,11 +24,9 @@ namespace :perf do
23
24
  end
24
25
 
25
26
  task :do_vs_fear_for do
26
- require "dry/monads/maybe"
27
27
  require "dry/monads/do"
28
28
 
29
29
  class Operation
30
- include Dry::Monads::Maybe::Mixin
31
30
  include Dry::Monads::Do.for(:call)
32
31
 
33
32
  def call
@@ -59,40 +58,21 @@ namespace :perf do
59
58
 
60
59
  # Contains internal benchmarking to if optimization works
61
60
  namespace :fear do
62
- task :fear_pattern_extracting_with_vs_without_cache do
63
- some = Fear.some([:err, "not found"])
64
-
65
- class WOCache < Fear::Extractor::Pattern
66
- def initialize(pattern)
67
- @matcher = compile_pattern_without_cache(pattern)
68
- end
69
- end
70
- pattern = "Fear::Some([:err, code])"
71
-
72
- Benchmark.ips do |x|
73
- x.report("With cache") do |_n|
74
- Fear::Extractor::Pattern.new(pattern).extracted_arguments(some)
75
- end
76
-
77
- x.report("Without cache") do |_n|
78
- WOCache.new(pattern).extracted_arguments(some)
79
- end
80
-
81
- x.compare!
82
- end
83
- end
84
-
85
61
  namespace :guard do
86
62
  task :and1_vs_new do
87
- condition = Integer
63
+ iterations = 1_000
88
64
 
89
65
  Benchmark.ips do |x|
90
66
  x.report("Guard.new") do |n|
91
- Fear::PartialFunction::Guard.new(condition) === n
67
+ iterations.times do
68
+ Fear::PartialFunction::Guard.new(Integer) === n
69
+ end
92
70
  end
93
71
 
94
72
  x.report("Guard.and1") do |n|
95
- Fear::PartialFunction::Guard.and1(condition) === n
73
+ iterations.times do
74
+ Fear::PartialFunction::Guard.and1(Integer) === n
75
+ end
96
76
  end
97
77
 
98
78
  x.compare!
@@ -100,6 +80,7 @@ namespace :perf do
100
80
  end
101
81
 
102
82
  task :and2_vs_and do
83
+ iterations = 1_000
103
84
  first = Integer
104
85
  second = ->(x) { x > 2 }
105
86
 
@@ -108,11 +89,11 @@ namespace :perf do
108
89
 
109
90
  Benchmark.ips do |x|
110
91
  x.report("and2") do |n|
111
- and2 === n
92
+ iterations.times { and2 === n }
112
93
  end
113
94
 
114
95
  x.report("Guard#and") do |n|
115
- and_and === n
96
+ iterations.times { and_and === n }
116
97
  end
117
98
 
118
99
  x.compare!
@@ -120,6 +101,7 @@ namespace :perf do
120
101
  end
121
102
 
122
103
  task :and3_vs_and_and do
104
+ iterations = 1_000
123
105
  first = Integer
124
106
  second = ->(x) { x > 2 }
125
107
  third = ->(x) { x < 10 }
@@ -132,11 +114,11 @@ namespace :perf do
132
114
 
133
115
  Benchmark.ips do |x|
134
116
  x.report("Guard.and3") do |n|
135
- and3 === n
117
+ iterations.times { and3 === n }
136
118
  end
137
119
 
138
120
  x.report("Guard#and") do |n|
139
- and_and_and === n
121
+ iterations.times { and_and_and === n }
140
122
  end
141
123
 
142
124
  x.compare!
@@ -165,16 +147,17 @@ namespace :perf do
165
147
  x.compare!
166
148
  end
167
149
  end
168
- end
169
-
170
- namespace :pattern_matching do
171
- require "qo"
172
- require "dry/matcher"
173
150
 
174
151
  task :option_match_vs_native_pattern_match do
175
152
  some = Fear.some(42)
176
153
 
177
154
  Benchmark.ips do |x|
155
+ matcher = Fear::Option.matcher do |m|
156
+ m.some(41, &:itself)
157
+ m.some(42, &:itself)
158
+ m.some(45, &:itself)
159
+ end
160
+
178
161
  x.report("case ... in ...") do
179
162
  case some
180
163
  in Fear::Some(41 => x)
@@ -186,7 +169,7 @@ namespace :perf do
186
169
  end
187
170
  end
188
171
 
189
- x.report("Option.match") do
172
+ x.report("Option#match") do
190
173
  some.match do |m|
191
174
  m.some(41, &:itself)
192
175
  m.some(42, &:itself)
@@ -194,27 +177,19 @@ namespace :perf do
194
177
  end
195
178
  end
196
179
 
180
+ x.report("Option#matcher") do
181
+ matcher.(some)
182
+ end
183
+
197
184
  x.compare!
198
185
  end
199
186
  end
187
+ end
200
188
 
201
- task :dry_vs_qo_vs_fear_try do
202
- module ExhaustivePatternMatch
203
- def initialize(*)
204
- super
205
- @default ||= self.else { raise Fear::MatchError }
206
- end
207
- end
208
-
209
- SuccessBranch = Qo.create_branch(name: "success", precondition: Fear::Success, extractor: :get)
210
- FailureBranch = Qo.create_branch(name: "failure", precondition: Fear::Failure, extractor: :exception)
211
-
212
- PatternMatch = Qo.create_pattern_match(
213
- branches: [SuccessBranch, FailureBranch],
214
- ).prepend(ExhaustivePatternMatch)
215
-
216
- Fear::Success.include(PatternMatch.mixin(as: :qo_match))
189
+ namespace :pattern_matching do
190
+ require "dry/matcher"
217
191
 
192
+ task :dry_vs_fear_try do
218
193
  success_case = Dry::Matcher::Case.new(
219
194
  match: ->(try, *pattern) {
220
195
  try.is_a?(Fear::Success) && pattern.all? { |p| p === try.get }
@@ -235,14 +210,6 @@ namespace :perf do
235
210
  success = Fear::Success.new(4)
236
211
 
237
212
  Benchmark.ips do |x|
238
- x.report("Qo") do
239
- success.qo_match do |m|
240
- m.failure(&:itself)
241
- m.success(Integer, ->(y) { y % 5 == 0 }, &:itself)
242
- m.success { "else" }
243
- end
244
- end
245
-
246
213
  x.report("Fear") do
247
214
  success.match do |m|
248
215
  m.failure(&:itself)
@@ -263,50 +230,6 @@ namespace :perf do
263
230
  end
264
231
  end
265
232
 
266
- task :qo_vs_fear_try_execution do
267
- module ExhaustivePatternMatch
268
- def initialize(*)
269
- super
270
- @default ||= self.else { raise Fear::MatchError }
271
- end
272
- end
273
-
274
- SuccessBranch = Qo.create_branch(name: "success", precondition: Fear::Success, extractor: :get)
275
- FailureBranch = Qo.create_branch(name: "failure", precondition: Fear::Failure, extractor: :exception)
276
-
277
- QoPatternMatch = Qo.create_pattern_match(
278
- branches: [SuccessBranch, FailureBranch],
279
- ).prepend(ExhaustivePatternMatch)
280
-
281
- Fear::Success.include(QoPatternMatch.mixin(as: :qo_match))
282
-
283
- success = Fear::Success.new(4)
284
-
285
- qo_matcher = QoPatternMatch.new do |m|
286
- m.success(1, &:itself)
287
- m.success(4, &:itself)
288
- m.failure { "failure" }
289
- end
290
-
291
- fear_matcher = Fear::TryPatternMatch.new do |m|
292
- m.success(1, &:itself)
293
- m.success(4, &:itself)
294
- m.failure { "failure" }
295
- end
296
-
297
- Benchmark.ips do |x|
298
- x.report("Qo") do
299
- qo_matcher.(success)
300
- end
301
-
302
- x.report("Fear") do
303
- fear_matcher.(success)
304
- end
305
-
306
- x.compare!
307
- end
308
- end
309
-
310
233
  task :factorial do
311
234
  factorial_proc = proc do |n|
312
235
  if n <= 1
@@ -322,12 +245,6 @@ namespace :perf do
322
245
  m.else { |n| n * factorial_pm.(n - 1) }
323
246
  end
324
247
 
325
- factorial_qo = Qo.match do |m|
326
- m.when(1, &:itself)
327
- m.when(0, &:itself)
328
- m.else { |n| n * factorial_qo.(n - 1) }
329
- end
330
-
331
248
  Benchmark.ips do |x|
332
249
  x.report("Proc") do
333
250
  factorial_proc.(100)
@@ -337,10 +254,6 @@ namespace :perf do
337
254
  factorial_pm.(100)
338
255
  end
339
256
 
340
- x.report("Qo") do
341
- factorial_qo.(100)
342
- end
343
-
344
257
  x.compare!
345
258
  end
346
259
  end
@@ -1,11 +1,12 @@
1
1
  > bundle exec rake perf:dry:do_vs_fear_for
2
+ ruby 3.3.0 (2023-12-25 revision 5124f9ac75) [arm64-darwin23]
2
3
  Warming up --------------------------------------
3
- Dry 31.375k i/100ms
4
- Fear 24.131k i/100ms
4
+ Dry 50.838k i/100ms
5
+ Fear 53.687T i/100ms
5
6
  Calculating -------------------------------------
6
- Dry 360.990k2.7%) i/s - 1.820M in 5.045364s
7
- Fear 7.212B27.2%) i/s - 27.210B in 4.656760s
7
+ Dry 505.586k1.3%) i/s - 2.542M in 5.028546s
8
+ Fear 38414118363278401536.00035.1%) i/s - 129350402624716800000.000 in 4.237227s
8
9
 
9
10
  Comparison:
10
- Fear: 7212177713.5 i/s
11
- Dry: 360989.8 i/s - 19978.90x slower
11
+ Fear: 38414118363278401536.0 i/s
12
+ Dry: 505586.3 i/s - 75979343079241.66x slower
@@ -1,11 +1,12 @@
1
1
  > bundle exec rake perf:dry:some_fmap_vs_fear_some_map
2
+ ruby 3.3.0 (2023-12-25 revision 5124f9ac75) [arm64-darwin23]
2
3
  Warming up --------------------------------------
3
- Dry 68.154k i/100ms
4
- Fear 151.093k i/100ms
4
+ Dry 156.108k i/100ms
5
+ Fear 398.884k i/100ms
5
6
  Calculating -------------------------------------
6
- Dry 884.315k4.1%) i/s - 4.430M in 5.018931s
7
- Fear 2.481M4.1%) i/s - 12.390M in 5.003728s
7
+ Dry 1.561M0.2%) i/s - 7.962M in 5.099636s
8
+ Fear 3.976M0.5%) i/s - 19.944M in 5.016186s
8
9
 
9
10
  Comparison:
10
- Fear: 2480589.0 i/s
11
- Dry: 884315.1 i/s - 2.81x slower
11
+ Fear: 3976079.7 i/s
12
+ Dry: 1561199.0 i/s - 2.55x slower
@@ -1,16 +1,14 @@
1
1
  # Depends on `n`, for 100!:
2
2
 
3
3
  > bundle exec rake perf:pattern_matching:factorial
4
+ ruby 3.3.0 (2023-12-25 revision 5124f9ac75) [arm64-darwin23]
4
5
  Warming up --------------------------------------
5
- Proc 2.395k i/100ms
6
- Fear 312.000 i/100ms
7
- Qo 122.000 i/100ms
6
+ Proc 5.678k i/100ms
7
+ Fear 859.000 i/100ms
8
8
  Calculating -------------------------------------
9
- Proc 26.620k (± 2.9%) i/s - 134.120k in 5.042738s
10
- Fear 3.219k4.1%) i/s - 16.224k in 5.049215s
11
- Qo 1.250k (± 4.8%) i/s - 6.344k in 5.090745s
9
+ Proc 56.634k0.2%) i/s - 283.900k in 5.012921s
10
+ Fear 8.573k0.5%) i/s - 42.950k in 5.009859s
12
11
 
13
12
  Comparison:
14
- Proc: 26620.3 i/s
15
- Fear: 3219.4 i/s - 8.27x slower
16
- Qo: 1249.6 i/s - 21.30x slower
13
+ Proc: 56633.8 i/s
14
+ Fear: 8573.3 i/s - 6.61x slower