@lilactown and others wishing to explore the value-proposition of Monads from a clojure perspective may appreciate this talk https://www.infoq.com/presentations/Macros-Monads/
Monads are very powerful and FWIW, I am glad to see this new library from @nilern ... one of my favorite things about Clojure is that it can be extended so flexibly that we can poach most excellent ideas from other languages.
@blak3mill3r great, let me know how it goes
Any chance to bother you for a sneak peak on how you intend to use it for async IO or effects?
i like the formulation with the various effect operations implemented as different types @nilern ... food for thought - are you heading towards a general purpose effect-combining approach like fused-effects &c ?
So https://github.com/nilern/taksi is my async library, the goal is something similar to Scalaz ZIO and Concurrent ML. I also have a freer monad with higher-order effects for maximum expressivity https://github.com/nilern/fell but I am not sure whether that is even a good idea; the ZIO/polysemy approach might not support backtracking with scoped resources or whatever but that is hardly called for in web apps.
Obviously those should not be used yet and fell
doesn't even use monnit
ATM
this looks great - and i haven't really grokked the free/freer stuff yet, having a clojure should help me with that 🙂
It's hard and dynamic typing probably makes it even harder. Again, not sure if bringing such a thing into Clojure is even a good idea.
well i won't be able to discuss that point until i've grokked them 🙂
but even if free/freer is not the route, i do think that there's a lot of scope for bringing effectful stuff into clojure
Yes and the re-frame (-style) effects processing is very clunky, surely we can do better than that
@nilern How do you know which monad to use in mlet
?
(mlet [a (foo 5)] ...
just becomes (bind (foo 5) (fn [a] ...
and bind
is a protocol method. The mlet
bindings could even use different monads but don't do that (seems that in Haskell do
is not just syntactic sugar after all since using different monads in one do
is a type error).
(In Haskell it is just sugar since bind has the type m a -> (a -> m b) -> m b
; the m
cannot change.)
Now I see. While you have a multimethod pure
, you actually use regular function for the particular monad.
(I see it now.)
Yes there is no magic to emulate return value polymorphism for pure
.
The docs for mlet
is a bit misleading I think, unless I'm missing something.
You found a bug in the docstring, the pure
part would not work (unless you e.g. :refer
monnit.option/pure
)
To make it work you'd have to save away the result of e.g. (foo 0)
and pass that as the first argument to pure
.
Actually (type a)
. algo.monads
implicitly wraps the body in the right pure
and Cats sets a dynamic Var to a MonadContext
so that (pure 0)
usually just works (but there have been bugs).
One of my motivations is to avoid any indirections and tricks like that. Even the pure
multimethod is just for situations where pure
must actually be polymorphic like helper fns/macros.
Unfortunately that approach doesn't work well with lazy evaluation, eg if you use it in a function that you use with map
. Then the context might be missing, or even the wrong context, when running the function.
As I said earlier I usually see dynamic Vars as a code smell. The Reader monad should be less fragile (but the Cats implementation uses dynamic Vars 🤯).
I put out 0.1.2 with docstring improvements https://cljdoc.org/d/com.deepbeginnings/monnit/0.1.2/api/monnit.core (thanks @lodin.johan!)
rewrite-clj
1.0.572-alpha is available. The rewrite-clj library is used to parse and rewrite Clojure/ClojureScript/EDN source from Clojure and CloureScript while preserving whitespace.
After a long, pleasant and circuitous journey, I am pleased to announce the first v1 (alpha) release of https://github.com/clj-commons/rewrite-clj. This release dusts off a well loved Clojure library, and adds https://github.com/clj-commons/rewrite-clj/blob/main/CHANGELOG.adoc#rewrite-clj-v1.
Notably, it merges in, and brings up to feature parity with rewrite-clj v1, the functionalities of https://github.com/clj-commons/rewrite-cljs. The release is looking solid to me, but I expect there to be issues and feedback, hence the alpha status. Thanks to a wonderful community for all the help and delightful interactions. And much thanks to @rundis for rewrite-cljs and @yannick.scherer for rewrite-clj v0.
All with an interest are most welcome to drop on over to #rewrite-clj to chat.