https://kotlinlang.org logo
Title
p

pablisco

09/28/2020, 5:15 PM
Literally a 1 char change: https://github.com/arrow-kt/arrow-fx/pull/286/files If anyone is feeling lucky 😎
c

carbaj0

09/28/2020, 5:37 PM
mmm... why are you throw exceptions?
p

pablisco

09/28/2020, 5:53 PM
I'm not 😅 that was there before. It's an terminal operation that propagates the fact that there is no items upward
There is another method called
firstOrNull()
c

carbaj0

09/28/2020, 6:20 PM
I see, it is only a "helper" function that could be useful in some cases
r

raulraja

09/28/2020, 6:21 PM
All terminal ops run effects and can be considered unsafe in streams. That’s why they are
suspend
so the effects including exceptions are handled by the continuation that runs the suspended program.
💯 2
by being suspend they are pure because they can only be composed in other suspend function, so while throwing the exception isn’t great it does not break referential transparency
c

carbaj0

09/28/2020, 6:27 PM
👌
k

kioba

09/30/2020, 2:23 PM
sorry for hanging up on this, but I don’t understand is, why don’t we explicitly return an Either<Error, O>, the caller could explicitly trigger the throw with
getOrThrow
? Should I understand more about where to use Either and where not to?
p

pablisco

09/30/2020, 3:32 PM
I've been thinking about that @kioba if we mirror the API from
Option
to nullables it could be possible to do:
stream.first().orElse { error("Oops!") }
If first() returns nullable
r

raulraja

09/30/2020, 3:39 PM
@pablisco
firstOrElse
?
p

pablisco

09/30/2020, 3:47 PM
Well, I’m thinking about composition of these functions:
fun <O> Stream<O>.first() : O?
fun <O> O?.orElse(block: () -> O) : O
As I mention here: https://github.com/arrow-kt/arrow-fx/pull/291#discussion_r497532005 This means that other operations that result in a nullable can benefit of that api, even the ones that are not part of Arrow. It would mean that we don’t have to maintain
firstOrElse
or similar for other types like ListK, etc. That said, I see the benefit of having shortcuts. For instance if we do:
stream.effectTap { .. }.drain()
We could have:
effectDrain {}
which does something similar… However, maybe there is a way we can automate/generate these composite shortcuts (are these comprehensions?) using Meta 🤔
👍 1
IMHO: smaller API = ❤️
👍 1
r

raulraja

09/30/2020, 4:30 PM
smaller api is better, agreed
And in that sense how is
orElse
different than
?:
p

pablisco

09/30/2020, 6:19 PM
They are functionally the same. The only difference is that
orElse
is easier to chain with other operations. Obviously, in this case we are talking about a terminal operation but I can see cases where it would facilitate working with the result from
?:
Which involves wrapping the statement in parentheses. The other thing is that it can be used to make the code more readable to some people:
fetchMemory()
  .orElse { fetchLocal() }
  .orElse { fetchRemote().andSave() }
Vs
fetchMemory() ?: fetchLocal() ?: fetchRemote().andSave()
Which, if a well intended developer comes after and adds some parentheses:
fetchMemory() ?: (fetchLocal() ?: fetchRemote()).andSave()
Boom! Behaviour is now changed 😅
Also,
orElse
can be considered a
flatMapLeft
, kind of, right?
r

raulraja

09/30/2020, 9:57 PM
yeah not opposed, I think those are valid cases.
specially if it’s all inlined
p

pablisco

09/30/2020, 10:07 PM
Damn it! I just tried to see if it was possible, but it’s not possible to do:
inline class Option<out A>(val value: A?)
nor:
typealias Option<A> = A?
😞 That would have been so nice for migration 😅