This page is not created by, affiliated with, or supported by Slack Technologies, Inc.
hi @dialelo following on from https://github.com/funcool/cats/issues/75 am i missing something obvious ? i've currently got some code using a Deferred[Either] monad (Deferred being my own creation v. similar to canal but for manifold Deferreds rather than core.async chans), and i'd like to use alet instead of mlet for the async concurrency gains...
I know that in monads this is resolved using monad transformers, but I'm not know it the same concept applies to your situation
i'm not using the manifold error - they are being converted to either/left values
The question is, why not use builtin error facilities of the async value primitives that you are using?
because then i get the either short-circuiting behaviour in multi-step computations
ah, yeah, good idea - i could use the on-error behaviour directly in the Deferred monad
what don't you like about deferreds ?
I prefer using something like this https://github.com/funcool/promissum
i'm using aleph, so deferred was an obvious choice for an async primitive
yeah, but the manifold documentation is obscure and only based on code examples or api reference
did you see : https://github.com/ztellman/manifold/blob/master/docs/deferred.md
yeah, they are quite basic. though deferred is quite a simple concept. the stream docs are worse and i had to do more code-reading there
The concept is very simple. You are right. But it not means simple concepts should not to be documented.
ha, well i'm certainly not complaining about better docs, and the funcool libs i've used have great docs
(them being cats and buddy)
the docs are not only about code examples. Are about how to install, how to contribute, the tricky cases, advaced use cases, the project maturity, quick start...
exactly, the situation is improving a bit but many Clojure libraries suffer from lack of good documentation
@mccraigmccraig: have you ended up using deferred's built-in error handling facilities?
@dialelo: i haven't , i'm using Either atm with a monad-transformer
i could use them though
which would get me out of needing to combine applicatives
so you want to be using Deferred[Either]
inside an alet
block and have: short-circuiting (from Either) and the bindings be the right values of either, am i right?
yeah, that was the idea... is that sane ?
or insane
seems reasonable to me, although if your async abstraction already supports error handling i'd go with it
yeah, from what i've read they can be composed generically, and each type doesn't need it's own transformer
there would still presumably need to be something which reified the composed applicative though ?
i can sidestep the problem for now by using manifold's error-handling though
since there are already monad-transformers, it might make sense to add the applicative nesting to those... even if the implementation is just a call to a generic impl
i've been thinking i might want to add a writer to my contexts at some point (the thing that brought me to wanting alet is a high-level async cassandra client) to trace exactly what happened in a given op, so when i get around to that i won't be able to sidestep it in the way i can here
yeah... it's on a holiday from cats atm is it ?
but in our opinion is one of the things that can be achieved more idiomatically in Clojure
of course we may be wrong, we're learning about all these abstractions by writing the library
true - this async stuff is the first thing i've done in clojure where there is real obvious value in the monad abstractions over and above other stuff already in the language
but then, once you've drunk the kool-aid, there seems to be value in being able to compose concepts and be able to rely on tested implementations which are designed to compose
though it's early days for me - i'm learning the abstractions to avoid going insane from callback hell
so a mixed approach may well be best for clojure
yes, it is definitely valuable to compose these abstractions although our context management strategy needs improvements for making them easier to use
but stacking monads through transformers can get complicated once you have more than two layers
so although we implemented reader, writer and state we didn't found ourselves using them at all
ah, ok, i wondered why you took them out
i'm currently looking at http://hackage.haskell.org/package/TypeCompose-0.9.10/docs/src/Control-Compose.html#%3A. for composing 2 applicatives or functors
but don't worry, they are going in under the cats.labs
namespace for the next release
interesting to hear of your experience implementing reader/writer/state and finding you were not using them... i guess i may well find the same... dunno yet. it's all pretty new to me
one thing to be aware of when using composed applicatives in alet
is that alet
uses the monadic bind for removing applicative layers
i see that in our transformers we don't define the applicative instance, i'm opening an issue to solve that
i've started working on implementing functor and applicative for every transformer we provide
oh, awesome... that will be handy - i'll stick with Either for error handling then... i'm already using Either for error handling in my web layer, so somewhere in my stack i will have to convert from manifold to Either error handling anyway
however i don't know when the PR will be ready, today i'm going to work on the core protocols chapter for the CLJS book we're writing https://github.com/funcool/clojurescript-unraveled/pull/98
i kickstarted the applicative work in this PR https://github.com/funcool/cats/pull/77
ok, well i'm not blocked atm, because the monad-transformer impl i have working at the moment works fine... it's just a bit slower than it could be because it's not concurrent enough. if i get to the point of being blocked, or i need a diversion, then i'll have a go at some of the other monads