Skip to content

Commit a735c19

Browse files
committed
Release 0.2.2
1 parent e2b087c commit a735c19

File tree

5 files changed

+77
-8
lines changed

5 files changed

+77
-8
lines changed

README.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -23,13 +23,13 @@ the project!
2323
To test Ox, use the following dependency, using either [sbt](https://www.scala-sbt.org):
2424

2525
```scala
26-
"com.softwaremill.ox" %% "core" % "0.2.1"
26+
"com.softwaremill.ox" %% "core" % "0.2.2"
2727
```
2828

2929
Or [scala-cli](https://scala-cli.virtuslab.org):
3030

3131
```scala
32-
//> using dep "com.softwaremill.ox::core:0.2.1"
32+
//> using dep "com.softwaremill.ox::core:0.2.2"
3333
```
3434

3535
Documentation is available at [https://ox.softwaremill.com](https://ox.softwaremill.com), ScalaDocs can be browsed at [https://javadoc.io](https://www.javadoc.io/doc/com.softwaremill.ox).

generated-doc/out/basics/error-handling.md

Lines changed: 70 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -87,7 +87,7 @@ val result: Either[Int | Long, String] = either:
8787
v1.ok() ++ v2.ok()
8888
```
8989

90-
Finally, options can be unwrapped as well; the error type is then `Unit`:
90+
Options can be unwrapped as well; the error type is then `Unit`:
9191

9292
```scala
9393
import ox.either
@@ -100,6 +100,21 @@ val result: Either[Unit, String] = either:
100100
v1.ok() * v2.ok()
101101
```
102102

103+
Finally, a forked computation, resulting in an `Either`, can be joined & unwrapped using a single `ok()` invocation:
104+
105+
```scala
106+
import ox.{either, fork, Fork, supervised}
107+
import ox.either.ok
108+
109+
val v1: Either[Int, String] = ???
110+
111+
supervised:
112+
val forkedResult: Fork[Either[Int, String]] = fork(either(v1.ok()))
113+
114+
val result: Either[Int, String] = either:
115+
forkedResult.ok()
116+
```
117+
103118
Failures can be reported using `.fail()`. For example (although a pattern match would be better in such a simple case):
104119

105120
```scala
@@ -120,3 +135,57 @@ import ox.catching
120135

121136
val result: Either[Throwable, String] = catching(throw new RuntimeException("boom"))
122137
```
138+
139+
### Nested `either` blocks
140+
141+
Either blocks cannot be nested in the same scope to prevent surprising failures after refactors. The `.ok()` combinator
142+
is typed using inference. Therefore, nesting of `either:` blocks can quickly lead to a scenario where due to a change
143+
in the return type of a method, another `either:` block will be selected by the `.ok()` combinator. This could lead to a
144+
change in execution semantics without a compile error. Consider:
145+
146+
```scala
147+
import ox.either, either.*
148+
149+
def returnsEither: Either[String, Int] = ???
150+
151+
val outerResult: Either[Exception, Unit] = either:
152+
val innerResult: Either[String, Int] = either:
153+
val i = returnsEither.ok() // this would jump to innerResult on Left
154+
// ...
155+
i
156+
()
157+
```
158+
159+
Now, after a small refactor of `returnsEither` return type the `returnsEither.ok()` expression would still compile but
160+
instead of short-circuiting the inner `either:` block, it would immediately jump to the outer `either:` block on errors.
161+
162+
```scala
163+
import ox.either, either.*
164+
165+
def returnsEither: Either[Exception, Int] = ???
166+
167+
val outerResult: Either[Exception, Unit] = either:
168+
val innerResult: Either[String, Int] = either:
169+
val i = returnsEither.ok() // this would jump to outerResult on Left now!
170+
// ...
171+
i
172+
()
173+
```
174+
175+
Proper way to solve this is to extract the inner `either:` block to a separate function:
176+
177+
```scala
178+
import ox.either, either.*
179+
180+
def returnsEither: Either[String, Int] = ???
181+
182+
def inner(): Either[String, Int] = either:
183+
val i = returnsEither.ok() // this can only jump to either on the opening of this function
184+
i
185+
186+
val outerResult: Either[Exception, Unit] = either:
187+
val innerResult = inner()
188+
()
189+
```
190+
191+
After this change refactoring `returnsEither` to return `Either[Exception, Int]` would yield a compile error on `returnsEither.ok()`.

generated-doc/out/basics/start-here.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,10 +4,10 @@
44

55
```scala
66
// sbt dependency
7-
"com.softwaremill.ox" %% "core" % "0.2.1"
7+
"com.softwaremill.ox" %% "core" % "0.2.2"
88

99
// scala-cli dependency
10-
//> using dep "com.softwaremill.ox::core:0.2.1"
10+
//> using dep "com.softwaremill.ox::core:0.2.2"
1111
```
1212

1313
## Scope of the Ox project

generated-doc/out/io.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -68,13 +68,13 @@ To use the plugin, add the following settings to your sbt configuration:
6868

6969
```scala
7070
autoCompilerPlugins := true
71-
addCompilerPlugin("com.softwaremill.ox" %% "plugin" % "0.2.1")
71+
addCompilerPlugin("com.softwaremill.ox" %% "plugin" % "0.2.2")
7272
```
7373

7474
For scala-cli:
7575

7676
```scala
77-
//> using plugin com.softwaremill.ox:::plugin:0.2.1
77+
//> using plugin com.softwaremill.ox:::plugin:0.2.2
7878
```
7979

8080
With the plugin enabled, the following code won't compile:

generated-doc/out/kafka.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
Dependency:
44

55
```scala
6-
"com.softwaremill.ox" %% "kafka" % "0.2.1"
6+
"com.softwaremill.ox" %% "kafka" % "0.2.2"
77
```
88

99
`Source`s which read from a Kafka topic, mapping stages and drains which publish to Kafka topics are available through

0 commit comments

Comments
 (0)