fear 2.0.1 → 3.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 (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