From the article: "Try can never yield pure functi...
# arrow
j
From the article: "Try can never yield pure functions since it’s eager and executes the effects on construction; it can only be made pure by marking it as suspend." Suspend marks side effects, and throwing exceptions, the whole purpose of code run in catch, is a side effect.
☝️ 1
n
I would not agree with fact that exception is side effect, e.g.:
Copy code
val result = Either.catch { 1/0 }
j
Yes that is still a side effect, integer division is not total and since it's return type does not indicate failure (option/either) it must throw an exception. Side effects are any changes that are visible outside of the return value and thrown exceptions are just that
If your return value does not indicate that a function may fail (with either, option or any monad error type like io) it should never throw
k
but
catch
itself never fails, and catch indicates the error with the return type 🤔 is it because
suspended
functions could only be called from a
suspended
function?
j
The side effect is not catching, it's throwing and the argument to
Either.catch
only makes sense if it can throw, hence suspend is needed. And
Either.catch
needs to be suspend because evaluating a suspended function needs to be in
suspend
because suspend can carry more than just throwing as a side effect.
k
yeah as expected it is the burden of chain. the part where you mention
"suspend can carry more than just throwing as a side effect"
<- this is interesting, can you suggest somewhere to read more about this?
j
it's equivalent (in power) to
IO
and
IO
can carry any effect, in terms of power its infinite for
IO
. (Which is also why I don't like plain
IO
but the only language capable of providing fast and easy to use effect systems is haskell 😕 ). A good way to view it is: You can lift any, literally any, effect into an
IO
value (and suspend as it's equivalent in power). Don't know where some good resources are, I think haskell effect systems provide some overview, I'll check that in a sec
Can't find anything good atm. But think about it this way:
IO
models any effect: Exceptions, Concurreny, Parallelism, Delay, State, Input, Output, Launching nukes and more. A return value of
IO<A>
or
suspend fun(): A
can do all of those and more. And that is why it has to be marked as such. In haskell with mtl or extensible effects you have more fine grained control where you can define literally any effect and defer lifiting it to
IO
as late as possible to further constrain functions. That is also (in part) the point for
Free
monads. You can define and test functions that, for example, return
Par<A>
which only allows parallel computation effects but not all of
IO
. That obviously needs to be evaluated to
IO
later, but for reasoning about that code you know that it can only do parallel computations. Sorry if this is somewhat incoherent 🙂 I am basically just writing down my thoughts on this as they come 😄
1
k
you should do it more 🙂 writing down my thoughts! I didn’t think about
suspend
this way. I don’t say I understand the whole concept but I see the idea now. I Suppose that is the part which is used by the Android Compose framework where the effect is a widget tree 🤔
👍 1
j
suspend
and
IO
is definitly quite arbitrary at first (especially if you know that haskell defines it as
State<RealWorld, A>
which seems even crazier as it's completely eliminated by the compiler and only exists for reasoning about code). I have never written a single line of code for android etc, how does this model look? I write down thoughts all the time in code ^-^ But that is usually just a reminder for me, mental models for more complex parts of whatever I am writing. Maybe I should just write stuff down somewhere public if its interesting enough 🙂
👍 1
🤔 1
k
I’m not exactly sure what you mean about the model in droid, We still figuring out the path on the platform but as you might know Andorid is super OOP inspired and the shift is just happening with compose. The only person I know on andorid with Comonadic UI implementation is @Jorge Castillo. He might can help here clear out some stuff
if you are asking about compose, well the effect is basically updates a
State<WidgetTree, A>
, it might be better explained by Leland Richardson’s post http://intelligiblebabble.com/compose-from-first-principles/ the last part is the interesint one with the title of
The @Composable Annotation
j
Interesting to see how reacts style comes over to so many other projects and languages :) definitely something I'll read in more detail thanks :)
👍 1