Re: Monads and Middleware
Functions are a type of monad, and function composition is a type of monadic binding. You could certainly say that middleware are a type of monad, but so many things can be thought of as monads that's not hugely useful in and of itself. - James On 1 July 2016 at 18:14, Scott Klarenbach <doyouunderst...@gmail.com> wrote: > I'm looking for some insight into the relationship between Monads and > Middleware. > > It seems to me that middleware (ala Ring, Boot) is really just a subset of > Monads, where bind and lift are globally agreed upon conventions, rather > than explicitly defined. For example, with middleware you need every > function to accept and return the same signature so as to be composable, > whereas with monads you explicitly provide the code for binding and lifting > into and out of the monad world. > > My basic questions are: > > 1.) Is middleware really a monad with a different name? > 2.) Is there any compelling reason to use monads in clojure instead of > middleware? > 3.) Are there classes of problems that can be solved with monads that > can't be solved with middleware? > 4.) Is there any benefit (beyond curiosity) to porting/re-implementing > middleware as monads? > > Thanks. > > Scott Klarenbach > www.invisiblerobot.io > > > -- > You received this message because you are subscribed to the Google > Groups "Clojure" group. > To post to this group, send email to clojure@googlegroups.com > Note that posts from new members are moderated - please be patient with > your first post. > To unsubscribe from this group, send email to > clojure+unsubscr...@googlegroups.com > For more options, visit this group at > http://groups.google.com/group/clojure?hl=en > --- > You received this message because you are subscribed to the Google Groups > "Clojure" group. > To unsubscribe from this group and stop receiving emails from it, send an > email to clojure+unsubscr...@googlegroups.com. > For more options, visit https://groups.google.com/d/optout. > -- You received this message because you are subscribed to the Google Groups "Clojure" group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en --- You received this message because you are subscribed to the Google Groups "Clojure" group. To unsubscribe from this group and stop receiving emails from it, send an email to clojure+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/d/optout.
Monads and Middleware
I'm looking for some insight into the relationship between Monads and Middleware. It seems to me that middleware (ala Ring, Boot) is really just a subset of Monads, where bind and lift are globally agreed upon conventions, rather than explicitly defined. For example, with middleware you need every function to accept and return the same signature so as to be composable, whereas with monads you explicitly provide the code for binding and lifting into and out of the monad world. My basic questions are: 1.) Is middleware really a monad with a different name? 2.) Is there any compelling reason to use monads in clojure instead of middleware? 3.) Are there classes of problems that can be solved with monads that can't be solved with middleware? 4.) Is there any benefit (beyond curiosity) to porting/re-implementing middleware as monads? Thanks. Scott Klarenbach www.invisiblerobot.io -- You received this message because you are subscribed to the Google Groups "Clojure" group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en --- You received this message because you are subscribed to the Google Groups "Clojure" group. To unsubscribe from this group and stop receiving emails from it, send an email to clojure+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/d/optout.
Re: [ANN] Fluokitten - Category theory concepts in Clojure - Functors, Applicatives, Monads, Monoids and more
*New version, 0.4.0 released:* http://fluokitten.uncomplicate.org/ has lots of documentation and tutorials. Source at: https://github.com/uncomplicate/fluokitten New features: - Added PseudoFunctor, PseudoApplicative, and PseudoMonad, to support destructive operations in Neanderthal. - Better support for functions and curried functions. - fold, foldmap, and op much improved with variadic versions. - Varargs versions of pure, return, and unit. Changes: - fmap implementation for function changed to be in line with bind; supports multi-arity functions and offer super-comp. - Collections use reducers where appropriate. - op, fold, foldmap, support multiple arguments, have better implementations. On Monday, July 22, 2013 at 4:33:48 PM UTC+2, Phillip Lord wrote: > > > > That's a good answer! I've enjoyed reading the documentation of both > fluokitten and morph and understood it. The functionality certainly > seems useful. > > Phil > > Dragan Djuric <drag...@gmail.com > writes: > > > If Clojure has all of the Haskell's type features, I guess there would > be > > only one Clojure monad library, more or less a direct port of Haskell's. > As > > Clojure is different, there are different ways to approach monads from > > neither of which can be the same as Haskell's, each having its pros and > > cons, so there are many libraries. Additional motivation in my case is > that > > the other libraries (except morph, which is also a newcomer) were poorly > > documented or not documented at all, and that even simple examples from > > Haskell literature were not simple at all in those libraries, and in > many > > cases, not even supported (many of them don't even define functors and > > monoids, let alone applicative functors). > > > > What I've not yet understood is what the difference is between all of > >> these libraries? > >> > >> > > > > -- > > -- > Phillip Lord, Phone: +44 (0) 191 222 7827 > Lecturer in Bioinformatics, Email: philli...@newcastle.ac.uk > > School of Computing Science, > http://homepages.cs.ncl.ac.uk/phillip.lord > Room 914 Claremont Tower, skype: russet_apples > Newcastle University, twitter: phillord > NE1 7RU > -- You received this message because you are subscribed to the Google Groups "Clojure" group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en --- You received this message because you are subscribed to the Google Groups "Clojure" group. To unsubscribe from this group and stop receiving emails from it, send an email to clojure+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/d/optout.
[ANN] monads 0.2.2
After a surprisingly long time I'm releasing a new version of my monads library, focussed on expressivity and correctness: https://github.com/bwo/monads Leiningen: [bwo/monads 0.2.2] Improvements from 0.1.0 include: - change from maps to protocols for monad implementations, which has increased flexibility and speed (this library is once again a little faster than morph) - all monad implementations interoperate with algo.generic.functor - monad transformers automatically lift operations from inner monads, if they're supported - a combined reader/writer/state monad (and transformer) was introduced, and the (faulty) list-t monad transformer was removed - improvements to call/cc, shift, and reset for the continuation monad - an applicative functor protocol was introduced, and implementations provided for several existing types and all monad implementations. Also, the `mdo` syntax macro was abstracted out and can now accept an arbitrary user-provided function for doing monadic binds, which should mean that it can be used with other libraries, though I haven't actually tested this. -- Ben Wolfson Human kind has used its intelligence to vary the flavour of drinks, which may be sweet, aromatic, fermented or spirit-based. ... Family and social life also offer numerous other occasions to consume drinks for pleasure. [Larousse, Drink entry] -- You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en --- You received this message because you are subscribed to the Google Groups Clojure group. To unsubscribe from this group and stop receiving emails from it, send an email to clojure+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/d/optout.
Re: monads not working in Clojure 1.4.0
Thanks Michael. On Saturday, November 9, 2013 10:26:09 AM UTC-8, Michael Klishin wrote: 2013/11/9 Gary Zhao gary...@gmail.com javascript: NoSuchMethodError clojure.lang.RT.mapUniqueKeys([Ljava/lang/Object;)Lclojure/lang/IPersistentMap; clojure.algo.monads/loading--4910--auto-- (monads.clj:11) It means you have some code compiled against 1.5.1 in monads, one of the other libraries or your own code. Run lein clean and try again. -- MK http://github.com/michaelklishin http://twitter.com/michaelklishin -- -- You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en --- You received this message because you are subscribed to the Google Groups Clojure group. To unsubscribe from this group and stop receiving emails from it, send an email to clojure+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/groups/opt_out.
monads not working in Clojure 1.4.0
Hello I saw the following error when using monads in Clojure 1.4.0, however it worked fine in Clojure 1.5.1. Isn't monads compatible with 1.4.0? [org.clojure/clojure 1.4.0] [org.clojure/algo.monads 0.1.4] NoSuchMethodError clojure.lang.RT.mapUniqueKeys([Ljava/lang/Object;)Lclojure/lang/IPersistentMap; clojure.algo.monads/loading--4910--auto-- (monads.clj:11) Thanks Gary -- -- You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en --- You received this message because you are subscribed to the Google Groups Clojure group. To unsubscribe from this group and stop receiving emails from it, send an email to clojure+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/groups/opt_out.
Re: monads not working in Clojure 1.4.0
2013/11/9 Gary Zhao garyz...@gmail.com NoSuchMethodError clojure.lang.RT.mapUniqueKeys([Ljava/lang/Object;)Lclojure/lang/IPersistentMap; clojure.algo.monads/loading--4910--auto-- (monads.clj:11) It means you have some code compiled against 1.5.1 in monads, one of the other libraries or your own code. Run lein clean and try again. -- MK http://github.com/michaelklishin http://twitter.com/michaelklishin -- -- You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en --- You received this message because you are subscribed to the Google Groups Clojure group. To unsubscribe from this group and stop receiving emails from it, send an email to clojure+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/groups/opt_out.
Re: [ANN] Fluokitten - Category theory concepts in Clojure - Functors, Applicatives, Monads, Monoids and more
That's a good answer! I've enjoyed reading the documentation of both fluokitten and morph and understood it. The functionality certainly seems useful. Phil Dragan Djuric draga...@gmail.com writes: If Clojure has all of the Haskell's type features, I guess there would be only one Clojure monad library, more or less a direct port of Haskell's. As Clojure is different, there are different ways to approach monads from neither of which can be the same as Haskell's, each having its pros and cons, so there are many libraries. Additional motivation in my case is that the other libraries (except morph, which is also a newcomer) were poorly documented or not documented at all, and that even simple examples from Haskell literature were not simple at all in those libraries, and in many cases, not even supported (many of them don't even define functors and monoids, let alone applicative functors). What I've not yet understood is what the difference is between all of these libraries? -- -- Phillip Lord, Phone: +44 (0) 191 222 7827 Lecturer in Bioinformatics, Email: phillip.l...@newcastle.ac.uk School of Computing Science, http://homepages.cs.ncl.ac.uk/phillip.lord Room 914 Claremont Tower, skype: russet_apples Newcastle University, twitter: phillord NE1 7RU -- -- You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en --- You received this message because you are subscribed to the Google Groups Clojure group. To unsubscribe from this group and stop receiving emails from it, send an email to clojure+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/groups/opt_out.
[ANN] Fluokitten 0.3.0 - Monads and more - now features
Fluokitten - Category Theory in Idiomatic Clojure has just been upgraded to 0.3.0 Get started guide: http://fluokitten.uncomplicate.org/articles/getting_started.html The library is in the clojars, so lein will pick it up easily. There are lot of new features: - mdo macro as a syntactic sugar for chained bind calls. - Implicit context (monad, functor, applicative) supported inside the dynamic scope of bind and all functions/macros that depend on it (=, mdo etc.) - return (also called unit) function, a version of pure that uses the implicit context. - with-context macro enables setting the implicit context for arbitrary body of expressions. - = and = functions that compose monadic functions. The documentation and the tutorials have been improved and updated. Please check the existing tutorials out and post your thoughts here. Your feedback is very valuable for making this library better. -- -- You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en --- You received this message because you are subscribed to the Google Groups Clojure group. To unsubscribe from this group and stop receiving emails from it, send an email to clojure+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/groups/opt_out.
Re: [ANN] Fluokitten - Category theory concepts in Clojure - Functors, Applicatives, Monads, Monoids and more
Hi Ben and everyone who participated in the discussion. Most of the issues we have been discussed (most notably mdo and agnostic return) have been implemented in the newly released version 0.3.0. No macrology was necessary for agnostic return :) Please try the new version and post your feedback. On Wednesday, July 3, 2013 9:31:58 PM UTC+2, Ben wrote: On Wed, Jul 3, 2013 at 7:49 AM, Dragan Djuric drag...@gmail.comjavascript: wrote: Monads as a Haskell construct is what the previously mentioned laws describe. Monads in category theory are defined in a category X as a triple (T, n, m) where T is a functor and m and n certan natural transformations such that certan diagrams commute. In that sense, I am not sure that even Haskell's implementation is perfectly clean. There's a lot of nitpicking to be done, but, that's not the point, and we are digressing a bit. The point is that in Fluokitten, you are expected to work within the certain monad as you agree, and since there is no type checking on the value that a function returns, it is the responsibility of the developer to make sure that it makes sense as in Clojure generally. It is fairly easy to do by passing a parameter to f that pure can use, if f implementation needs to be agnostic to the actual monad that it will be called from. There are other approaches, so the programmer can make a choice that is the best fit for the problem at hand. Even in the example that you gave from your library, what stops the programmer to shoot himself in the foot by doing basically the same thing that we are talking about here: (defn f [g] (comp atom g g)) (require '[monads.maybe :as m]) (def mc (= (return 3) (f inc))) (run-monad m/m mc) What is the result if f is broken (in the context of the monad m/m in this case)? I didn't try it, so I may be wrong, but I doubt that the Clojure compiler complains about that one. Of course the compiler doesn't complain, how could it? I'm not asking you to have the clojure compiler complain. I'm attempting to point out that your library makes it impossible to write generic functions involving monads. That is, for fluokitten, you *have* to write f as something like (comp atom g g) or (comp vector g g) or (comp just g g) or whatever. You don't have the option of writing (comp return g g) and having that work right when the function is run in *multiple* monads. Which is a major expressivity drawback, in my mind. This is basically the same thing as comes up with Armando Blancas' morph library, which is, like yours, based on protocols. The expressivity point is the key, not the nonexistent haskell-in-clojure typechecker. That's why I asked the question I asked in my first email: whether it's possible to write this function (which I've desugared): (defn tst-reader [f] (= ask (fn [env] (= (lift (f env)) (fn [_] (= (return (println here I am)) (fn [_] (return v which can operate in an instance of the reader monad transformer parametrized by an *arbitrary* inner monad---so that you don't know in advance what the return or = should be (and you don't know in advance what the lift should be, since more than one interpretation of the reader monad is possible---all that's required here is that the monad support an ask operation). I suppose you could thread specimen special return, bind, ask, and lift functions through (and if you used fancy macrology to do that, you'd have the core.monads approach), but that's really quite cumbersome. IMO, the ability to write code like that is a large part of what makes monadic abstraction powerful and interesting. -- Ben Wolfson Human kind has used its intelligence to vary the flavour of drinks, which may be sweet, aromatic, fermented or spirit-based. ... Family and social life also offer numerous other occasions to consume drinks for pleasure. [Larousse, Drink entry] -- -- You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en --- You received this message because you are subscribed to the Google Groups Clojure group. To unsubscribe from this group and stop receiving emails from it, send an email to clojure+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/groups/opt_out.
Re: [ANN] Fluokitten - Category theory concepts in Clojure - Functors, Applicatives, Monads, Monoids and more
Thanks for the tip, Michael. I added a notification on every page, for the TL;DR crowd, so I hope that will catch the attention of enough people and improve the future readability of the docs. On Wednesday, July 3, 2013 2:34:33 PM UTC+2, Michael Klishin wrote: 2013/7/3 Dragan Djuric drag...@gmail.com javascript: The site source is in the gh-pages branch in the main source repository on github: https://github.com/uncomplicate/fluokitten/tree/gh-pages It's worth mentioning somewhere. ClojureWerkz projects link to doc source at the top of every guide, adding a README link is fine, too. -- MK http://github.com/michaelklishin http://twitter.com/michaelklishin -- -- You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en --- You received this message because you are subscribed to the Google Groups Clojure group. To unsubscribe from this group and stop receiving emails from it, send an email to clojure+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/groups/opt_out.
Re: [ANN] Fluokitten - Category theory concepts in Clojure - Functors, Applicatives, Monads, Monoids and more
On Wednesday, July 3, 2013 2:06:34 AM UTC+2, Ben wrote: On Tue, Jul 2, 2013 at 4:33 PM, Dragan Djuric drag...@gmail.comjavascript: wrote: And in this case you have to explicitly specify which monad you want to use, every time you call bind. I understand that in some case it might be a preferred way, but in my opinion for most cases that I care about I prefer it the other way. No, you don't. You don't have to specify the monad you want to use until you actually want to use it: Unless you need to use two or more different monads in that function, in which case I don't see now would you do that at all. And, you have to structure the code a bit awkwardly for clojure, and have to say specifically, I want such and such monad type, and run it with a runner. I'm not saying that that is not good option. Clojure has its features and some compromise has to be made. I just prefer the sort of compromises I made for Fluokitten to the sorts of compromises made by other libraries. ; nREPL 0.1.7 user #Namespace monads.core monads.core (defn mc [x] (= (return x) (fn [a] (= (return (inc a)) (fn [b] (return (+ x (* 2 b #'monads.core/mc monads.core (def m* (mc 5)) #'monads.core/m* monads.core (require '[monads.identity :as i] '[monads.maybe :as m]) nil monads.core (run-monad i/m m*) 17 monads.core (run-monad m/m m*) #Just 17 monads.core m* is already defined in a completely agnostic way before it's run. I thought i had already demonstrated that in my previous email when I defined mc as (= (return 3) (f inc)), prior to interpreting it in the context of any particular monad. Regarding monadic laws, which one exactly demands that you cannot change the monad (not counting the fact that haskell's implementation does it that way)? Here are the laws, in Haskell: return a = k = k a m = return= m m = (\x - k x = h) = (m = k) = h It seems to me the laws are still satisfied if you keep changing monads in each bind (if compiler is not restricting it, as is the case with Haskell but not with Clojure). I suppose that may be right: you're supposed to verify that the laws obtain for a putative monad; they don't come for free just by calling something a monad. Allowing = to have the type m a - (a - n b) - n b just means that you can't verify that yours obeys the laws. If you get to choose the type of return, even the second one is up for grabs! It does seem somewhat odd to me to advertise the package as being familiar to Haskellers and to employ category-theoretic concepts and then to be so blasé about the definition of a monad. (I wonder if you can get away with this changing of type at all if you define bind in terms of fmap and join). Here is how the laws are specified (and tested) in Fluokitten (writing from the top of my head so please excuse me if I mess up something): (def return (pure [])) ;;This def is to make it more familiar for those who already read this tread, it is not actually in fluokitten tests. (def k (comp return foo bar baz)) ;; note the agnostic return. There are ways in Clojure to change what is it bound for, but I won't go into that here, It does not seem that important to me now. The point is, fluokitten supports it... (= (return a) k) = (k a) (= [1 2 3] return) = m (= [1 2 3] (fn [x] (bind (k x) h))) = (= m k h) So, if monad stays the same, everything is nice and tidy and close enough to Clojure and Haskell. Now, what would happen if monad changes after the bind? The first law does not constrain it The second does not too, since it says what happens when you bind with (pure m) not (pure n) The third, associativity, will also be satisfied Haskell compiler would complain wildly, but there is no Haskell compiler in my REPL :) Can I prove it? NO, I didn't try. As you say, most of the time you will work in the same monad. Since Clojure is dynamic, the programmer is expected to take an extra care and test that everything works as expected. But, it seems to me that, even if the monad change, (in most cases?) it will still work... On Wednesday, July 3, 2013 1:19:10 AM UTC+2, Ben wrote: IMO you *always* want the monad to stay the same---the laws describing monadic computations don't account for swapping the things out midstream, at any rate. And it pays to be able to define monadic computations without having to explicitly pass around a token to serve as the current monad. FWIW, you *can* directly translate that function into clojure: monads.core (defn f [g] (comp return g g)) #'monads.core/f monads.core (require '[monads.state :as st]) nil monads.core (st/run-state (= get-state (f inc)) 5) #Pair [7 5] monads.core (require '[monads.list :as l]) nil monads.core (require '[monads.maybe :as m]) nil monads.core (def mc (= (return 3) (f inc
Re: [ANN] Fluokitten - Category theory concepts in Clojure - Functors, Applicatives, Monads, Monoids and more
The specific bind implementations always get the instance of the Monad protocol the bind was called with (since it is a part of an implementation of the Monad protocol), so you use that instance as a first argument to pure. Of course, if you call bind with a function that does not make sense in a context, you'll get a runtime exception, like in the rest of Clojure. Clojure is not strongly typed, so it puts some expectations on the programmer. I am not trying to fix Clojure. Thank you for some very thoughtful comments. If you are interested, we can try to write a bit more detailed comparisons of the approaches in both libraries. On Wednesday, July 3, 2013 2:21:29 AM UTC+2, Ben wrote: On Tue, Jul 2, 2013 at 5:06 PM, Ben Wolfson wol...@gmail.comjavascript: wrote: On Tue, Jul 2, 2013 at 4:33 PM, Dragan Djuric drag...@gmail.comjavascript: wrote: Regarding monadic laws, which one exactly demands that you cannot change the monad (not counting the fact that haskell's implementation does it that way)? Here are the laws, in Haskell: return a = k = k a m = return= m m = (\x - k x = h) = (m = k) = h It seems to me the laws are still satisfied if you keep changing monads in each bind (if compiler is not restricting it, as is the case with Haskell but not with Clojure). I suppose that may be right: you're supposed to verify that the laws obtain for a putative monad; they don't come for free just by calling something a monad. Allowing = to have the type m a - (a - n b) - n b just means that you can't verify that yours obeys the laws. If you get to choose the type of return, even the second one is up for grabs! It does seem somewhat odd to me to advertise the package as being familiar to Haskellers and to employ category-theoretic concepts and then to be so blasé about the definition of a monad. (I wonder if you can get away with this changing of type at all if you define bind in terms of fmap and join). How are you even supposed to implement bind, in fact? (Never mind reasoning about what's going on in your program if you can't be certain that the code won't switch out the monad you think you're working in, when it does matter to you that you're in a specific one.) Generally for some specific monad you need to do something specific with the return of f. For instance, your seq-bind is implemented in terms of mapcat---meaning that the f that's the second argument of mapcat had better return a seqable. This doesn't work: (mapcat (comp atom inc) '(1 2 3)). -- Ben Wolfson Human kind has used its intelligence to vary the flavour of drinks, which may be sweet, aromatic, fermented or spirit-based. ... Family and social life also offer numerous other occasions to consume drinks for pleasure. [Larousse, Drink entry] -- -- You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en --- You received this message because you are subscribed to the Google Groups Clojure group. To unsubscribe from this group and stop receiving emails from it, send an email to clojure+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/groups/opt_out.
Re: [ANN] Fluokitten - Category theory concepts in Clojure - Functors, Applicatives, Monads, Monoids and more
This looks fantastic. I probably won't be able to resist to type check it with core.typed at some point. And enough documentation to satisfy Michael Klishin? I'm impressed :) Thanks, Ambrose On Wed, Jul 3, 2013 at 2:07 AM, Dragan Djuric draga...@gmail.com wrote: I am pleased to announce a first public release of new (and different) monads and friends library for Clojure. Extensive *documentation* is at http://fluokitten.uncomplicate.org Fluokitten is a Clojure library that implements category theory concepts, such as functors, applicative functors, monads, monoids etc. in idiomatic Clojure. Main project goals are: - Fit well into idiomatic Clojure - Clojure programmers should be able to use and understand Fluokitten like any regular Clojure library. - Fit well into Haskell monadic types conventions - programmers should be able to reuse existing widespread monadic programming know-how and easily translate it to Clojure code. - Be reasonably easy to learn - the code from the existing books, articles and tutorials for learning monadic programming, which is usually written in Haskell should be easily translatable to Clojure with Fluokitten. - Offer good performance. Please give us your feedback, and we would also love if anyone is willing to help, regardless of previous experience, so please *get involved*. There are lots of things to be improved: - If you are a native English speaker, i would really appreciate if you can help with correcting the English on the Fluokitten site and in the documentation. - Contribute your example code (your own or the ports from Haskell tutorials) to be added to Fluokitten tests. - Contribute articles and tutorials. - Do code review of the Fluokitten code and suggest improvements. - If you find bugs, report them via Fluokitten issue tracker. - If you have any additional suggestion, contact us here: http://fluokitten.uncomplicate.org/articles/community.html -- -- You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en --- You received this message because you are subscribed to the Google Groups Clojure group. To unsubscribe from this group and stop receiving emails from it, send an email to clojure+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/groups/opt_out. -- -- You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en --- You received this message because you are subscribed to the Google Groups Clojure group. To unsubscribe from this group and stop receiving emails from it, send an email to clojure+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/groups/opt_out.
Re: [ANN] Fluokitten - Category theory concepts in Clojure - Functors, Applicatives, Monads, Monoids and more
I probably won't be able to resist to type check it with core.typed at some point. If you contribute that, or help me baking in (some) non-invasive type checking into Fluokitten, that would be FANTASTIC! I have that in vague long-term plans, but I haven't had time to look at core.typed (I only skimmed through the homepage when it was released). And enough documentation to satisfy Michael Klishin? I'm impressed :) Thanks :) Actually, one of the main project goals is to make monads (et al) approachable for beginners, and for that, docs and tutorials are the main thing. So, this library really does not make much sense without lots of documentation. I hope to even improve it on that point. -- -- You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en --- You received this message because you are subscribed to the Google Groups Clojure group. To unsubscribe from this group and stop receiving emails from it, send an email to clojure+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/groups/opt_out.
Re: [ANN] Fluokitten - Category theory concepts in Clojure - Functors, Applicatives, Monads, Monoids and more
On Wed, Jul 3, 2013 at 7:50 PM, Dragan Djuric draga...@gmail.com wrote: I probably won't be able to resist to type check it with core.typed at some point. If you contribute that, or help me baking in (some) non-invasive type checking into Fluokitten, that would be FANTASTIC! I have that in vague long-term plans, but I haven't had time to look at core.typed (I only skimmed through the homepage when it was released). I'm very glad you're interested! Skimming your code, you use conj a lot (via into). I'm actually working on an accurate and extensible type for conj type right now. The code looks very pure and accommodating for type checking. And enough documentation to satisfy Michael Klishin? I'm impressed :) Thanks :) Actually, one of the main project goals is to make monads (et al) approachable for beginners, and for that, docs and tutorials are the main thing. So, this library really does not make much sense without lots of documentation. I hope to even improve it on that point. Thought: Whether type signatures help for beginners here is debatable. It probably makes some parts clearer, and some parts incomprehensible. Anyway, I'll be in touch, congratulations again :) Ambrose -- -- You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en --- You received this message because you are subscribed to the Google Groups Clojure group. To unsubscribe from this group and stop receiving emails from it, send an email to clojure+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/groups/opt_out.
Re: [ANN] Fluokitten - Category theory concepts in Clojure - Functors, Applicatives, Monads, Monoids and more
2013/7/3 Dragan Djuric draga...@gmail.com one of the main project goals is to make monads (et al) approachable for beginners, and for that, docs and tutorials are the main thing. So, this library really does not make much sense without lots of documentation. I hope to even improve it on that point. Dragan, That's a worthy goal. I tried to find the doc site source on github but couldn't. Is it open source? I think making it open source under a liberal license with a straightforward contribution policy is a good idea. Others will be able to help (as you know, everybody and their grandma in the FP community has an opinion on monads et al.) Thanks! -- MK http://github.com/michaelklishin http://twitter.com/michaelklishin -- -- You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en --- You received this message because you are subscribed to the Google Groups Clojure group. To unsubscribe from this group and stop receiving emails from it, send an email to clojure+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/groups/opt_out.
Re: [ANN] Fluokitten - Category theory concepts in Clojure - Functors, Applicatives, Monads, Monoids and more
Michael, The site source is in the gh-pages branch in the main source repository on github: https://github.com/uncomplicate/fluokitten/tree/gh-pages On Wednesday, July 3, 2013 2:19:07 PM UTC+2, Michael Klishin wrote: 2013/7/3 Dragan Djuric drag...@gmail.com javascript: one of the main project goals is to make monads (et al) approachable for beginners, and for that, docs and tutorials are the main thing. So, this library really does not make much sense without lots of documentation. I hope to even improve it on that point. Dragan, That's a worthy goal. I tried to find the doc site source on github but couldn't. Is it open source? I think making it open source under a liberal license with a straightforward contribution policy is a good idea. Others will be able to help (as you know, everybody and their grandma in the FP community has an opinion on monads et al.) Thanks! -- MK http://github.com/michaelklishin http://twitter.com/michaelklishin -- -- You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en --- You received this message because you are subscribed to the Google Groups Clojure group. To unsubscribe from this group and stop receiving emails from it, send an email to clojure+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/groups/opt_out.
Re: [ANN] Fluokitten - Category theory concepts in Clojure - Functors, Applicatives, Monads, Monoids and more
2013/7/3 Dragan Djuric draga...@gmail.com The site source is in the gh-pages branch in the main source repository on github: https://github.com/uncomplicate/fluokitten/tree/gh-pages It's worth mentioning somewhere. ClojureWerkz projects link to doc source at the top of every guide, adding a README link is fine, too. -- MK http://github.com/michaelklishin http://twitter.com/michaelklishin -- -- You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en --- You received this message because you are subscribed to the Google Groups Clojure group. To unsubscribe from this group and stop receiving emails from it, send an email to clojure+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/groups/opt_out.
Re: [ANN] Fluokitten - Category theory concepts in Clojure - Functors, Applicatives, Monads, Monoids and more
On Wed, Jul 3, 2013 at 12:32 AM, Dragan Djuric draga...@gmail.com wrote: On Wednesday, July 3, 2013 2:06:34 AM UTC+2, Ben wrote: On Tue, Jul 2, 2013 at 4:33 PM, Dragan Djuric drag...@gmail.com wrote: And in this case you have to explicitly specify which monad you want to use, every time you call bind. I understand that in some case it might be a preferred way, but in my opinion for most cases that I care about I prefer it the other way. No, you don't. You don't have to specify the monad you want to use until you actually want to use it: Unless you need to use two or more different monads in that function, in which case I don't see now would you do that at all. And, you have to structure the code a bit awkwardly for clojure, and have to say specifically, I want such and such monad type, and run it with a runner. I'm not saying that that is not good option. Clojure has its features and some compromise has to be made. I just prefer the sort of compromises I made for Fluokitten to the sorts of compromises made by other libraries. Well, my *very first* message demonstrated how to do that in a generic way. (defn tst-reader [f] (mdo env - ask v - (lift (f env)) (return (println here I am)) (return v))) You use more than one monad here in the same way you do it in Haskell: using a monad transformer, lifting from one to the other. Here you can do it without specifying *either* layer of the stack (as long as the first supports ask). You *never* have to say I want such and such monad type while you're writing the function, until you actually run it, and the same computation can be run with multiple different types (again, my first message demonstrated this, embedding arbitrary different effects including early exit and mutable state into that function without modifying it at all). As far as I can tell, with Fluokitten you *always* do. I suppose that may be right: you're supposed to verify that the laws obtain for a putative monad; they don't come for free just by calling something a monad. Allowing = to have the type m a - (a - n b) - n b just means that you can't verify that yours obeys the laws. If you get to choose the type of return, even the second one is up for grabs! It does seem somewhat odd to me to advertise the package as being familiar to Haskellers and to employ category-theoretic concepts and then to be so blasé about the definition of a monad. (I wonder if you can get away with this changing of type at all if you define bind in terms of fmap and join). Here is how the laws are specified (and tested) in Fluokitten (writing from the top of my head so please excuse me if I mess up something): (def return (pure [])) ;;This def is to make it more familiar for those who already read this tread, it is not actually in fluokitten tests. (def k (comp return foo bar baz)) ;; note the agnostic return. There are ways in Clojure to change what is it bound for, but I won't go into that here, It does not seem that important to me now. The point is, fluokitten supports it... That is not an agnostic return: it works only for vectors. You could change what it's bound for with, I suppose, with-redefs? (= (return a) k) = (k a) (= [1 2 3] return) = m (= [1 2 3] (fn [x] (bind (k x) h))) = (= m k h) So, if monad stays the same, everything is nice and tidy and close enough to Clojure and Haskell. Now, what would happen if monad changes after the bind? The first law does not constrain it The second does not too, since it says what happens when you bind with (pure m) not (pure n) The third, associativity, will also be satisfied Really? Let's find out! uncomplicate.fluokitten.core (def return (pure [])) #'uncomplicate.fluokitten.core/return uncomplicate.fluokitten.core (def k (comp return inc (partial * 2))) uncomplicate.fluokitten.core (= (= [1 2 3] k) (fn [x] (atom (inc x IllegalArgumentException Don't know how to create ISeq from: clojure.lang.Atom clojure.lang.RT.seqFrom (RT.java:505) uncomplicate.fluokitten.core (= [1 2 3] (fn [x] (= (k x) (fn [y] (atom (inc y)) IllegalArgumentException Don't know how to create ISeq from: clojure.lang.Atom clojure.lang.RT.seqFrom (RT.java:505) I guess you're right: they are the same. However, I think this, regarding the second law, is telling: The second does not too, since it says what happens when you bind with (pure m) not (pure n) *all* the laws only say what happen when you stay within the same monad, because the types the laws give to = and return *require* that. -- Ben Wolfson Human kind has used its intelligence to vary the flavour of drinks, which may be sweet, aromatic, fermented or spirit-based. ... Family and social life also offer numerous other occasions to consume drinks for pleasure. [Larousse, Drink entry] -- -- You received this message because you are subscribed to the Google Groups Clojure group. To post
Re: [ANN] Fluokitten - Category theory concepts in Clojure - Functors, Applicatives, Monads, Monoids and more
On Wed, Jul 3, 2013 at 7:07 AM, Ben Wolfson wolf...@gmail.com wrote: However, I think this, regarding the second law, is telling: The second does not too, since it says what happens when you bind with (pure m) not (pure n) *all* the laws only say what happen when you stay within the same monad, because the types the laws give to = and return *require* that. Addendum, if you're going to say that the various monad laws don't apply because the types differ, then you are, whether you like it or not, not talking about monads; monads are what the laws describe. -- Ben Wolfson Human kind has used its intelligence to vary the flavour of drinks, which may be sweet, aromatic, fermented or spirit-based. ... Family and social life also offer numerous other occasions to consume drinks for pleasure. [Larousse, Drink entry] -- -- You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en --- You received this message because you are subscribed to the Google Groups Clojure group. To unsubscribe from this group and stop receiving emails from it, send an email to clojure+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/groups/opt_out.
Re: [ANN] Fluokitten - Category theory concepts in Clojure - Functors, Applicatives, Monads, Monoids and more
Monads as a Haskell construct is what the previously mentioned laws describe. Monads in category theory are defined in a category X as a triple (T, n, m) where T is a functor and m and n certan natural transformations such that certan diagrams commute. In that sense, I am not sure that even Haskell's implementation is perfectly clean. There's a lot of nitpicking to be done, but, that's not the point, and we are digressing a bit. The point is that in Fluokitten, you are expected to work within the certain monad as you agree, and since there is no type checking on the value that a function returns, it is the responsibility of the developer to make sure that it makes sense as in Clojure generally. It is fairly easy to do by passing a parameter to f that pure can use, if f implementation needs to be agnostic to the actual monad that it will be called from. There are other approaches, so the programmer can make a choice that is the best fit for the problem at hand. Even in the example that you gave from your library, what stops the programmer to shoot himself in the foot by doing basically the same thing that we are talking about here: (defn f [g] (comp atom g g)) (require '[monads.maybe :as m]) (def mc (= (return 3) (f inc))) (run-monad m/m mc) What is the result if f is broken (in the context of the monad m/m in this case)? I didn't try it, so I may be wrong, but I doubt that the Clojure compiler complains about that one. On Wednesday, July 3, 2013 4:11:31 PM UTC+2, Ben wrote: On Wed, Jul 3, 2013 at 7:07 AM, Ben Wolfson wol...@gmail.comjavascript: wrote: However, I think this, regarding the second law, is telling: The second does not too, since it says what happens when you bind with (pure m) not (pure n) *all* the laws only say what happen when you stay within the same monad, because the types the laws give to = and return *require* that. Addendum, if you're going to say that the various monad laws don't apply because the types differ, then you are, whether you like it or not, not talking about monads; monads are what the laws describe. -- Ben Wolfson Human kind has used its intelligence to vary the flavour of drinks, which may be sweet, aromatic, fermented or spirit-based. ... Family and social life also offer numerous other occasions to consume drinks for pleasure. [Larousse, Drink entry] -- -- You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en --- You received this message because you are subscribed to the Google Groups Clojure group. To unsubscribe from this group and stop receiving emails from it, send an email to clojure+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/groups/opt_out.
Re: [ANN] Fluokitten - Category theory concepts in Clojure - Functors, Applicatives, Monads, Monoids and more
I've never really used monads or monoids, but one thing that does confuse me is how come there are so may libraries for supporting them. I've been reading the documentation of morph (https://github.com/blancas/morph) recently, which is the first one I've understood. A quick look at fluokitten suggests that the doc is good also! What I've not yet understood is what the difference is between all of these libraries? Phil Dragan Djuric draga...@gmail.com writes: I am pleased to announce a first public release of new (and different) monads and friends library for Clojure. Extensive *documentation* is at http://fluokitten.uncomplicate.org Fluokitten is a Clojure library that implements category theory concepts, such as functors, applicative functors, monads, monoids etc. in idiomatic Clojure. Main project goals are: - Fit well into idiomatic Clojure - Clojure programmers should be able to use and understand Fluokitten like any regular Clojure library. - Fit well into Haskell monadic types conventions - programmers should be able to reuse existing widespread monadic programming know-how and easily translate it to Clojure code. - Be reasonably easy to learn - the code from the existing books, articles and tutorials for learning monadic programming, which is usually written in Haskell should be easily translatable to Clojure with Fluokitten. - Offer good performance. Please give us your feedback, and we would also love if anyone is willing to help, regardless of previous experience, so please *get involved*. There are lots of things to be improved: - If you are a native English speaker, i would really appreciate if you can help with correcting the English on the Fluokitten site and in the documentation. - Contribute your example code (your own or the ports from Haskell tutorials) to be added to Fluokitten tests. - Contribute articles and tutorials. - Do code review of the Fluokitten code and suggest improvements. - If you find bugs, report them via Fluokitten issue tracker. - If you have any additional suggestion, contact us here: http://fluokitten.uncomplicate.org/articles/community.html -- -- Phillip Lord, Phone: +44 (0) 191 222 7827 Lecturer in Bioinformatics, Email: phillip.l...@newcastle.ac.uk School of Computing Science, http://homepages.cs.ncl.ac.uk/phillip.lord Room 914 Claremont Tower, skype: russet_apples Newcastle University, twitter: phillord NE1 7RU -- -- You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en --- You received this message because you are subscribed to the Google Groups Clojure group. To unsubscribe from this group and stop receiving emails from it, send an email to clojure+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/groups/opt_out.
Re: [ANN] Fluokitten - Category theory concepts in Clojure - Functors, Applicatives, Monads, Monoids and more
If Clojure has all of the Haskell's type features, I guess there would be only one Clojure monad library, more or less a direct port of Haskell's. As Clojure is different, there are different ways to approach monads from neither of which can be the same as Haskell's, each having its pros and cons, so there are many libraries. Additional motivation in my case is that the other libraries (except morph, which is also a newcomer) were poorly documented or not documented at all, and that even simple examples from Haskell literature were not simple at all in those libraries, and in many cases, not even supported (many of them don't even define functors and monoids, let alone applicative functors). What I've not yet understood is what the difference is between all of these libraries? -- -- You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en --- You received this message because you are subscribed to the Google Groups Clojure group. To unsubscribe from this group and stop receiving emails from it, send an email to clojure+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/groups/opt_out.
Re: [ANN] Fluokitten - Category theory concepts in Clojure - Functors, Applicatives, Monads, Monoids and more
Hi, Am Mittwoch, 3. Juli 2013 16:49:43 UTC+2 schrieb Dragan Djuric: Monads as a Haskell construct is what the previously mentioned laws describe. Monads in category theory are defined in a category X as a triple (T, n, m) where T is a functor and m and n certan natural transformations such that certan diagrams commute. In that sense, I am not sure that even Haskell's implementation is perfectly clean. in category theory, monads are functors with additional constraints. Haskell's implementation is clean to the extend that Hask, i.e Haskell types and morphisms between them, form a category (there are some issues with laziness). The connection to the categorical definition is most easily seen if you define monads using join instead of = (bind). You basically need a functor, i.e. a type constructor with a proper fmap (check the laws here as well), and two natural transformations mu, eta. As it turns out, polymorphic functions are natural transformations in Haskell's category, i.e. they always obey the required laws, no need to check them. Let's call your functor type t, then mu and eta have the following types: mu :: a - t a -- Haskell's return eta :: t (t a) - t a -- Haskell's join The required laws now state that: eta (eta mm) = eta (fmap eta mm) eta (mu m) = eta (fmap mu m)= identity which just says that if you have something of type t (t (t a)) it does not matter whether you flatten it from the inside or outside first and if you have something of type t a, you can put it into another t from the outside or inside and flatten it to get back the identity. Now, conceptually changing the monad does not make much sense. Remember that a monad is a functor with additional structure, so we are always working in the same functor! The laws just express that we have a special functor which obeys additional properties, besides the functorial ones. Also generalizing the types of (=) to support different monads is forbidden by the laws. Try to define myBind :: (Monad m, Monad n) = m a - (a - n b) - n b-- like (=), but changes the monad and now look at the second law: x = return = x or written with explicit types: ((x :: m a) = (return :: a - m a)) :: m a = x :: m a ((x :: m a) `myBind` (return :: a - n a)) :: n a but this cannot equal (x :: m a), since it does not even have the same type! Best, Nils -- -- You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en --- You received this message because you are subscribed to the Google Groups Clojure group. To unsubscribe from this group and stop receiving emails from it, send an email to clojure+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/groups/opt_out.
Re: [ANN] Fluokitten - Category theory concepts in Clojure - Functors, Applicatives, Monads, Monoids and more
Yes, I agree completely, when we stay inside Haskell. However, Clojure is dynamic. Here are two objects that are equal despite having different types: Consider this case: (= [1] (list 1)) ;= true (isa? (type [1]) (list 1)) ;= false In fact, equality in Java (and Clojure) depends on the implementation of equals and hashCode, so, as in the previous example, it is possible that two things are equal while having different type. I know, these are special cases, but a library that wants to be idiomatic has to support even those special cases that are common in a language. So, a bind that operates on a vector might return a list - different types, different monad, but still equal! I am not sure what would be the best solution, I'm just giving a counterexample that illustrates why these things in Clojure are not that straightforward as in Haskell. On Wednesday, July 3, 2013 6:20:08 PM UTC+2, Nils Bertschinger wrote: Hi, Am Mittwoch, 3. Juli 2013 16:49:43 UTC+2 schrieb Dragan Djuric: Monads as a Haskell construct is what the previously mentioned laws describe. Monads in category theory are defined in a category X as a triple (T, n, m) where T is a functor and m and n certan natural transformations such that certan diagrams commute. In that sense, I am not sure that even Haskell's implementation is perfectly clean. in category theory, monads are functors with additional constraints. Haskell's implementation is clean to the extend that Hask, i.e Haskell types and morphisms between them, form a category (there are some issues with laziness). The connection to the categorical definition is most easily seen if you define monads using join instead of = (bind). You basically need a functor, i.e. a type constructor with a proper fmap (check the laws here as well), and two natural transformations mu, eta. As it turns out, polymorphic functions are natural transformations in Haskell's category, i.e. they always obey the required laws, no need to check them. Let's call your functor type t, then mu and eta have the following types: mu :: a - t a -- Haskell's return eta :: t (t a) - t a -- Haskell's join The required laws now state that: eta (eta mm) = eta (fmap eta mm) eta (mu m) = eta (fmap mu m)= identity which just says that if you have something of type t (t (t a)) it does not matter whether you flatten it from the inside or outside first and if you have something of type t a, you can put it into another t from the outside or inside and flatten it to get back the identity. Now, conceptually changing the monad does not make much sense. Remember that a monad is a functor with additional structure, so we are always working in the same functor! The laws just express that we have a special functor which obeys additional properties, besides the functorial ones. Also generalizing the types of (=) to support different monads is forbidden by the laws. Try to define myBind :: (Monad m, Monad n) = m a - (a - n b) - n b-- like (=), but changes the monad and now look at the second law: x = return = x or written with explicit types: ((x :: m a) = (return :: a - m a)) :: m a = x :: m a ((x :: m a) `myBind` (return :: a - n a)) :: n a but this cannot equal (x :: m a), since it does not even have the same type! Best, Nils -- -- You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en --- You received this message because you are subscribed to the Google Groups Clojure group. To unsubscribe from this group and stop receiving emails from it, send an email to clojure+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/groups/opt_out.
Re: [ANN] Fluokitten - Category theory concepts in Clojure - Functors, Applicatives, Monads, Monoids and more
On Wed, Jul 3, 2013 at 10:31 AM, Dragan Djuric draga...@gmail.com wrote: Yes, I agree completely, when we stay inside Haskell. However, Clojure is dynamic. Here are two objects that are equal despite having different types: If you're going to talk about category theory concepts, then that's the constraint you have to operate under. monad is constituted by the laws, the laws involve operations with a certain type, and that's just it. It's not a matter of being in Haskell or not, it's a matter of accurately implementing the concepts you claim to be implementing. I would actually maintain that a call to bind whose first argument is a vector but which returns a list (because it's implemented with mapcat, say) is not changing the monad, because you're actually operating in the list monad (what algo.monads calls the sequence monad, I think) and while the implementation might choose different ways of mapping the function depending on the type of the first argument to bind, that's an implementation detail. -- Ben Wolfson Human kind has used its intelligence to vary the flavour of drinks, which may be sweet, aromatic, fermented or spirit-based. ... Family and social life also offer numerous other occasions to consume drinks for pleasure. [Larousse, Drink entry] -- -- You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en --- You received this message because you are subscribed to the Google Groups Clojure group. To unsubscribe from this group and stop receiving emails from it, send an email to clojure+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/groups/opt_out.
Re: [ANN] Fluokitten - Category theory concepts in Clojure - Functors, Applicatives, Monads, Monoids and more
If you're going to talk about category theory concepts, then that's the constraint you have to operate under. monad is constituted by the laws, the laws involve operations with a certain type, and that's just it. It's not a matter of being in Haskell or not, it's a matter of accurately implementing the concepts you claim to be implementing. I do not want to be a nitpick, but category theory does not define monads (and functors and everything else) through types, but through categories. Categories themselves are not defined through types, but through - objects - arrows - source and target assignments between arrows and objects - assignment id from objects to arrows - partial composition of arrows - restricting axioms of associativity and identity So, not only that types are not necessary for talking about monads, even functions are not necessary, let alone the laws that are defined strictly through types and/or functions (which I suppose is a special case). But, as I said, neither it is terribly important for now, neither I am prepared (or willing) to go that deep into CT, which, not being a matematician, I do not have a desire to dedicate my life to, so I would stay away from this digression from now on :) I agree that Haskell's way is the most advanced and formally right impementation available today, but I do not agree with your and that's just it. I gave an example (and there are more) where in Clojure it's not just it, and regarding the list monad, I do not agree with you. The vector, list, lazy-seq etc, contexts are not the same, although they are similar, and in a lot of cases in Clojure programming it is very important to be certain whether you are using a vector, a list or a lazy seq. Treating everything as a list monad is enough in some cases, and not enough in others, which are common. -- -- You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en --- You received this message because you are subscribed to the Google Groups Clojure group. To unsubscribe from this group and stop receiving emails from it, send an email to clojure+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/groups/opt_out.
Re: [ANN] Fluokitten - Category theory concepts in Clojure - Functors, Applicatives, Monads, Monoids and more
On Wed, Jul 3, 2013 at 7:49 AM, Dragan Djuric draga...@gmail.com wrote: Monads as a Haskell construct is what the previously mentioned laws describe. Monads in category theory are defined in a category X as a triple (T, n, m) where T is a functor and m and n certan natural transformations such that certan diagrams commute. In that sense, I am not sure that even Haskell's implementation is perfectly clean. There's a lot of nitpicking to be done, but, that's not the point, and we are digressing a bit. The point is that in Fluokitten, you are expected to work within the certain monad as you agree, and since there is no type checking on the value that a function returns, it is the responsibility of the developer to make sure that it makes sense as in Clojure generally. It is fairly easy to do by passing a parameter to f that pure can use, if f implementation needs to be agnostic to the actual monad that it will be called from. There are other approaches, so the programmer can make a choice that is the best fit for the problem at hand. Even in the example that you gave from your library, what stops the programmer to shoot himself in the foot by doing basically the same thing that we are talking about here: (defn f [g] (comp atom g g)) (require '[monads.maybe :as m]) (def mc (= (return 3) (f inc))) (run-monad m/m mc) What is the result if f is broken (in the context of the monad m/m in this case)? I didn't try it, so I may be wrong, but I doubt that the Clojure compiler complains about that one. Of course the compiler doesn't complain, how could it? I'm not asking you to have the clojure compiler complain. I'm attempting to point out that your library makes it impossible to write generic functions involving monads. That is, for fluokitten, you *have* to write f as something like (comp atom g g) or (comp vector g g) or (comp just g g) or whatever. You don't have the option of writing (comp return g g) and having that work right when the function is run in *multiple* monads. Which is a major expressivity drawback, in my mind. This is basically the same thing as comes up with Armando Blancas' morph library, which is, like yours, based on protocols. The expressivity point is the key, not the nonexistent haskell-in-clojure typechecker. That's why I asked the question I asked in my first email: whether it's possible to write this function (which I've desugared): (defn tst-reader [f] (= ask (fn [env] (= (lift (f env)) (fn [_] (= (return (println here I am)) (fn [_] (return v which can operate in an instance of the reader monad transformer parametrized by an *arbitrary* inner monad---so that you don't know in advance what the return or = should be (and you don't know in advance what the lift should be, since more than one interpretation of the reader monad is possible---all that's required here is that the monad support an ask operation). I suppose you could thread specimen special return, bind, ask, and lift functions through (and if you used fancy macrology to do that, you'd have the core.monads approach), but that's really quite cumbersome. IMO, the ability to write code like that is a large part of what makes monadic abstraction powerful and interesting. -- Ben Wolfson Human kind has used its intelligence to vary the flavour of drinks, which may be sweet, aromatic, fermented or spirit-based. ... Family and social life also offer numerous other occasions to consume drinks for pleasure. [Larousse, Drink entry] -- -- You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en --- You received this message because you are subscribed to the Google Groups Clojure group. To unsubscribe from this group and stop receiving emails from it, send an email to clojure+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/groups/opt_out.
[ANN] Fluokitten - Category theory concepts in Clojure - Functors, Applicatives, Monads, Monoids and more
I am pleased to announce a first public release of new (and different) monads and friends library for Clojure. Extensive *documentation* is at http://fluokitten.uncomplicate.org Fluokitten is a Clojure library that implements category theory concepts, such as functors, applicative functors, monads, monoids etc. in idiomatic Clojure. Main project goals are: - Fit well into idiomatic Clojure - Clojure programmers should be able to use and understand Fluokitten like any regular Clojure library. - Fit well into Haskell monadic types conventions - programmers should be able to reuse existing widespread monadic programming know-how and easily translate it to Clojure code. - Be reasonably easy to learn - the code from the existing books, articles and tutorials for learning monadic programming, which is usually written in Haskell should be easily translatable to Clojure with Fluokitten. - Offer good performance. Please give us your feedback, and we would also love if anyone is willing to help, regardless of previous experience, so please *get involved*. There are lots of things to be improved: - If you are a native English speaker, i would really appreciate if you can help with correcting the English on the Fluokitten site and in the documentation. - Contribute your example code (your own or the ports from Haskell tutorials) to be added to Fluokitten tests. - Contribute articles and tutorials. - Do code review of the Fluokitten code and suggest improvements. - If you find bugs, report them via Fluokitten issue tracker. - If you have any additional suggestion, contact us here: http://fluokitten.uncomplicate.org/articles/community.html -- -- You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en --- You received this message because you are subscribed to the Google Groups Clojure group. To unsubscribe from this group and stop receiving emails from it, send an email to clojure+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/groups/opt_out.
Re: [ANN] Fluokitten - Category theory concepts in Clojure - Functors, Applicatives, Monads, Monoids and more
2013/7/2 Dragan Djuric draga...@gmail.com I am pleased to announce a first public release of new (and different) monads and friends library for Clojure. Extensive *documentation* is at http://fluokitten.uncomplicate.org Good job, Dragan! -- MK http://github.com/michaelklishin http://twitter.com/michaelklishin -- -- You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en --- You received this message because you are subscribed to the Google Groups Clojure group. To unsubscribe from this group and stop receiving emails from it, send an email to clojure+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/groups/opt_out.
Re: [ANN] Fluokitten - Category theory concepts in Clojure - Functors, Applicatives, Monads, Monoids and more
I haven't played around with this but it looks as if the second argument to bind needs to know what kind of monad it's operating in, is that right? Would it be possible to write agnostic functions like this in this lib? monads.core (defn tst-reader [f] (mdo env - ask v - (lift (f env)) (return (println here I am)) (return v))) #'monads.core/tst-reader monads.core (require '[monads.reader :as r] '[monads.identity :as i] '[monads.state :as st] '[monads.error :as e]) nil monads.core (r/run-reader-t (r/t i/m) (tst-reader (comp return inc)) 5) here I am 6 monads.core (r/run-reader-t (r/t e/m) (tst-reader (fn [_] (throw-error early exit))) 5) #Either [:left early exit] monads.core (st/run-state (r/run-reader-t (r/t st/m) (tst-reader (fn [env] ( (modify #(assoc % :env env)) (return (dec env) 5) {}) here I am #Pair [4 {:env 5}] monads.core ? On Tue, Jul 2, 2013 at 11:07 AM, Dragan Djuric draga...@gmail.com wrote: I am pleased to announce a first public release of new (and different) monads and friends library for Clojure. Extensive *documentation* is at http://fluokitten.uncomplicate.org Fluokitten is a Clojure library that implements category theory concepts, such as functors, applicative functors, monads, monoids etc. in idiomatic Clojure. Main project goals are: - Fit well into idiomatic Clojure - Clojure programmers should be able to use and understand Fluokitten like any regular Clojure library. - Fit well into Haskell monadic types conventions - programmers should be able to reuse existing widespread monadic programming know-how and easily translate it to Clojure code. - Be reasonably easy to learn - the code from the existing books, articles and tutorials for learning monadic programming, which is usually written in Haskell should be easily translatable to Clojure with Fluokitten. - Offer good performance. Please give us your feedback, and we would also love if anyone is willing to help, regardless of previous experience, so please *get involved*. There are lots of things to be improved: - If you are a native English speaker, i would really appreciate if you can help with correcting the English on the Fluokitten site and in the documentation. - Contribute your example code (your own or the ports from Haskell tutorials) to be added to Fluokitten tests. - Contribute articles and tutorials. - Do code review of the Fluokitten code and suggest improvements. - If you find bugs, report them via Fluokitten issue tracker. - If you have any additional suggestion, contact us here: http://fluokitten.uncomplicate.org/articles/community.html -- -- You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en --- You received this message because you are subscribed to the Google Groups Clojure group. To unsubscribe from this group and stop receiving emails from it, send an email to clojure+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/groups/opt_out. -- Ben Wolfson Human kind has used its intelligence to vary the flavour of drinks, which may be sweet, aromatic, fermented or spirit-based. ... Family and social life also offer numerous other occasions to consume drinks for pleasure. [Larousse, Drink entry] -- -- You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en --- You received this message because you are subscribed to the Google Groups Clojure group. To unsubscribe from this group and stop receiving emails from it, send an email to clojure+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/groups/opt_out.
Re: [ANN] Fluokitten - Category theory concepts in Clojure - Functors, Applicatives, Monads, Monoids and more
No, the second argument to bind only needs to be a function that takes a plain value and return a monadic value; you do not need to specify anything explicitly and it does not need to know what kind of monad it is operating on. Whatever that function returns will be a monad that the eventual second bind will operate on. Moreover, Fluokitten supports vararg bind, so the function is actually the last argument of bind in general case; it is the second argument only if there are two args. Please note that Fluokitten does not have a built-in mdo (a syntactic sugar for nested binds) for now. The reason is that Clojure itself has native constructs that do many stuff that Haskell's do does, so I am not yet sure why and if it would be useful, and if I add it how to make it non-awkward. Of course, I am open to suggestions. Also note that Fluokitten is not monad-centric, it has functors, applicatives, etc and I plan to add more categorical concepts, so It is different in that regard from other monadic Clojure libraries. That's why I would like to suggest reading the docs, most of the stuff is significantly different from other libs, and more similar (but simpler, due to the lack of legacy) to Haskell's categorical stuff. On Tuesday, July 2, 2013 9:15:10 PM UTC+2, Ben wrote: I haven't played around with this but it looks as if the second argument to bind needs to know what kind of monad it's operating in, is that right? Would it be possible to write agnostic functions like this in this lib? monads.core (defn tst-reader [f] (mdo env - ask v - (lift (f env)) (return (println here I am)) (return v))) #'monads.core/tst-reader monads.core (require '[monads.reader :as r] '[monads.identity :as i] '[monads.state :as st] '[monads.error :as e]) nil monads.core (r/run-reader-t (r/t i/m) (tst-reader (comp return inc)) 5) here I am 6 monads.core (r/run-reader-t (r/t e/m) (tst-reader (fn [_] (throw-error early exit))) 5) #Either [:left early exit] monads.core (st/run-state (r/run-reader-t (r/t st/m) (tst-reader (fn [env] ( (modify #(assoc % :env env)) (return (dec env) 5) {}) here I am #Pair [4 {:env 5}] monads.core ? On Tue, Jul 2, 2013 at 11:07 AM, Dragan Djuric drag...@gmail.comjavascript: wrote: I am pleased to announce a first public release of new (and different) monads and friends library for Clojure. Extensive *documentation* is at http://fluokitten.uncomplicate.org Fluokitten is a Clojure library that implements category theory concepts, such as functors, applicative functors, monads, monoids etc. in idiomatic Clojure. Main project goals are: - Fit well into idiomatic Clojure - Clojure programmers should be able to use and understand Fluokitten like any regular Clojure library. - Fit well into Haskell monadic types conventions - programmers should be able to reuse existing widespread monadic programming know-how and easily translate it to Clojure code. - Be reasonably easy to learn - the code from the existing books, articles and tutorials for learning monadic programming, which is usually written in Haskell should be easily translatable to Clojure with Fluokitten. - Offer good performance. Please give us your feedback, and we would also love if anyone is willing to help, regardless of previous experience, so please *get involved*. There are lots of things to be improved: - If you are a native English speaker, i would really appreciate if you can help with correcting the English on the Fluokitten site and in the documentation. - Contribute your example code (your own or the ports from Haskell tutorials) to be added to Fluokitten tests. - Contribute articles and tutorials. - Do code review of the Fluokitten code and suggest improvements. - If you find bugs, report them via Fluokitten issue tracker. - If you have any additional suggestion, contact us here: http://fluokitten.uncomplicate.org/articles/community.html -- -- You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clo...@googlegroups.comjavascript: Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+u...@googlegroups.com javascript: For more options, visit this group at http://groups.google.com/group/clojure?hl=en --- You received this message because you are subscribed to the Google Groups Clojure group. To unsubscribe from this group and stop receiving emails from it, send an email to clojure+u...@googlegroups.com javascript:. For more options, visit https://groups.google.com/groups/opt_out. -- Ben Wolfson Human kind has used its intelligence to vary the flavour of drinks, which may be sweet, aromatic, fermented or spirit
Re: [ANN] Fluokitten - Category theory concepts in Clojure - Functors, Applicatives, Monads, Monoids and more
I did look at the docs and I don't really get how to return a monadic value in the right monad, the way return does automatically. All the examples I saw have something like vector or atom or what-have-you. On Tue, Jul 2, 2013 at 2:41 PM, Dragan Djuric draga...@gmail.com wrote: No, the second argument to bind only needs to be a function that takes a plain value and return a monadic value; you do not need to specify anything explicitly and it does not need to know what kind of monad it is operating on. Whatever that function returns will be a monad that the eventual second bind will operate on. Moreover, Fluokitten supports vararg bind, so the function is actually the last argument of bind in general case; it is the second argument only if there are two args. Please note that Fluokitten does not have a built-in mdo (a syntactic sugar for nested binds) for now. The reason is that Clojure itself has native constructs that do many stuff that Haskell's do does, so I am not yet sure why and if it would be useful, and if I add it how to make it non-awkward. Of course, I am open to suggestions. Also note that Fluokitten is not monad-centric, it has functors, applicatives, etc and I plan to add more categorical concepts, so It is different in that regard from other monadic Clojure libraries. That's why I would like to suggest reading the docs, most of the stuff is significantly different from other libs, and more similar (but simpler, due to the lack of legacy) to Haskell's categorical stuff. On Tuesday, July 2, 2013 9:15:10 PM UTC+2, Ben wrote: I haven't played around with this but it looks as if the second argument to bind needs to know what kind of monad it's operating in, is that right? Would it be possible to write agnostic functions like this in this lib? monads.core (defn tst-reader [f] (mdo env - ask v - (lift (f env)) (return (println here I am)) (return v))) #'monads.core/tst-reader monads.core (require '[monads.reader :as r] '[monads.identity :as i] '[monads.state :as st] '[monads.error :as e]) nil monads.core (r/run-reader-t (r/t i/m) (tst-reader (comp return inc)) 5) here I am 6 monads.core (r/run-reader-t (r/t e/m) (tst-reader (fn [_] (throw-error early exit))) 5) #Either [:left early exit] monads.core (st/run-state (r/run-reader-t (r/t st/m) (tst-reader (fn [env] ( (modify #(assoc % :env env)) (return (dec env) 5) {}) here I am #Pair [4 {:env 5}] monads.core ? On Tue, Jul 2, 2013 at 11:07 AM, Dragan Djuric drag...@gmail.com wrote: I am pleased to announce a first public release of new (and different) monads and friends library for Clojure. Extensive *documentation* is at http://fluokitten.**uncomplicate.orghttp://fluokitten.uncomplicate.org Fluokitten is a Clojure library that implements category theory concepts, such as functors, applicative functors, monads, monoids etc. in idiomatic Clojure. Main project goals are: - Fit well into idiomatic Clojure - Clojure programmers should be able to use and understand Fluokitten like any regular Clojure library. - Fit well into Haskell monadic types conventions - programmers should be able to reuse existing widespread monadic programming know-how and easily translate it to Clojure code. - Be reasonably easy to learn - the code from the existing books, articles and tutorials for learning monadic programming, which is usually written in Haskell should be easily translatable to Clojure with Fluokitten. - Offer good performance. Please give us your feedback, and we would also love if anyone is willing to help, regardless of previous experience, so please *get involved*. There are lots of things to be improved: - If you are a native English speaker, i would really appreciate if you can help with correcting the English on the Fluokitten site and in the documentation. - Contribute your example code (your own or the ports from Haskell tutorials) to be added to Fluokitten tests. - Contribute articles and tutorials. - Do code review of the Fluokitten code and suggest improvements. - If you find bugs, report them via Fluokitten issue tracker. - If you have any additional suggestion, contact us here: http://fluokitten.**uncomplicate.org/articles/**community.htmlhttp://fluokitten.uncomplicate.org/articles/community.html -- -- You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clo...@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+u...@**googlegroups.com For more options, visit this group at http://groups.google.com/**group/clojure?hl=enhttp://groups.google.com/group/clojure?hl=en --- You received this message because you are subscribed
Re: [ANN] Fluokitten - Category theory concepts in Clojure - Functors, Applicatives, Monads, Monoids and more
e.g., I'm not sure how to define the function f here: $ ghci GHCi, version 7.4.1: http://www.haskell.org/ghc/ :? for help Loading package ghc-prim ... linking ... done. Loading package integer-gmp ... linking ... done. Loading package base ... linking ... done. Prelude let f :: (Monad m) = (a - a) - a - m a ; f g = return . g . g Prelude Just 4 = f (2+) Just 8 Prelude [[1]] = f (2:) [[2,2,1]] Prelude import Control.Monad.State Prelude Control.Monad.State runState (get = f (+4)) 4 Loading package transformers-0.2.2.0 ... linking ... done. Loading package mtl-2.0.1.0 ... linking ... done. (12,4) Prelude Control.Monad.State On Tue, Jul 2, 2013 at 2:45 PM, Ben Wolfson wolf...@gmail.com wrote: I did look at the docs and I don't really get how to return a monadic value in the right monad, the way return does automatically. All the examples I saw have something like vector or atom or what-have-you. On Tue, Jul 2, 2013 at 2:41 PM, Dragan Djuric draga...@gmail.com wrote: No, the second argument to bind only needs to be a function that takes a plain value and return a monadic value; you do not need to specify anything explicitly and it does not need to know what kind of monad it is operating on. Whatever that function returns will be a monad that the eventual second bind will operate on. Moreover, Fluokitten supports vararg bind, so the function is actually the last argument of bind in general case; it is the second argument only if there are two args. Please note that Fluokitten does not have a built-in mdo (a syntactic sugar for nested binds) for now. The reason is that Clojure itself has native constructs that do many stuff that Haskell's do does, so I am not yet sure why and if it would be useful, and if I add it how to make it non-awkward. Of course, I am open to suggestions. Also note that Fluokitten is not monad-centric, it has functors, applicatives, etc and I plan to add more categorical concepts, so It is different in that regard from other monadic Clojure libraries. That's why I would like to suggest reading the docs, most of the stuff is significantly different from other libs, and more similar (but simpler, due to the lack of legacy) to Haskell's categorical stuff. On Tuesday, July 2, 2013 9:15:10 PM UTC+2, Ben wrote: I haven't played around with this but it looks as if the second argument to bind needs to know what kind of monad it's operating in, is that right? Would it be possible to write agnostic functions like this in this lib? monads.core (defn tst-reader [f] (mdo env - ask v - (lift (f env)) (return (println here I am)) (return v))) #'monads.core/tst-reader monads.core (require '[monads.reader :as r] '[monads.identity :as i] '[monads.state :as st] '[monads.error :as e]) nil monads.core (r/run-reader-t (r/t i/m) (tst-reader (comp return inc)) 5) here I am 6 monads.core (r/run-reader-t (r/t e/m) (tst-reader (fn [_] (throw-error early exit))) 5) #Either [:left early exit] monads.core (st/run-state (r/run-reader-t (r/t st/m) (tst-reader (fn [env] ( (modify #(assoc % :env env)) (return (dec env) 5) {}) here I am #Pair [4 {:env 5}] monads.core ? On Tue, Jul 2, 2013 at 11:07 AM, Dragan Djuric drag...@gmail.comwrote: I am pleased to announce a first public release of new (and different) monads and friends library for Clojure. Extensive *documentation* is at http://fluokitten.**uncomplicate.orghttp://fluokitten.uncomplicate.org Fluokitten is a Clojure library that implements category theory concepts, such as functors, applicative functors, monads, monoids etc. in idiomatic Clojure. Main project goals are: - Fit well into idiomatic Clojure - Clojure programmers should be able to use and understand Fluokitten like any regular Clojure library. - Fit well into Haskell monadic types conventions - programmers should be able to reuse existing widespread monadic programming know-how and easily translate it to Clojure code. - Be reasonably easy to learn - the code from the existing books, articles and tutorials for learning monadic programming, which is usually written in Haskell should be easily translatable to Clojure with Fluokitten. - Offer good performance. Please give us your feedback, and we would also love if anyone is willing to help, regardless of previous experience, so please *get involved*. There are lots of things to be improved: - If you are a native English speaker, i would really appreciate if you can help with correcting the English on the Fluokitten site and in the documentation. - Contribute your example code (your own or the ports from Haskell tutorials) to be added to Fluokitten tests. - Contribute articles and tutorials. - Do code review of the Fluokitten code and suggest improvements. - If you find bugs, report them via Fluokitten issue tracker
Re: [ANN] Fluokitten - Category theory concepts in Clojure - Functors, Applicatives, Monads, Monoids and more
pure function, defined in applicative, is equivalent to return (In Haskell, in Fluokitten there is only pure). I think I understand what is your question now. Since Clojure does not support polymorphysm based on the returning argument you cannot translate that Haskell code exactly. For such a case (when you want to keep operating in the same monad without knowing which one it is), a you have to provide an argument for m in f (but that's how Clojure works :), and then apply it partially or curry it: (defn f [m g] (comp (pure m) g g)) (def c+ (curry +)) (bind [1 2 3] (f [] (c+ 2)) or (= [1 2 3] (f [] (c+ 2)) If [] really hurts your aesthetic views maybe a macro (bind* or mdo) would help, since instead of [], any vector, let's say [1 2 3] would do, but then, it's a special case when you actually want the monad to stay the same. Thank you for helpful comments, BTW :) On Wednesday, July 3, 2013 12:03:45 AM UTC+2, Ben wrote: e.g., I'm not sure how to define the function f here: $ ghci GHCi, version 7.4.1: http://www.haskell.org/ghc/ :? for help Loading package ghc-prim ... linking ... done. Loading package integer-gmp ... linking ... done. Loading package base ... linking ... done. Prelude let f :: (Monad m) = (a - a) - a - m a ; f g = return . g . g Prelude Just 4 = f (2+) Just 8 Prelude [[1]] = f (2:) [[2,2,1]] Prelude import Control.Monad.State Prelude Control.Monad.State runState (get = f (+4)) 4 Loading package transformers-0.2.2.0 ... linking ... done. Loading package mtl-2.0.1.0 ... linking ... done. (12,4) Prelude Control.Monad.State On Tue, Jul 2, 2013 at 2:45 PM, Ben Wolfson wol...@gmail.comjavascript: wrote: I did look at the docs and I don't really get how to return a monadic value in the right monad, the way return does automatically. All the examples I saw have something like vector or atom or what-have-you. On Tue, Jul 2, 2013 at 2:41 PM, Dragan Djuric drag...@gmail.comjavascript: wrote: No, the second argument to bind only needs to be a function that takes a plain value and return a monadic value; you do not need to specify anything explicitly and it does not need to know what kind of monad it is operating on. Whatever that function returns will be a monad that the eventual second bind will operate on. Moreover, Fluokitten supports vararg bind, so the function is actually the last argument of bind in general case; it is the second argument only if there are two args. Please note that Fluokitten does not have a built-in mdo (a syntactic sugar for nested binds) for now. The reason is that Clojure itself has native constructs that do many stuff that Haskell's do does, so I am not yet sure why and if it would be useful, and if I add it how to make it non-awkward. Of course, I am open to suggestions. Also note that Fluokitten is not monad-centric, it has functors, applicatives, etc and I plan to add more categorical concepts, so It is different in that regard from other monadic Clojure libraries. That's why I would like to suggest reading the docs, most of the stuff is significantly different from other libs, and more similar (but simpler, due to the lack of legacy) to Haskell's categorical stuff. On Tuesday, July 2, 2013 9:15:10 PM UTC+2, Ben wrote: I haven't played around with this but it looks as if the second argument to bind needs to know what kind of monad it's operating in, is that right? Would it be possible to write agnostic functions like this in this lib? monads.core (defn tst-reader [f] (mdo env - ask v - (lift (f env)) (return (println here I am)) (return v))) #'monads.core/tst-reader monads.core (require '[monads.reader :as r] '[monads.identity :as i] '[monads.state :as st] '[monads.error :as e]) nil monads.core (r/run-reader-t (r/t i/m) (tst-reader (comp return inc)) 5) here I am 6 monads.core (r/run-reader-t (r/t e/m) (tst-reader (fn [_] (throw-error early exit))) 5) #Either [:left early exit] monads.core (st/run-state (r/run-reader-t (r/t st/m) (tst-reader (fn [env] ( (modify #(assoc % :env env)) (return (dec env) 5) {}) here I am #Pair [4 {:env 5}] monads.core ? On Tue, Jul 2, 2013 at 11:07 AM, Dragan Djuric drag...@gmail.comwrote: I am pleased to announce a first public release of new (and different) monads and friends library for Clojure. Extensive *documentation* is at http://fluokitten.**uncomplicate.orghttp://fluokitten.uncomplicate.org Fluokitten is a Clojure library that implements category theory concepts, such as functors, applicative functors, monads, monoids etc. in idiomatic Clojure. Main project goals are: - Fit well into idiomatic Clojure - Clojure programmers should be able to use and understand Fluokitten like any regular Clojure library. - Fit well into Haskell monadic types conventions - programmers should be able to reuse
Re: [ANN] Fluokitten - Category theory concepts in Clojure - Functors, Applicatives, Monads, Monoids and more
I wanted to say THE pure function. Now I realize that pure function is ambiguous :) On Wednesday, July 3, 2013 1:03:26 AM UTC+2, Dragan Djuric wrote: pure function, defined in applicative, is equivalent to return (In Haskell, in Fluokitten there is only pure). I think I understand what is your question now. Since Clojure does not support polymorphysm based on the returning argument you cannot translate that Haskell code exactly. For such a case (when you want to keep operating in the same monad without knowing which one it is), a you have to provide an argument for m in f (but that's how Clojure works :), and then apply it partially or curry it: (defn f [m g] (comp (pure m) g g)) (def c+ (curry +)) (bind [1 2 3] (f [] (c+ 2)) or (= [1 2 3] (f [] (c+ 2)) If [] really hurts your aesthetic views maybe a macro (bind* or mdo) would help, since instead of [], any vector, let's say [1 2 3] would do, but then, it's a special case when you actually want the monad to stay the same. Thank you for helpful comments, BTW :) On Wednesday, July 3, 2013 12:03:45 AM UTC+2, Ben wrote: e.g., I'm not sure how to define the function f here: $ ghci GHCi, version 7.4.1: http://www.haskell.org/ghc/ :? for help Loading package ghc-prim ... linking ... done. Loading package integer-gmp ... linking ... done. Loading package base ... linking ... done. Prelude let f :: (Monad m) = (a - a) - a - m a ; f g = return . g . g Prelude Just 4 = f (2+) Just 8 Prelude [[1]] = f (2:) [[2,2,1]] Prelude import Control.Monad.State Prelude Control.Monad.State runState (get = f (+4)) 4 Loading package transformers-0.2.2.0 ... linking ... done. Loading package mtl-2.0.1.0 ... linking ... done. (12,4) Prelude Control.Monad.State On Tue, Jul 2, 2013 at 2:45 PM, Ben Wolfson wol...@gmail.com wrote: I did look at the docs and I don't really get how to return a monadic value in the right monad, the way return does automatically. All the examples I saw have something like vector or atom or what-have-you. On Tue, Jul 2, 2013 at 2:41 PM, Dragan Djuric drag...@gmail.com wrote: No, the second argument to bind only needs to be a function that takes a plain value and return a monadic value; you do not need to specify anything explicitly and it does not need to know what kind of monad it is operating on. Whatever that function returns will be a monad that the eventual second bind will operate on. Moreover, Fluokitten supports vararg bind, so the function is actually the last argument of bind in general case; it is the second argument only if there are two args. Please note that Fluokitten does not have a built-in mdo (a syntactic sugar for nested binds) for now. The reason is that Clojure itself has native constructs that do many stuff that Haskell's do does, so I am not yet sure why and if it would be useful, and if I add it how to make it non-awkward. Of course, I am open to suggestions. Also note that Fluokitten is not monad-centric, it has functors, applicatives, etc and I plan to add more categorical concepts, so It is different in that regard from other monadic Clojure libraries. That's why I would like to suggest reading the docs, most of the stuff is significantly different from other libs, and more similar (but simpler, due to the lack of legacy) to Haskell's categorical stuff. On Tuesday, July 2, 2013 9:15:10 PM UTC+2, Ben wrote: I haven't played around with this but it looks as if the second argument to bind needs to know what kind of monad it's operating in, is that right? Would it be possible to write agnostic functions like this in this lib? monads.core (defn tst-reader [f] (mdo env - ask v - (lift (f env)) (return (println here I am)) (return v))) #'monads.core/tst-reader monads.core (require '[monads.reader :as r] '[monads.identity :as i] '[monads.state :as st] '[monads.error :as e]) nil monads.core (r/run-reader-t (r/t i/m) (tst-reader (comp return inc)) 5) here I am 6 monads.core (r/run-reader-t (r/t e/m) (tst-reader (fn [_] (throw-error early exit))) 5) #Either [:left early exit] monads.core (st/run-state (r/run-reader-t (r/t st/m) (tst-reader (fn [env] ( (modify #(assoc % :env env)) (return (dec env) 5) {}) here I am #Pair [4 {:env 5}] monads.core ? On Tue, Jul 2, 2013 at 11:07 AM, Dragan Djuric drag...@gmail.comwrote: I am pleased to announce a first public release of new (and different) monads and friends library for Clojure. Extensive *documentation* is at http://fluokitten.**uncomplicate.orghttp://fluokitten.uncomplicate.org Fluokitten is a Clojure library that implements category theory concepts, such as functors, applicative functors, monads, monoids etc. in idiomatic Clojure. Main project goals are: - Fit well into idiomatic Clojure - Clojure programmers should be able to use
Re: [ANN] Fluokitten - Category theory concepts in Clojure - Functors, Applicatives, Monads, Monoids and more
IMO you *always* want the monad to stay the same---the laws describing monadic computations don't account for swapping the things out midstream, at any rate. And it pays to be able to define monadic computations without having to explicitly pass around a token to serve as the current monad. FWIW, you *can* directly translate that function into clojure: monads.core (defn f [g] (comp return g g)) #'monads.core/f monads.core (require '[monads.state :as st]) nil monads.core (st/run-state (= get-state (f inc)) 5) #Pair [7 5] monads.core (require '[monads.list :as l]) nil monads.core (require '[monads.maybe :as m]) nil monads.core (def mc (= (return 3) (f inc))) #'monads.core/mc monads.core (run-monad m/m mc) #Just 5 monads.core (run-monad l/m mc) (5) monads.core (st/run-state mc {}) #Pair [5 {}] You just have to take a different approach to how the results are executed. (This is with this lib: https://github.com/bwo/monads) On Tue, Jul 2, 2013 at 4:03 PM, Dragan Djuric draga...@gmail.com wrote: pure function, defined in applicative, is equivalent to return (In Haskell, in Fluokitten there is only pure). I think I understand what is your question now. Since Clojure does not support polymorphysm based on the returning argument you cannot translate that Haskell code exactly. For such a case (when you want to keep operating in the same monad without knowing which one it is), a you have to provide an argument for m in f (but that's how Clojure works :), and then apply it partially or curry it: (defn f [m g] (comp (pure m) g g)) (def c+ (curry +)) (bind [1 2 3] (f [] (c+ 2)) or (= [1 2 3] (f [] (c+ 2)) If [] really hurts your aesthetic views maybe a macro (bind* or mdo) would help, since instead of [], any vector, let's say [1 2 3] would do, but then, it's a special case when you actually want the monad to stay the same. Thank you for helpful comments, BTW :) On Wednesday, July 3, 2013 12:03:45 AM UTC+2, Ben wrote: e.g., I'm not sure how to define the function f here: $ ghci GHCi, version 7.4.1: http://www.haskell.org/ghc/ :? for help Loading package ghc-prim ... linking ... done. Loading package integer-gmp ... linking ... done. Loading package base ... linking ... done. Prelude let f :: (Monad m) = (a - a) - a - m a ; f g = return . g . g Prelude Just 4 = f (2+) Just 8 Prelude [[1]] = f (2:) [[2,2,1]] Prelude import Control.Monad.State Prelude Control.Monad.State runState (get = f (+4)) 4 Loading package transformers-0.2.2.0 ... linking ... done. Loading package mtl-2.0.1.0 ... linking ... done. (12,4) Prelude Control.Monad.State On Tue, Jul 2, 2013 at 2:45 PM, Ben Wolfson wol...@gmail.com wrote: I did look at the docs and I don't really get how to return a monadic value in the right monad, the way return does automatically. All the examples I saw have something like vector or atom or what-have-you. On Tue, Jul 2, 2013 at 2:41 PM, Dragan Djuric drag...@gmail.com wrote: No, the second argument to bind only needs to be a function that takes a plain value and return a monadic value; you do not need to specify anything explicitly and it does not need to know what kind of monad it is operating on. Whatever that function returns will be a monad that the eventual second bind will operate on. Moreover, Fluokitten supports vararg bind, so the function is actually the last argument of bind in general case; it is the second argument only if there are two args. Please note that Fluokitten does not have a built-in mdo (a syntactic sugar for nested binds) for now. The reason is that Clojure itself has native constructs that do many stuff that Haskell's do does, so I am not yet sure why and if it would be useful, and if I add it how to make it non-awkward. Of course, I am open to suggestions. Also note that Fluokitten is not monad-centric, it has functors, applicatives, etc and I plan to add more categorical concepts, so It is different in that regard from other monadic Clojure libraries. That's why I would like to suggest reading the docs, most of the stuff is significantly different from other libs, and more similar (but simpler, due to the lack of legacy) to Haskell's categorical stuff. On Tuesday, July 2, 2013 9:15:10 PM UTC+2, Ben wrote: I haven't played around with this but it looks as if the second argument to bind needs to know what kind of monad it's operating in, is that right? Would it be possible to write agnostic functions like this in this lib? monads.core (defn tst-reader [f] (mdo env - ask v - (lift (f env)) (return (println here I am)) (return v))) #'monads.core/tst-reader monads.core (require '[monads.reader :as r] '[monads.identity :as i] '[monads.state :as st] '[monads.error :as e]) nil monads.core (r/run-reader-t (r/t i/m) (tst-reader (comp return inc)) 5) here I am 6 monads.core (r/run-reader-t (r/t e/m) (tst-reader (fn
Re: [ANN] Fluokitten - Category theory concepts in Clojure - Functors, Applicatives, Monads, Monoids and more
And in this case you have to explicitly specify which monad you want to use, every time you call bind. I understand that in some case it might be a preferred way, but in my opinion for most cases that I care about I prefer it the other way. Regarding monadic laws, which one exactly demands that you cannot change the monad (not counting the fact that haskell's implementation does it that way)? Here are the laws, in Haskell: return a = k = k a m = return= m m = (\x - k x = h) = (m = k) = h It seems to me the laws are still satisfied if you keep changing monads in each bind (if compiler is not restricting it, as is the case with Haskell but not with Clojure). On Wednesday, July 3, 2013 1:19:10 AM UTC+2, Ben wrote: IMO you *always* want the monad to stay the same---the laws describing monadic computations don't account for swapping the things out midstream, at any rate. And it pays to be able to define monadic computations without having to explicitly pass around a token to serve as the current monad. FWIW, you *can* directly translate that function into clojure: monads.core (defn f [g] (comp return g g)) #'monads.core/f monads.core (require '[monads.state :as st]) nil monads.core (st/run-state (= get-state (f inc)) 5) #Pair [7 5] monads.core (require '[monads.list :as l]) nil monads.core (require '[monads.maybe :as m]) nil monads.core (def mc (= (return 3) (f inc))) #'monads.core/mc monads.core (run-monad m/m mc) #Just 5 monads.core (run-monad l/m mc) (5) monads.core (st/run-state mc {}) #Pair [5 {}] You just have to take a different approach to how the results are executed. (This is with this lib: https://github.com/bwo/monads) On Tue, Jul 2, 2013 at 4:03 PM, Dragan Djuric drag...@gmail.comjavascript: wrote: pure function, defined in applicative, is equivalent to return (In Haskell, in Fluokitten there is only pure). I think I understand what is your question now. Since Clojure does not support polymorphysm based on the returning argument you cannot translate that Haskell code exactly. For such a case (when you want to keep operating in the same monad without knowing which one it is), a you have to provide an argument for m in f (but that's how Clojure works :), and then apply it partially or curry it: (defn f [m g] (comp (pure m) g g)) (def c+ (curry +)) (bind [1 2 3] (f [] (c+ 2)) or (= [1 2 3] (f [] (c+ 2)) If [] really hurts your aesthetic views maybe a macro (bind* or mdo) would help, since instead of [], any vector, let's say [1 2 3] would do, but then, it's a special case when you actually want the monad to stay the same. Thank you for helpful comments, BTW :) On Wednesday, July 3, 2013 12:03:45 AM UTC+2, Ben wrote: e.g., I'm not sure how to define the function f here: $ ghci GHCi, version 7.4.1: http://www.haskell.org/ghc/ :? for help Loading package ghc-prim ... linking ... done. Loading package integer-gmp ... linking ... done. Loading package base ... linking ... done. Prelude let f :: (Monad m) = (a - a) - a - m a ; f g = return . g . g Prelude Just 4 = f (2+) Just 8 Prelude [[1]] = f (2:) [[2,2,1]] Prelude import Control.Monad.State Prelude Control.Monad.State runState (get = f (+4)) 4 Loading package transformers-0.2.2.0 ... linking ... done. Loading package mtl-2.0.1.0 ... linking ... done. (12,4) Prelude Control.Monad.State On Tue, Jul 2, 2013 at 2:45 PM, Ben Wolfson wol...@gmail.com wrote: I did look at the docs and I don't really get how to return a monadic value in the right monad, the way return does automatically. All the examples I saw have something like vector or atom or what-have-you. On Tue, Jul 2, 2013 at 2:41 PM, Dragan Djuric drag...@gmail.comwrote: No, the second argument to bind only needs to be a function that takes a plain value and return a monadic value; you do not need to specify anything explicitly and it does not need to know what kind of monad it is operating on. Whatever that function returns will be a monad that the eventual second bind will operate on. Moreover, Fluokitten supports vararg bind, so the function is actually the last argument of bind in general case; it is the second argument only if there are two args. Please note that Fluokitten does not have a built-in mdo (a syntactic sugar for nested binds) for now. The reason is that Clojure itself has native constructs that do many stuff that Haskell's do does, so I am not yet sure why and if it would be useful, and if I add it how to make it non-awkward. Of course, I am open to suggestions. Also note that Fluokitten is not monad-centric, it has functors, applicatives, etc and I plan to add more categorical concepts, so It is different in that regard from other monadic Clojure libraries. That's why I would like to suggest reading the docs, most of the stuff is significantly different from other libs, and more similar (but simpler, due
Re: [ANN] Fluokitten - Category theory concepts in Clojure - Functors, Applicatives, Monads, Monoids and more
On Tue, Jul 2, 2013 at 4:33 PM, Dragan Djuric draga...@gmail.com wrote: And in this case you have to explicitly specify which monad you want to use, every time you call bind. I understand that in some case it might be a preferred way, but in my opinion for most cases that I care about I prefer it the other way. No, you don't. You don't have to specify the monad you want to use until you actually want to use it: ; nREPL 0.1.7 user #Namespace monads.core monads.core (defn mc [x] (= (return x) (fn [a] (= (return (inc a)) (fn [b] (return (+ x (* 2 b #'monads.core/mc monads.core (def m* (mc 5)) #'monads.core/m* monads.core (require '[monads.identity :as i] '[monads.maybe :as m]) nil monads.core (run-monad i/m m*) 17 monads.core (run-monad m/m m*) #Just 17 monads.core m* is already defined in a completely agnostic way before it's run. I thought i had already demonstrated that in my previous email when I defined mc as (= (return 3) (f inc)), prior to interpreting it in the context of any particular monad. Regarding monadic laws, which one exactly demands that you cannot change the monad (not counting the fact that haskell's implementation does it that way)? Here are the laws, in Haskell: return a = k = k a m = return= m m = (\x - k x = h) = (m = k) = h It seems to me the laws are still satisfied if you keep changing monads in each bind (if compiler is not restricting it, as is the case with Haskell but not with Clojure). I suppose that may be right: you're supposed to verify that the laws obtain for a putative monad; they don't come for free just by calling something a monad. Allowing = to have the type m a - (a - n b) - n b just means that you can't verify that yours obeys the laws. If you get to choose the type of return, even the second one is up for grabs! It does seem somewhat odd to me to advertise the package as being familiar to Haskellers and to employ category-theoretic concepts and then to be so blasé about the definition of a monad. (I wonder if you can get away with this changing of type at all if you define bind in terms of fmap and join). On Wednesday, July 3, 2013 1:19:10 AM UTC+2, Ben wrote: IMO you *always* want the monad to stay the same---the laws describing monadic computations don't account for swapping the things out midstream, at any rate. And it pays to be able to define monadic computations without having to explicitly pass around a token to serve as the current monad. FWIW, you *can* directly translate that function into clojure: monads.core (defn f [g] (comp return g g)) #'monads.core/f monads.core (require '[monads.state :as st]) nil monads.core (st/run-state (= get-state (f inc)) 5) #Pair [7 5] monads.core (require '[monads.list :as l]) nil monads.core (require '[monads.maybe :as m]) nil monads.core (def mc (= (return 3) (f inc))) #'monads.core/mc monads.core (run-monad m/m mc) #Just 5 monads.core (run-monad l/m mc) (5) monads.core (st/run-state mc {}) #Pair [5 {}] You just have to take a different approach to how the results are executed. (This is with this lib: https://github.com/bwo/monads) On Tue, Jul 2, 2013 at 4:03 PM, Dragan Djuric drag...@gmail.com wrote: pure function, defined in applicative, is equivalent to return (In Haskell, in Fluokitten there is only pure). I think I understand what is your question now. Since Clojure does not support polymorphysm based on the returning argument you cannot translate that Haskell code exactly. For such a case (when you want to keep operating in the same monad without knowing which one it is), a you have to provide an argument for m in f (but that's how Clojure works :), and then apply it partially or curry it: (defn f [m g] (comp (pure m) g g)) (def c+ (curry +)) (bind [1 2 3] (f [] (c+ 2)) or (= [1 2 3] (f [] (c+ 2)) If [] really hurts your aesthetic views maybe a macro (bind* or mdo) would help, since instead of [], any vector, let's say [1 2 3] would do, but then, it's a special case when you actually want the monad to stay the same. Thank you for helpful comments, BTW :) On Wednesday, July 3, 2013 12:03:45 AM UTC+2, Ben wrote: e.g., I'm not sure how to define the function f here: $ ghci GHCi, version 7.4.1: http://www.haskell.org/ghc/ :? for help Loading package ghc-prim ... linking ... done. Loading package integer-gmp ... linking ... done. Loading package base ... linking ... done. Prelude let f :: (Monad m) = (a - a) - a - m a ; f g = return . g . g Prelude Just 4 = f (2+) Just 8 Prelude [[1]] = f (2:) [[2,2,1]] Prelude import Control.Monad.State Prelude Control.Monad.State runState (get = f (+4)) 4 Loading package transformers-0.2.2.0 ... linking ... done. Loading package mtl-2.0.1.0 ... linking ... done. (12,4) Prelude Control.Monad.State On Tue, Jul 2, 2013 at 2:45 PM, Ben Wolfson wol
Re: [ANN] Fluokitten - Category theory concepts in Clojure - Functors, Applicatives, Monads, Monoids and more
On Tue, Jul 2, 2013 at 5:06 PM, Ben Wolfson wolf...@gmail.com wrote: On Tue, Jul 2, 2013 at 4:33 PM, Dragan Djuric draga...@gmail.com wrote: Regarding monadic laws, which one exactly demands that you cannot change the monad (not counting the fact that haskell's implementation does it that way)? Here are the laws, in Haskell: return a = k = k a m = return= m m = (\x - k x = h) = (m = k) = h It seems to me the laws are still satisfied if you keep changing monads in each bind (if compiler is not restricting it, as is the case with Haskell but not with Clojure). I suppose that may be right: you're supposed to verify that the laws obtain for a putative monad; they don't come for free just by calling something a monad. Allowing = to have the type m a - (a - n b) - n b just means that you can't verify that yours obeys the laws. If you get to choose the type of return, even the second one is up for grabs! It does seem somewhat odd to me to advertise the package as being familiar to Haskellers and to employ category-theoretic concepts and then to be so blasé about the definition of a monad. (I wonder if you can get away with this changing of type at all if you define bind in terms of fmap and join). How are you even supposed to implement bind, in fact? (Never mind reasoning about what's going on in your program if you can't be certain that the code won't switch out the monad you think you're working in, when it does matter to you that you're in a specific one.) Generally for some specific monad you need to do something specific with the return of f. For instance, your seq-bind is implemented in terms of mapcat---meaning that the f that's the second argument of mapcat had better return a seqable. This doesn't work: (mapcat (comp atom inc) '(1 2 3)). -- Ben Wolfson Human kind has used its intelligence to vary the flavour of drinks, which may be sweet, aromatic, fermented or spirit-based. ... Family and social life also offer numerous other occasions to consume drinks for pleasure. [Larousse, Drink entry] -- -- You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en --- You received this message because you are subscribed to the Google Groups Clojure group. To unsubscribe from this group and stop receiving emails from it, send an email to clojure+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/groups/opt_out.
Re: - operator and monads
Yes, I said that it's *like *function composition in reverse order. And only if you apply the function returned by comp, as I did in my example. It's not to be taken too literally, but it is perhaps helpful for people coming from language that have function composition but no analogue to -. On Sunday, 14 April 2013 21:03:20 UTC+1, Marko Topolnik wrote: On Sunday, April 14, 2013 7:51:10 PM UTC+2, Matthew Hill wrote: Function composition is done via comp. Using - and - is like function composition in reverse order (though there's a difference between how the two thread return values), and often it reads more naturally. - applies the functions immediately whereas comp returns a new function that is the composition of its arguments. - works with functions of any arity; comp only with unary functions. As pointed out above, - merely combines the unevaluated forms it is given, and only if they happen to be function application forms will the result be similar to function composition. -marko -- -- You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en --- You received this message because you are subscribed to the Google Groups Clojure group. To unsubscribe from this group and stop receiving emails from it, send an email to clojure+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/groups/opt_out.
ANN: Morph 0.3.0, monads+functors lib gets perf boost
In this release the lib gets rid of reflective calls by adding type hints. https://github.com/blancas/morph I don't have any benchmarks, but in Ben's tree-numbering Morph's timing goes from ~13,700 msecs down to ~350. https://github.com/bwo/monads/wiki/Tree-numbering-benchmark Morph tries hard to demystify the use of monads (though writing new ones may be a bit tricker). The same with functors: types that map regular functions over their fields. Morph extends Clojure types as functors; want to map over a collection and keep the type? Use Morp's fmap instead of map. Extending your own types as functors is pretty easy. Documentation: https://github.com/blancas/morph/wiki http://blancas.github.io/morph/ For bug reports, feedback, or feature requests: https://github.com/blancas/morph/issues?state=open -- -- You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en --- You received this message because you are subscribed to the Google Groups Clojure group. To unsubscribe from this group and stop receiving emails from it, send an email to clojure+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/groups/opt_out.
Re: - operator and monads
Function composition is done via comp. Using - and - is like function composition in reverse order (though there's a difference between how the two thread return values), and often it reads more naturally. user (- [1 2 5] rest first) 2 user ((comp first rest) [1 2 5]) 2 On Wednesday, 3 April 2013 19:21:43 UTC+1, Plinio Balduino wrote: Hi there Is it correct to say that - operator is a kind of monad in Clojure? Thank you in advance. Plínio Balduino -- -- You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en --- You received this message because you are subscribed to the Google Groups Clojure group. To unsubscribe from this group and stop receiving emails from it, send an email to clojure+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/groups/opt_out.
Re: - operator and monads
On Sunday, April 14, 2013 7:51:10 PM UTC+2, Matthew Hill wrote: Function composition is done via comp. Using - and - is like function composition in reverse order (though there's a difference between how the two thread return values), and often it reads more naturally. - applies the functions immediately whereas comp returns a new function that is the composition of its arguments. - works with functions of any arity; comp only with unary functions. As pointed out above, - merely combines the unevaluated forms it is given, and only if they happen to be function application forms will the result be similar to function composition. -marko -- -- You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en --- You received this message because you are subscribed to the Google Groups Clojure group. To unsubscribe from this group and stop receiving emails from it, send an email to clojure+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/groups/opt_out.
Re: - operator and monads
On Sun, Apr 14, 2013 at 1:03 PM, Marko Topolnik marko.topol...@gmail.comwrote: On Sunday, April 14, 2013 7:51:10 PM UTC+2, Matthew Hill wrote: Function composition is done via comp. Using - and - is like function composition in reverse order (though there's a difference between how the two thread return values), and often it reads more naturally. - applies the functions immediately whereas comp returns a new function that is the composition of its arguments. - works with functions of any arity; comp only with unary functions. As pointed out above, - merely combines the unevaluated forms it is given, and only if they happen to be function application forms will the result be similar to function composition. Even that's somewhat misleading. user= (defn make-adder [n] (fn [x] (+ n x))) #'user/make-adder user= ((comp println (make-adder 4)) 3) 7 nil user= (- 3 (make-adder 4) println) ArityException Wrong number of args (2) passed to: user$make-adder clojure.lang.AFn.throwArity (AFn.java:437) user= (- 3 ((make-adder 4)) println) 7 nil (make-adder 4) is a function application form but the result isn't similar to function composition because the threading operators rewrite their arguments, so we end up with (make-adder 3 4). If it were expected that all arguments but the first would be functions, rather than lists corresponding to function-invocations-with-one-argument-deleted, then - *could* be equivalent to function composition (and could be written as a regular function): user= (defn -* [a cs] ((apply comp (reverse cs)) a)) #'user/-* user= (-* 3 (make-adder 4) println) 7 nil user= (-* [1 2 3] (partial map inc) set #(contains? % 4)) true -- Ben Wolfson Human kind has used its intelligence to vary the flavour of drinks, which may be sweet, aromatic, fermented or spirit-based. ... Family and social life also offer numerous other occasions to consume drinks for pleasure. [Larousse, Drink entry] -- -- You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en --- You received this message because you are subscribed to the Google Groups Clojure group. To unsubscribe from this group and stop receiving emails from it, send an email to clojure+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/groups/opt_out.
Monads usage
Hi, I've been reading about monads for the past couple of weeks and I think I got the idea, but I still don't know when to use it since I don't have enough experience with functional programming. So, I'd like to ask you guys if you can point me to some examples of Monads usage in the wild. Because I've seen a lot of simple examples but not a real one, used in a library, etc. Does anyone know a good example of real world usage? Thanks in advance. -- -- You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en --- You received this message because you are subscribed to the Google Groups Clojure group. To unsubscribe from this group and stop receiving emails from it, send an email to clojure+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/groups/opt_out.
Re: Monads usage
I have a love/hate relationship with monads. I think their use in Clojure programming is much more limited than most would like to admit. However, I have found a very nice use for them: in my case, I'm attempting to insert a very complex AST into Datomic. I'd like all my data to go into Datomic as one large transaction (a vector of hashmaps). My first attempt at this code looked like this: Assume my data is: {:type :+ :arg0 {:type :const :value 1} :arg1 {:type :const :value 2} Insert for the + node: (let [[arg0-id with-arg0] (insert-node (:arg0 this) plan) [arg1-id with-arg1] (insert-node (:arg1 this) with-arg1) [this-id with-this] (assert-entity {:arg0 arg0-id :arg1 arg1-od})] [this-id with-this]) So basically every single function has to return the last inserted id as well as a db tx plan that contains all items that need to be inserted. Not only is this code ugly, but I found it very error prone. Sometimes I would pass the wrong plan name in, and things would break. So I looked at this and said why not use the state monad. So now insert-node looks like this: (insert-node [ent] (fn [plan] . do stuff . [ent plan])) I created a monad binding function called gen-plan: (defmacro gen-plan [binds id-expr] (let [binds (partition 2 binds) psym (gensym plan_) f (reduce (fn [acc [id expr]] `(~(with-bind id expr psym acc) ~psym)) `[~id-expr ~psym] (reverse binds))] `(fn [~psym] ~f))) And our example above looks like this: (gen-plan [arg0-id (insert-node (:arg0 this)) arg1-id (insert-node (:arg1 this)) this-id (assert-entity {:arg0 arg0-id :arg1 arg1-id})] this-id) Notice how the state monad makes the plan implicit. And now I can write super complex functions like this, without drowning in the code. Notice how this block (which generates a tx for writing a SSA style if expression to Datomic) is clear from any mentions of explicit state, but yet is remains completely functional. (gen-plan [fnc (get-in-plan [:state :fn]) test-id (write-ssa test) test-block (get-block) pre-then-block (add-block fnc) _ (set-block pre-then-block) then-val (write-ssa then) post-then-block (get-block) then-terminated? (terminated? post-then-block) pre-else-block (add-block fnc) _ (set-block pre-else-block) else-val (write-ssa else) post-else-block (get-block) else-terminated? (terminated? post-else-block) merge-block (add-block fnc) _ (set-block merge-block) phi-val (add-phi) _ (set-block test-block) br-id (terminate-block :inst.type/br test-id pre-then-block pre-else-block) _ (if then-terminated? (no-op) (gen-plan [_ (set-block post-then-block) _ (terminate-block :inst.type/jmp merge-block) _ (add-to-phi phi-val post-then-block then-val)] nil)) _ (if else-terminated? (no-op) (gen-plan [_ (set-block post-else-block) _ (terminate-block :inst.type/jmp merge-block) _ (add-to-phi phi-val post-else-block else-val)] nil)) _ (set-block merge-block)] phi-val) So I look at this way, I see monads as a purely academic exercise 90% of the time. To try to go whole hog and apply them to every problem at hand is just nonsense. However, there are times (like in this example) where monads end up being the perfect tool for the job at hand. So I say, instead of looking at a problem and saying what monad is this? Instead, look at ugly code and say hrm...I wonder if programming method X could make this cleaner. If that method is a monad, awesome! Timothy On Mon, Apr 8, 2013 at 8:56 AM, Carlos Galdino carloshsgald...@gmail.comwrote: Hi, I've been reading about monads for the past couple of weeks and I think I got the idea, but I still don't know when to use it since I don't have enough experience with functional programming. So, I'd like to ask you guys if you can point me to some examples of Monads usage in the wild. Because I've seen a lot of simple examples but not a real one, used in a library, etc. Does anyone know a good example of real world usage? Thanks in advance. -- -- You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en --- You received this message because you are subscribed to the Google Groups Clojure group. To unsubscribe from this group and stop receiving emails from it, send an email to clojure+unsubscr...@googlegroups.com
Re: Monads usage
oops, gen-plan was missing a helper function: (defn- with-bind [id expr psym body] `(fn [~psym] (let [[~id ~psym] ( ~expr ~psym)] (assert ~psym Nil plan) ~body))) On Mon, Apr 8, 2013 at 9:32 AM, Timothy Baldridge tbaldri...@gmail.comwrote: I have a love/hate relationship with monads. I think their use in Clojure programming is much more limited than most would like to admit. However, I have found a very nice use for them: in my case, I'm attempting to insert a very complex AST into Datomic. I'd like all my data to go into Datomic as one large transaction (a vector of hashmaps). My first attempt at this code looked like this: Assume my data is: {:type :+ :arg0 {:type :const :value 1} :arg1 {:type :const :value 2} Insert for the + node: (let [[arg0-id with-arg0] (insert-node (:arg0 this) plan) [arg1-id with-arg1] (insert-node (:arg1 this) with-arg1) [this-id with-this] (assert-entity {:arg0 arg0-id :arg1 arg1-od})] [this-id with-this]) So basically every single function has to return the last inserted id as well as a db tx plan that contains all items that need to be inserted. Not only is this code ugly, but I found it very error prone. Sometimes I would pass the wrong plan name in, and things would break. So I looked at this and said why not use the state monad. So now insert-node looks like this: (insert-node [ent] (fn [plan] . do stuff . [ent plan])) I created a monad binding function called gen-plan: (defmacro gen-plan [binds id-expr] (let [binds (partition 2 binds) psym (gensym plan_) f (reduce (fn [acc [id expr]] `(~(with-bind id expr psym acc) ~psym)) `[~id-expr ~psym] (reverse binds))] `(fn [~psym] ~f))) And our example above looks like this: (gen-plan [arg0-id (insert-node (:arg0 this)) arg1-id (insert-node (:arg1 this)) this-id (assert-entity {:arg0 arg0-id :arg1 arg1-id})] this-id) Notice how the state monad makes the plan implicit. And now I can write super complex functions like this, without drowning in the code. Notice how this block (which generates a tx for writing a SSA style if expression to Datomic) is clear from any mentions of explicit state, but yet is remains completely functional. (gen-plan [fnc (get-in-plan [:state :fn]) test-id (write-ssa test) test-block (get-block) pre-then-block (add-block fnc) _ (set-block pre-then-block) then-val (write-ssa then) post-then-block (get-block) then-terminated? (terminated? post-then-block) pre-else-block (add-block fnc) _ (set-block pre-else-block) else-val (write-ssa else) post-else-block (get-block) else-terminated? (terminated? post-else-block) merge-block (add-block fnc) _ (set-block merge-block) phi-val (add-phi) _ (set-block test-block) br-id (terminate-block :inst.type/br test-id pre-then-block pre-else-block) _ (if then-terminated? (no-op) (gen-plan [_ (set-block post-then-block) _ (terminate-block :inst.type/jmp merge-block) _ (add-to-phi phi-val post-then-block then-val)] nil)) _ (if else-terminated? (no-op) (gen-plan [_ (set-block post-else-block) _ (terminate-block :inst.type/jmp merge-block) _ (add-to-phi phi-val post-else-block else-val)] nil)) _ (set-block merge-block)] phi-val) So I look at this way, I see monads as a purely academic exercise 90% of the time. To try to go whole hog and apply them to every problem at hand is just nonsense. However, there are times (like in this example) where monads end up being the perfect tool for the job at hand. So I say, instead of looking at a problem and saying what monad is this? Instead, look at ugly code and say hrm...I wonder if programming method X could make this cleaner. If that method is a monad, awesome! Timothy On Mon, Apr 8, 2013 at 8:56 AM, Carlos Galdino carloshsgald...@gmail.comwrote: Hi, I've been reading about monads for the past couple of weeks and I think I got the idea, but I still don't know when to use it since I don't have enough experience with functional programming. So, I'd like to ask you guys if you can point me to some examples of Monads usage in the wild. Because I've seen a lot of simple examples but not a real one, used in a library, etc. Does anyone know a good example of real world usage? Thanks in advance. -- -- You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from
Re: Monads usage
Last week I released a project with a monadic translator that needed to: - work on sequences of expressions, arbitrarily nested - generate Clojure code or stop and report the first error - maintain a symbol table with easy access but not global state The relevant code is here: https://github.com/blancas/eisen/blob/master/src/main/clojure/blancas/eisen/trans.clj The code uses a StateT monad transformer and Either monad wrapped in five API functions: -left, -right, get-se, modify-se, run-se. Functions report errors with (-left); function (-right) wraps good values. The macro (monad) corresponds to Haskell's do; it chains monadic values or short-circuits and propagates errors. (defn trans-binop Translates the application of a binary operator. [ast] (monad [x (trans-expr (:left ast)) y (trans-expr (:right ast))] (let [f (- ast :op :value str symbol)] (-right `(~f ~x ~y) The symbol table is available through get-se and modify-se. A typical use case is to enter declared names, translate the expressions, then remove the names from the symbol table. (defn trans-let Translates a let expression. [{:keys [decls exprs]}] (let [env (map (comp symbol :name) decls)] (monad [_ (modify-se into env) decls (trans-bindings decls) exprs (trans-exprs exprs) _ (modify-se difference env)] (-right `(let [~@(apply concat decls)] ~@exprs) To translate expressions in a sequence it uses the generic function (seqm); function (run-se) evaluates the resulting sequenced monads using an initial state predefs. The result from (run-se) feeds (either) which evaluates to the first form on -left and to the second on -right. (let [job (monad [v (seqm (map eval-ast coll))] (-right v))] (either [res (run-se job predefs)] {:ok false :error res} {:ok true :decls (map first res) :value (- res last second)}))) On Monday, April 8, 2013 7:56:35 AM UTC-7, Carlos Galdino wrote: Hi, I've been reading about monads for the past couple of weeks and I think I got the idea, but I still don't know when to use it since I don't have enough experience with functional programming. So, I'd like to ask you guys if you can point me to some examples of Monads usage in the wild. Because I've seen a lot of simple examples but not a real one, used in a library, etc. Does anyone know a good example of real world usage? Thanks in advance. -- -- You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en --- You received this message because you are subscribed to the Google Groups Clojure group. To unsubscribe from this group and stop receiving emails from it, send an email to clojure+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/groups/opt_out.
Re: - operator and monads
if you come from the haskell world, it is like . piplining - but in reverse order I needed some time to get used to it but I really like - - as- ... to structure my code. It helps to see the sequence of functions that operate on your data On Wed, Apr 3, 2013 at 11:05 PM, Alan Malloy a...@malloys.org wrote: Not even that: - is not a function composition operator at all, but a form-rewriting macro. You can perfectly well write (- [x xs] (for (inc x))) to get (for [x xs] (inc x)), and that is not composing any functions. The two things are entirely separate. On Wednesday, April 3, 2013 12:45:55 PM UTC-7, Marko Topolnik wrote: I guess you mean the monadic bind operation, but - is not it. The only conceptual connection between *bind* and - is that they are both some kind of function composition operators. -marko On Wednesday, April 3, 2013 8:21:43 PM UTC+2, Plinio Balduino wrote: Hi there Is it correct to say that - operator is a kind of monad in Clojure? Thank you in advance. Plínio Balduino -- -- You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en --- You received this message because you are subscribed to the Google Groups Clojure group. To unsubscribe from this group and stop receiving emails from it, send an email to clojure+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/groups/opt_out. -- -- You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en --- You received this message because you are subscribed to the Google Groups Clojure group. To unsubscribe from this group and stop receiving emails from it, send an email to clojure+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/groups/opt_out.
Re: - operator and monads
Isn't the dot just like Clojure's *comp*? As Allan correctly points out, the thrushes are macros that combine the given forms in a specified way, which only under certain constraints has the effect of composing function applications, whereas *comp* is truly a function composition operator. On Thursday, April 4, 2013 4:25:18 PM UTC+2, Maik Schünemann wrote: if you come from the haskell world, it is like . piplining - but in reverse order I needed some time to get used to it but I really like - - as- ... to structure my code. It helps to see the sequence of functions that operate on your data On Wed, Apr 3, 2013 at 11:05 PM, Alan Malloy al...@malloys.orgjavascript: wrote: Not even that: - is not a function composition operator at all, but a form-rewriting macro. You can perfectly well write (- [x xs] (for (inc x))) to get (for [x xs] (inc x)), and that is not composing any functions. The two things are entirely separate. On Wednesday, April 3, 2013 12:45:55 PM UTC-7, Marko Topolnik wrote: I guess you mean the monadic bind operation, but - is not it. The only conceptual connection between *bind* and - is that they are both some kind of function composition operators. -marko On Wednesday, April 3, 2013 8:21:43 PM UTC+2, Plinio Balduino wrote: Hi there Is it correct to say that - operator is a kind of monad in Clojure? Thank you in advance. Plínio Balduino -- -- You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clo...@googlegroups.comjavascript: Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+u...@googlegroups.com javascript: For more options, visit this group at http://groups.google.com/group/clojure?hl=en --- You received this message because you are subscribed to the Google Groups Clojure group. To unsubscribe from this group and stop receiving emails from it, send an email to clojure+u...@googlegroups.com javascript:. For more options, visit https://groups.google.com/groups/opt_out. -- -- You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en --- You received this message because you are subscribed to the Google Groups Clojure group. To unsubscribe from this group and stop receiving emails from it, send an email to clojure+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/groups/opt_out.
ANN: monads 0.1.0, YA monads lib for clojure
After much tinkering I am announcing a new monads implementation: https://github.com/bwo/monads Rather than using protocols or symbol macros as (I believe) all hitherto existing monad libraries for Clojure have, this implementation has the elements of a monadic computation build up a structure which the individual monads interpret, with the goal of allowing for flexibility and expressiveness. The wiki has a small benchmark, which also gives an example of using the state monad: https://github.com/bwo/monads/wiki/Tree-numbering-benchmark And an example of using monad transformer stacks, demonstrating the state, writer, maybe, and error monads: https://github.com/bwo/monads/wiki/An-expression-evaluator Feedback welcome! -- Ben Wolfson Human kind has used its intelligence to vary the flavour of drinks, which may be sweet, aromatic, fermented or spirit-based. ... Family and social life also offer numerous other occasions to consume drinks for pleasure. [Larousse, Drink entry] -- -- You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en --- You received this message because you are subscribed to the Google Groups Clojure group. To unsubscribe from this group and stop receiving emails from it, send an email to clojure+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/groups/opt_out.
- operator and monads
Hi there Is it correct to say that - operator is a kind of monad in Clojure? Thank you in advance. Plínio Balduino -- -- You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en --- You received this message because you are subscribed to the Google Groups Clojure group. To unsubscribe from this group and stop receiving emails from it, send an email to clojure+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/groups/opt_out.
Re: - operator and monads
I guess you mean the monadic bind operation, but - is not it. The only conceptual connection between *bind* and - is that they are both some kind of function composition operators. -marko On Wednesday, April 3, 2013 8:21:43 PM UTC+2, Plinio Balduino wrote: Hi there Is it correct to say that - operator is a kind of monad in Clojure? Thank you in advance. Plínio Balduino -- -- You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en --- You received this message because you are subscribed to the Google Groups Clojure group. To unsubscribe from this group and stop receiving emails from it, send an email to clojure+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/groups/opt_out.
Re: - operator and monads
Now it's clear. Thank you Plínio On Wed, Apr 3, 2013 at 4:45 PM, Marko Topolnik marko.topol...@gmail.comwrote: I guess you mean the monadic bind operation, but - is not it. The only conceptual connection between *bind* and - is that they are both some kind of function composition operators. -marko On Wednesday, April 3, 2013 8:21:43 PM UTC+2, Plinio Balduino wrote: Hi there Is it correct to say that - operator is a kind of monad in Clojure? Thank you in advance. Plínio Balduino -- -- You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en --- You received this message because you are subscribed to the Google Groups Clojure group. To unsubscribe from this group and stop receiving emails from it, send an email to clojure+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/groups/opt_out. -- -- You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en --- You received this message because you are subscribed to the Google Groups Clojure group. To unsubscribe from this group and stop receiving emails from it, send an email to clojure+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/groups/opt_out.
Re: - operator and monads
Not even that: - is not a function composition operator at all, but a form-rewriting macro. You can perfectly well write (- [x xs] (for (inc x))) to get (for [x xs] (inc x)), and that is not composing any functions. The two things are entirely separate. On Wednesday, April 3, 2013 12:45:55 PM UTC-7, Marko Topolnik wrote: I guess you mean the monadic bind operation, but - is not it. The only conceptual connection between *bind* and - is that they are both some kind of function composition operators. -marko On Wednesday, April 3, 2013 8:21:43 PM UTC+2, Plinio Balduino wrote: Hi there Is it correct to say that - operator is a kind of monad in Clojure? Thank you in advance. Plínio Balduino -- -- You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en --- You received this message because you are subscribed to the Google Groups Clojure group. To unsubscribe from this group and stop receiving emails from it, send an email to clojure+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/groups/opt_out.
Re: [ANN] Morph v0.1.0 Monads friends: pure functions, less boilerplate
btw, have you seen https://github.com/jduey/protocol-monads ? Marek On Thursday, February 7, 2013 1:06:39 AM UTC+1, Armando Blancas wrote: Morph is a new implementation of monads based on protocols. It's intended to provide the common patterns of error-handling, short-circuit sequencing, and modeling of stateful computations in pure functions. I've tried to make this library idiomatic while keeping it close to its Haskell roots. This is a utility library that, I hope, can make your coding easier. No particular knowledge is assumed or required. The docs name things but rely on getting an intuitive feeling of what's going on. Protocols are relevant only if you want to write your own plumbing, which shouldn't be difficult; otherwise it's all ready to use. Project: https://github.com/blancas/morph User Guide: https://github.com/blancas/morph/wiki Codox API: http://blancas.github.com/morph Please use the project wiki for feedback, bug reports, or feature requests. -- -- You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en --- You received this message because you are subscribed to the Google Groups Clojure group. To unsubscribe from this group and stop receiving emails from it, send an email to clojure+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/groups/opt_out.
Re: [ANN] Morph v0.1.0 Monads friends: pure functions, less boilerplate
Yeap, I've had looked at Jim Duey's projects and had read his articles at his website; it's good content. On Thursday, February 7, 2013 1:48:12 AM UTC-8, Marek Srank wrote: btw, have you seen https://github.com/jduey/protocol-monads ? Marek On Thursday, February 7, 2013 1:06:39 AM UTC+1, Armando Blancas wrote: Morph is a new implementation of monads based on protocols. It's intended to provide the common patterns of error-handling, short-circuit sequencing, and modeling of stateful computations in pure functions. I've tried to make this library idiomatic while keeping it close to its Haskell roots. This is a utility library that, I hope, can make your coding easier. No particular knowledge is assumed or required. The docs name things but rely on getting an intuitive feeling of what's going on. Protocols are relevant only if you want to write your own plumbing, which shouldn't be difficult; otherwise it's all ready to use. Project: https://github.com/blancas/morph User Guide: https://github.com/blancas/morph/wiki Codox API: http://blancas.github.com/morph Please use the project wiki for feedback, bug reports, or feature requests. -- -- You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en --- You received this message because you are subscribed to the Google Groups Clojure group. To unsubscribe from this group and stop receiving emails from it, send an email to clojure+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/groups/opt_out.
[ANN] Morph v0.1.0 Monads friends: pure functions, less boilerplate
Morph is a new implementation of monads based on protocols. It's intended to provide the common patterns of error-handling, short-circuit sequencing, and modeling of stateful computations in pure functions. I've tried to make this library idiomatic while keeping it close to its Haskell roots. This is a utility library that, I hope, can make your coding easier. No particular knowledge is assumed or required. The docs name things but rely on getting an intuitive feeling of what's going on. Protocols are relevant only if you want to write your own plumbing, which shouldn't be difficult; otherwise it's all ready to use. Project: https://github.com/blancas/morph User Guide: https://github.com/blancas/morph/wiki Codox API: http://blancas.github.com/morph Please use the project wiki for feedback, bug reports, or feature requests. -- -- You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en --- You received this message because you are subscribed to the Google Groups Clojure group. To unsubscribe from this group and stop receiving emails from it, send an email to clojure+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/groups/opt_out.
Re: [ANN] Morph v0.1.0 Monads friends: pure functions, less boilerplate
this is great, just one nit to pick about currying (because it's something that's bitten me in the past in other contexts): in the wiki you say For a predefined function with a fixed number of arguments, only the function name must be supplied., but this is only sort of true---the issue isn't whether the function is predefined or not, the issue is whether the argument is a symbol that resolves to a var. This, for instance, doesn't work: (let [t take] (((curry t) 3) '(1 2 3 4))) Even though take is a predefined function. And this picks up the wrong metadata (this example is factitious on its face, but it could happen in practice): blancas.morph.core (defn three-params [a b c] a) #'blancas.morph.core/three-params blancas.morph.core (let [three-params take] (((curry three-params) 3) '(1 2 3 4))) #core$eval2780$G__2784__2785$G__2786__2787$fn__2788 blancas.morph.core$eval2780 $G__2784__2785$G__2786__2787$fn__2788@65c66812 blancas.morph.core because resolve goes directly to var bindings, overlooking other niceties of lexical scope. Unrelatedly: - I couldn't figure out how to write something like foldM, because I couldn't figure out how to call return on the seed value when the list is empty. ISTR (when you announced your parsing library) that there isn't a way to do that kind of thing at all? - I'm curious about the Monoid protocol---I have one in babbage, and it has two more methods than yours, mempty? and value (instead of monoid-specific accessors). Why not put the accessors in the protocol? On Wed, Feb 6, 2013 at 4:06 PM, Armando Blancas abm221...@gmail.com wrote: Morph is a new implementation of monads based on protocols. It's intended to provide the common patterns of error-handling, short-circuit sequencing, and modeling of stateful computations in pure functions. I've tried to make this library idiomatic while keeping it close to its Haskell roots. This is a utility library that, I hope, can make your coding easier. No particular knowledge is assumed or required. The docs name things but rely on getting an intuitive feeling of what's going on. Protocols are relevant only if you want to write your own plumbing, which shouldn't be difficult; otherwise it's all ready to use. Project: https://github.com/blancas/morph User Guide: https://github.com/blancas/morph/wiki Codox API: http://blancas.github.com/morph Please use the project wiki for feedback, bug reports, or feature requests. -- -- You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en --- You received this message because you are subscribed to the Google Groups Clojure group. To unsubscribe from this group and stop receiving emails from it, send an email to clojure+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/groups/opt_out. -- Ben Wolfson Human kind has used its intelligence to vary the flavour of drinks, which may be sweet, aromatic, fermented or spirit-based. ... Family and social life also offer numerous other occasions to consume drinks for pleasure. [Larousse, Drink entry] -- -- You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en --- You received this message because you are subscribed to the Google Groups Clojure group. To unsubscribe from this group and stop receiving emails from it, send an email to clojure+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/groups/opt_out.
Re: [ANN] Morph v0.1.0 Monads friends: pure functions, less boilerplate
this is great, just one nit to pick about currying (because it's something that's bitten me in the past in other contexts): in the wiki you say For a predefined function with a fixed number of arguments, only the function name must be supplied., but this is only sort of true---the issue isn't whether the function is predefined or not, the issue is whether the argument is a symbol that resolves to a var. This, for instance, doesn't work: (let [t take] (((curry t) 3) '(1 2 3 4))) Even though take is a predefined function. And this picks up the wrong metadata (this example is factitious on its face, but it could happen in practice): blancas.morph.core (defn three-params [a b c] a) #'blancas.morph.core/three-params blancas.morph.core (let [three-params take] (((curry three-params) 3) '(1 2 3 4))) #core$eval2780$G__2784__2785$G__2786__2787$fn__2788 blancas.morph.core$eval2780 $G__2784__2785$G__2786__2787$fn__2788@65c66812 blancas.morph.core because resolve goes directly to var bindings, overlooking other niceties of lexical scope. Unrelatedly: - I couldn't figure out how to write something like foldM, because I couldn't figure out how to call return on the seed value when the list is empty. ISTR (when you announced your parsing library) that there isn't a way to do that kind of thing at all? - I'm curious about the Monoid protocol---I have one in babbage, and it has two more methods than yours, mempty? and value (instead of monoid-specific accessors). Why not put the accessors in the protocol? On Wed, Feb 6, 2013 at 4:06 PM, Armando Blancas abm221...@gmail.com wrote: Morph is a new implementation of monads based on protocols. It's intended to provide the common patterns of error-handling, short-circuit sequencing, and modeling of stateful computations in pure functions. I've tried to make this library idiomatic while keeping it close to its Haskell roots. This is a utility library that, I hope, can make your coding easier. No particular knowledge is assumed or required. The docs name things but rely on getting an intuitive feeling of what's going on. Protocols are relevant only if you want to write your own plumbing, which shouldn't be difficult; otherwise it's all ready to use. Project: https://github.com/blancas/morph User Guide: https://github.com/blancas/morph/wiki Codox API: http://blancas.github.com/morph Please use the project wiki for feedback, bug reports, or feature requests. -- -- You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en --- You received this message because you are subscribed to the Google Groups Clojure group. To unsubscribe from this group and stop receiving emails from it, send an email to clojure+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/groups/opt_out. -- Ben Wolfson Human kind has used its intelligence to vary the flavour of drinks, which may be sweet, aromatic, fermented or spirit-based. ... Family and social life also offer numerous other occasions to consume drinks for pleasure. [Larousse, Drink entry] -- -- You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en --- You received this message because you are subscribed to the Google Groups Clojure group. To unsubscribe from this group and stop receiving emails from it, send an email to clojure+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/groups/opt_out.
Re: [ANN] Morph v0.1.0 Monads friends: pure functions, less boilerplate
Good catch with currying non vars; I'll try to work something out. Also, should come up with a general defcurry macro; I'm not happy with that. Things like foldM may just not be possible, but I'll keep track of these issues so maybe I can give you a good answer for the things you've brought up. Just having to deal with deftype'd monoids is a bit of a pain, so I welcome ideas to simplify them. On Wednesday, February 6, 2013 4:43:33 PM UTC-8, Ben wrote: this is great, just one nit to pick about currying (because it's something that's bitten me in the past in other contexts): in the wiki you say For a predefined function with a fixed number of arguments, only the function name must be supplied., but this is only sort of true---the issue isn't whether the function is predefined or not, the issue is whether the argument is a symbol that resolves to a var. This, for instance, doesn't work: (let [t take] (((curry t) 3) '(1 2 3 4))) Even though take is a predefined function. And this picks up the wrong metadata (this example is factitious on its face, but it could happen in practice): blancas.morph.core (defn three-params [a b c] a) #'blancas.morph.core/three-params blancas.morph.core (let [three-params take] (((curry three-params) 3) '(1 2 3 4))) #core$eval2780$G__2784__2785$G__2786__2787$fn__2788 blancas.morph.core$eval2780 $G__2784__2785$G__2786__2787$fn__2788@65c66812 blancas.morph.core because resolve goes directly to var bindings, overlooking other niceties of lexical scope. Unrelatedly: - I couldn't figure out how to write something like foldM, because I couldn't figure out how to call return on the seed value when the list is empty. ISTR (when you announced your parsing library) that there isn't a way to do that kind of thing at all? - I'm curious about the Monoid protocol---I have one in babbage, and it has two more methods than yours, mempty? and value (instead of monoid-specific accessors). Why not put the accessors in the protocol? On Wed, Feb 6, 2013 at 4:06 PM, Armando Blancas abm2...@gmail.comjavascript: wrote: Morph is a new implementation of monads based on protocols. It's intended to provide the common patterns of error-handling, short-circuit sequencing, and modeling of stateful computations in pure functions. I've tried to make this library idiomatic while keeping it close to its Haskell roots. This is a utility library that, I hope, can make your coding easier. No particular knowledge is assumed or required. The docs name things but rely on getting an intuitive feeling of what's going on. Protocols are relevant only if you want to write your own plumbing, which shouldn't be difficult; otherwise it's all ready to use. Project: https://github.com/blancas/morph User Guide: https://github.com/blancas/morph/wiki Codox API: http://blancas.github.com/morph Please use the project wiki for feedback, bug reports, or feature requests. -- -- You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clo...@googlegroups.comjavascript: Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+u...@googlegroups.com javascript: For more options, visit this group at http://groups.google.com/group/clojure?hl=en --- You received this message because you are subscribed to the Google Groups Clojure group. To unsubscribe from this group and stop receiving emails from it, send an email to clojure+u...@googlegroups.com javascript:. For more options, visit https://groups.google.com/groups/opt_out. -- Ben Wolfson Human kind has used its intelligence to vary the flavour of drinks, which may be sweet, aromatic, fermented or spirit-based. ... Family and social life also offer numerous other occasions to consume drinks for pleasure. [Larousse, Drink entry] -- -- You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en --- You received this message because you are subscribed to the Google Groups Clojure group. To unsubscribe from this group and stop receiving emails from it, send an email to clojure+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/groups/opt_out.
Re: monads
In a few lines: Monads are a common framework to represent any sequential computation. What is a sequential computation? - either no computation at all. return :: a - m a does that. - or I have already a computation and want to go on with my computation. But then, I need to be able to look at the result of the first part of the computation to now what to do next: bind :: m a - (a - m b) - m b This tells: If I have a computation returning a value of type a, and when I will know a, I will be able to create a computation returning some b, then I can sequence those and make a computation returning some b. When I want to run it, I will run the first and use the result to construct the second and then run it. * What is interesting is that you have a representation of sequential computations and can use a common libraries of functions to work with any kind of sequential things. And there are a lot of things that corresponds to this: side-effects, logic programming, parsing... Nicolas. * The monadic notion of sequential computation allows to look at intermediate results to determine what to do next. You obtain other notion of computations like Arrows or Applicative functors if you restrict this right. -- You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en
Re: monads
On Friday, October 26, 2012 11:06:59 AM UTC-5, Brian Craft wrote: I've read about four tutorials on monads so far, but it still escapes me. In fact, I'm still not sure what problem it solves. I'm familiar with the problem of having, say, three functions like f(a) - b, g(c) - d, h(e) - f, which you'd like to chain like f(g(h(x))), but you can't because b is a different type from c and d is a different type from e. The monad tutorials all start with a problem like this, but I still can't tell if they're actually providing a solution, because it appears every monad is specific to a particular type. E.g. a sequence monad. So, great, I have something that takes a scalar and returns a sequence. That might solve g(h(x)) if f is a scalar and c is a sequence by letting me write g(s(h(x))), but it doesn't solve the whole problem, since I still have f() to worry about. snip Brian, you may have looked at it already, but I found Konrad Hinsen's 4-part tutorial linked from the README in Clojure's algo.monads repository to be quite helpful: https://github.com/clojure/algo.monads By the way, the links in that README to Jim Duey's tutorials are broken; here is the correct link to Part 1 of Jim's tutorials: http://www.intensivesystems.net/tutorials/monads_101.html I read Jim's tutorials first, and then tried Konrad's. I found the latter a bit more helpful. Also, Konrad's explanation of the state monad in Part 3 really clicked with me, so I felt it was worth working through Parts 1 and 2, even though I was still scratching my head a bit when I finished Part 2. Jim also has a more recent set of blog posts dedicated to exploring monads: http://www.clojure.net/archive.html I worked from the bottom of that list to the top, after reading the other tutorials, and came away with a basic but sound understanding of the core concepts: m-result, m-bind, the Monad Laws, etc. Also note that Jim has developed a new monads library for Clojure, implemented with protocols: https://github.com/jduey/protocol-monads Working through that library's test suite seems like a good way improve one's understanding of monads; also, I'm going to try to port the examples from algo.monads over to protocol-monads. I haven't done that yet, but when I do you will be able to find them in my fork of protocol-monads (if things go well, I'll submit a pull request): https://github.com/michaelsbradleyjr/protocol-monads/blob/examples/src/examples/monads.clj The original examples for algo.monads: https://github.com/clojure/algo.monads/blob/master/src/examples/clojure/examples/monads.clj -- You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en
Re: monads
On Fri, 2012-10-26 at 21:55 -0700, Ben Wolfson wrote: f :: a - b g :: c - d h :: e - j [renamed from f] and you'd like to chain [them] like f(g(h(x))), but you can't because b is a different type from c and d is a different type from e., how does m-chain help? I would have expected, given the b is a different type from c thing, that the chaining would go h(g(f(x)), but it's not as if that helps, unless the types work out like: b ~ m c d ~ m e I assume that Brian's original example involved such constraints, implicitly; i.e., a, b, c, d, e are metasyntactic variables in prose referring to values, not type variables. -- Stephen Compall ^aCollection allSatisfy: [:each | aCondition]: less is better than -- You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en
Re: monads
I found these articles very valuable in understanding the original motivation for monads and their use for practical development. Imperative Functional Programming Simon Peyton Jones, Philip Wadler http://research.microsoft.com/pubs/67066/imperative.ps.z Monadic Parser Combinators Graham Hutton http://eprints.nottingham.ac.uk/237/1/monparsing.pdf On Friday, October 26, 2012 9:06:59 AM UTC-7, Brian Craft wrote: I've read about four tutorials on monads so far, but it still escapes me. In fact, I'm still not sure what problem it solves. I'm familiar with the problem of having, say, three functions like f(a) - b, g(c) - d, h(e) - f, which you'd like to chain like f(g(h(x))), but you can't because b is a different type from c and d is a different type from e. The monad tutorials all start with a problem like this, but I still can't tell if they're actually providing a solution, because it appears every monad is specific to a particular type. E.g. a sequence monad. So, great, I have something that takes a scalar and returns a sequence. That might solve g(h(x)) if f is a scalar and c is a sequence by letting me write g(s(h(x))), but it doesn't solve the whole problem, since I still have f() to worry about. So, two specific questions. First, do monads provide a generic solution, so I can apply f(g(h(x)))? Second, is it the whole point of monads to use macros so you don't see the glue functions, like s(), in my example? I mean, we can always write glue functions so we can compose functions with different input/output types without using monads. What exactly are monads adding? Oh, and one more. If I were to actually use a monad in a piece of production code, what are the chances that the next person working on the code would have the faintest idea how it worked? ;-p -- You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en
monads
I've read about four tutorials on monads so far, but it still escapes me. In fact, I'm still not sure what problem it solves. I'm familiar with the problem of having, say, three functions like f(a) - b, g(c) - d, h(e) - f, which you'd like to chain like f(g(h(x))), but you can't because b is a different type from c and d is a different type from e. The monad tutorials all start with a problem like this, but I still can't tell if they're actually providing a solution, because it appears every monad is specific to a particular type. E.g. a sequence monad. So, great, I have something that takes a scalar and returns a sequence. That might solve g(h(x)) if f is a scalar and c is a sequence by letting me write g(s(h(x))), but it doesn't solve the whole problem, since I still have f() to worry about. So, two specific questions. First, do monads provide a generic solution, so I can apply f(g(h(x)))? Second, is it the whole point of monads to use macros so you don't see the glue functions, like s(), in my example? I mean, we can always write glue functions so we can compose functions with different input/output types without using monads. What exactly are monads adding? Oh, and one more. If I were to actually use a monad in a piece of production code, what are the chances that the next person working on the code would have the faintest idea how it worked? ;-p -- You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en
Re: monads
I can't say I grok monads completely yet, but was one of the tutorials you read this one? http://blog.sigfpe.com/2006/08/you-could-have-invented-monads-and.html I like the style of showing how they solve problems that arise naturally in the context of purely functional programming, with several examples of those kinds of problems. Andy On Oct 26, 2012, at 9:06 AM, Brian Craft wrote: I've read about four tutorials on monads so far, but it still escapes me. In fact, I'm still not sure what problem it solves. I'm familiar with the problem of having, say, three functions like f(a) - b, g(c) - d, h(e) - f, which you'd like to chain like f(g(h(x))), but you can't because b is a different type from c and d is a different type from e. The monad tutorials all start with a problem like this, but I still can't tell if they're actually providing a solution, because it appears every monad is specific to a particular type. E.g. a sequence monad. So, great, I have something that takes a scalar and returns a sequence. That might solve g(h(x)) if f is a scalar and c is a sequence by letting me write g(s(h(x))), but it doesn't solve the whole problem, since I still have f() to worry about. So, two specific questions. First, do monads provide a generic solution, so I can apply f(g(h(x)))? Second, is it the whole point of monads to use macros so you don't see the glue functions, like s(), in my example? I mean, we can always write glue functions so we can compose functions with different input/output types without using monads. What exactly are monads adding? Oh, and one more. If I were to actually use a monad in a piece of production code, what are the chances that the next person working on the code would have the faintest idea how it worked? ;-p -- You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en
Re: monads
On Oct 26, 2012, at 11:06 AM, Brian Craft wrote: I've read about four tutorials on monads so far, but it still escapes me. In fact, I'm still not sure what problem it solves. Monads are hard to understand, and I too found I wasn't the target audience for the explanations I read. I finally had to write my own as a way to force me to understand. Advertisement: the explanation is in chapter 10 and the optional chapters 15 and 16 of my book. (URL in my signature.) People seem to like mine because I start with the implementation, not the abstract ideas. Also, I lie when necessary on the way to the complete explanation. The problem monads solve is twofold: 1. Suppose you have a series of computational steps. The results of those steps have to be combined in some way. A monad lets you move the combination rules away from the steps, so that you don't have to look at them. You just look at the steps and keep the rules in the back of your mind. That reduces code clutter. 2. Often, the rules are more general purpose than the steps. For example, it's common to want to break out of a series of steps when an error happens. Rather than scattering `if`s between some steps, you can point the Error monad at them. (When is that better than just using try/catch? -- that's still an open question to me.) That said, the *really* general-purpose monads tend to get written into the language as special forms. Clojure's `let` and `for` are both monads, but you don't need to know that to use them. One thing that's important to realize about monads is that they apply the *same* rule to every step. That seems to make them clunky when you're working on problems that aren't nicely structured. But for certain structured problems, especially ones that lend themselves to combinations of predefined rules that apply to every step, monads are just The Right Thing. Even if you don't use them, I'm inclined to think monads are a useful example of how to think about functions in a functional language. It helps you avoid just writing C code in Clojure. - Brian Marick, Artisanal Labrador Contract programming in Ruby and Clojure Occasional consulting on Agile Writing /Functional Programming for the Object-Oriented Programmer/: https://leanpub.com/fp-oo -- You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en
Re: monads
On Fri, 2012-10-26 at 09:06 -0700, Brian Craft wrote: First, do monads provide a generic solution, so I can apply f(g(h(x)))? Yes. control.algo.monads provides it as m-chain. The closest equivalent to m-chain in Haskell is (foldl' (=) return), but in most situations you would favor f = g = h x for your example, or more compositionally (f = g = h) x. Second, is it the whole point of monads to use macros so you don't see the glue functions, like s(), in my example? I mean, we can always write glue functions so we can compose functions with different input/output types without using monads. We can always write things out explicitly instead of exploiting existing abstractions. As for macros, the above samples use ordinary Haskell function calls. -- Stephen Compall ^aCollection allSatisfy: [:each | aCondition]: less is better than -- You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en
Re: monads
On Fri, Oct 26, 2012 at 8:39 PM, Stephen Compall stephen.comp...@gmail.com wrote: On Fri, 2012-10-26 at 09:06 -0700, Brian Craft wrote: First, do monads provide a generic solution, so I can apply f(g(h(x)))? Yes. control.algo.monads provides it as m-chain. Can you expand on this? If the functions are f :: a - b g :: c - d h :: e - j [renamed from f] and you'd like to chain [them] like f(g(h(x))), but you can't because b is a different type from c and d is a different type from e., how does m-chain help? I would have expected, given the b is a different type from c thing, that the chaining would go h(g(f(x)), but it's not as if that helps, unless the types work out like: b ~ m c d ~ m e in which case f = g = h :: a - j works fine (assuming j is a monadic value). But as a general matter I don't see how monadic composition solves the problem. -- Ben Wolfson Human kind has used its intelligence to vary the flavour of drinks, which may be sweet, aromatic, fermented or spirit-based. ... Family and social life also offer numerous other occasions to consume drinks for pleasure. [Larousse, Drink entry] -- You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en
Transients, pods, and monads
I finally found the time to watch the video recording of Rich's keynote at Clojure/conj. Lots of interesting stuff, as usual... When he started talking about transients and pods, I saw the term state monad flashing in the background. I suppose most people don't see, which is why I am writing this ;-) A pod is pretty much the same as a call of a state-monad command. Different pod policies translate to different variants of the m-bind function of the state monad. The transient is the state that is threaded through the sequence of commands. The state monad commands correspond to Rich's procs. Haskell uses variants of the state monad in much the same way as Rich uses pods: to make sure that mutable state is handled in a controlled way that ensures referential transparency for the outside world. If pods and transients make it into Clojure, that would be the third monad to be implemented in the core, after the identity monad (let) and the sequence monad (for). Which one is next? One advantage that would be obtained by using generic monad mechanisms instead of individually designed special cases for each monad is combinators for proce inside pods. There are probably many others. Konrad. -- You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en
Re: what stack traces include / exclude regarding monads
A domonad expression always boils down to a series of m-bind and m- result calls. That's its definition. You can check out my explanation of that here: http://www.clojure.net/2012/02/08/Doing-things/ As such, the stack traces become less helpful. I mostly rely on thinking about my monad expressions and well placed printlns for debugging. That and good unit tests. Jim On Feb 14, 1:00 pm, Andrew ache...@gmail.com wrote: I guess the use of domonads leaves behind do statements with m_bind's and m_result's... and since these expressions are not fn's, they don't count as method calls and are thus not part of the stack trace. But if I'm mistaken or if anyone has figured out how to use monads and still get detailed stack traces, please do let me know. -- You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en
Re: what stack traces include / exclude regarding monads
I guess the use of domonads leaves behind do statements with m_bind's and m_result's... and since these expressions are not fn's, they don't count as method calls and are thus not part of the stack trace. But if I'm mistaken or if anyone has figured out how to use monads and still get detailed stack traces, please do let me know. -- You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en
what stack traces include / exclude regarding monads
I've been experimenting with a state monad. Below is a list of what is included in my stack trace [+] and what isn't [-]. I've noticed that a call to a symbol that is bound to the result of a domonad (not sure if that's the right way to describe it) doesn't end up in my stack trace. I was planning on having a lot of things like that combined arbitrarily (see cc in the list below), but if they're not going to show up in stack traces (besides calls to m_bind -- which are not informative since they're always going to be on the same line), then that makes it tough to debug... Can I do something to cause my stack trace to include them somehow? Thanks in advance! [+] call to aa, an ordinary method whose body is (bb {}) shows up in the stack trace naturally. [-] bb is excluded from the stack trace. It is defined to be synonymous with symbol cc with (def bb cc). Of course, I don't expect this to be in the stack trace since it's not a method call. But I did include it as part of poking my stack trace. [-] cc is excluded from the stack trace. It is bound to the result of a state-m domonad: (def cc (domonad state-m My thinking (which appears to be incorrect) is that this definition of cc should be equivalent to (def cc some fn which takes a state and returns [value new-state]) which I thought would be like a defn and thus would show up in a stack trace when called. [+] dd is a monadic value that's used inside cc (inside the domonad part). So dd is a fn that takes a state and returns [value new-state]. dd shows up in the stack trace when called. [+] ee is an ordinary method called by dd. ee shows up in the stack trace. -- You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en
Re: what stack traces include / exclude regarding monads
Here's the code if the list in the original post was too cryptic. None of the items beginning with cc show up in the stack trace by name -- m_bind shows up instead. (defn ee [] (show-stack)) (def dd (fn [s] [ (show-stack) s])) (def cc2 (with-monad sim-m (domonad [_# dd] 4))) (def cc1 (with-monad sim-m (domonad [_# cc2] 5))) (def cc (with-monad sim-m (domonad [_# cc1] 6))) (def bb cc) (defn aa [] (bb {})) -- You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en
Re: Do you use Monads in your real clojure applications
On 01/04/2012 03:05 AM, Takahiro Hozumi wrote: In MVC pattern, Model should take responsibility for business logic. Therefore I write validate function for creating in the model. If creating a instance of the model should be safe, I must validate a parameter in the create function. My problem is that a controller have to validate a parameter twice in the validate function and the create function. Ring handler example (defn handler [{:keys [params] :as req}] (if (person/valid? params) {:status 200 :body (json/generate-string (person/create params))} {:status 400})) I think this might be suited to monads, which I don't fully understand. If you work with self-imposed restrictions that make you call functions with the same parameters twice in short order, you should reconsider those restrictions. If all the information you need from a validator is true/false, you can just call a model function. One that is written under the assumption that a certain requirement is met, before it is called. If the validator returns nil or some concrete piece of imformation, you just need to call it, store the result. Then you may call a model function with the result (if it is non-nil). Moustache makes that very straightforward: (defn integer [s] returns nil if s does not represent an integer (try (Integer/parseInt s) (catch Exception e))) (app [order [id integer]] my-handler) ; for /order/134 @id@ will be bind to 134 (not 134), this route will not match /order/abc. Example taken from https://github.com/cgrand/moustache -- Thorsten Wilms thorwil's design for free software: http://thorwil.wordpress.com/ -- You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en
Re: Do you use Monads in your real clojure applications
Hi, Am 04.01.2012 um 10:12 schrieb Thorsten Wilms: (defn handler [{:keys [params] :as req}] (if (person/valid? params) {:status 200 :body (json/generate-string (person/create params))} {:status 400})) Or you let the create function return nil on invalid params. (defn handler [{:keys [params] :as req}] (if-let [p (person/create params)] {:status 200 :body (json/generate-string p)} {:status 400})) Sincerely Meikel -- You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en
Re: Do you use Monads in your real clojure applications
Thanks to all authors for help. Best regards, Dragan Radevic -- You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en
Re: Do you use Monads in your real clojure applications
Thank you for your great answer Konrad. On Jan 3, 9:46 am, googlegro...@khinsen.fastmail.net wrote: Dragan R writes: On the net I read that Impure functional programming doesn't really need monads. and It appears that in the presence of mutable state, a lot of the advantages of monads become moot. Monads are an abstraction mechanism, so you never need them. You can always use the lower-level techniques in terms of which monads are implemented. The only language that has made monads nearly inevitable is Haskell, because its standard library is based on monads. But even in Haskell, monads can be avoided, at the cost of rewriting stuff that is already in the standard library. As with all abstractions, the real question is not whether you need them, but whether their use improves your programs. This depends as much on the programmer as on the problem, so there is not clear answer. As a rule of thumb, I'd say that you should consider using monads if your application 1) can profit from more than one of them, or 2) can profit from the generic monad operators. I probably use monad more than the average programme in my own code, but that's also because I happen to be familiar with them. I could very well live with fewer monads in my code. But once you know monads, they appear magically everywhere you look ;-) Konrad. -- You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en
Do you use Monads in your real clojure applications
Dragan R writes: On the net I read that Impure functional programming doesn't really need monads. and It appears that in the presence of mutable state, a lot of the advantages of monads become moot. Monads are an abstraction mechanism, so you never need them. You can always use the lower-level techniques in terms of which monads are implemented. The only language that has made monads nearly inevitable is Haskell, because its standard library is based on monads. But even in Haskell, monads can be avoided, at the cost of rewriting stuff that is already in the standard library. As with all abstractions, the real question is not whether you need them, but whether their use improves your programs. This depends as much on the programmer as on the problem, so there is not clear answer. As a rule of thumb, I'd say that you should consider using monads if your application 1) can profit from more than one of them, or 2) can profit from the generic monad operators. I probably use monad more than the average programme in my own code, but that's also because I happen to be familiar with them. I could very well live with fewer monads in my code. But once you know monads, they appear magically everywhere you look ;-) Konrad. -- You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en
Re: Do you use Monads in your real clojure applications
Hi, I used monads in two projects. * The last rewrite of ClojureQL before v1.0 used a state monad to keep track of various things during query creation. * ClojureCheck also uses a monad approach to create and combine generators for test data. * Dave Ray and I tried a monad style in the async branch of seesaw. Both were custom monad implementations. Both work(ed) reasonably well. However things have a relatively high strangeness factor. Since the execution of things is deferred till someone actually runs the monad pipeline, you can't use your usual try/catch construct to take care of problems. Everything has to be constrained to your monadic function. So you need to have some way to error out of your monadic pipeline. This leads you to monad transformers and complicates things even more. In Clojure I haven't seen a use were other approaches weren't just as feasible or were monads would have simplified things. They are a legal approach, but I would judge on a case-by-base basis. Sincerely Meikel -- You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en
Re: Do you use Monads in your real clojure applications
On 3 January 2012 08:46, googlegro...@khinsen.fastmail.net wrote: Dragan R writes: On the net I read that Impure functional programming doesn't really need monads. and It appears that in the presence of mutable state, a lot of the advantages of monads become moot. Monads are an abstraction mechanism, so you never need them. You can always use the lower-level techniques in terms of which monads are implemented. This +1. You need to be more specific about what you mean when you say code uses monads. In one sense, any code which uses a 'for' sequence comprehension is using a monad, because it satisfies all of the properties of a monad. In another sense, only code which contains and names specific things as monads, and uses general operators which apply to all monads, is using them. I've been using monads a lot recently with Overtone -- by which I mean I've been using (state-t cont-m), the continuation monad transformed to add state. I'm using it because: a) I want to simulate state representing the current beat number, and b) I want to schedule future events using apply-at; so rather than returning from a function to continue a melody, I call apply-at and pass the current continuation to it. As an example of what I've achieved, see this gist: https://gist.github.com/1441831 Using clojure.algo.monads, I have created a basic DSL which allows me to say (wait 1) to pause for one beat, and (at-current-beat (foo)) to schedule event (foo) to happen on the current beat. These commands are relative to the current time, but using monads I can transform them into commands at an absolute time using overtone's built-in 'at and 'apply-at macros, and to automagically handle the scheduling. This is a work in progress; I'm planning a fuller write-up of what I'm doing which I will send to the overtone list once I've ironed out the wrinkles. Phil -- You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en
Re: Do you use Monads in your real clojure applications
We use monads within one of our work project, but not to any large amount. It mostly boils down to using the Maybe monad to avoid giant nested if- lets. - Lee Hinman -- You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en
Re: Do you use Monads in your real clojure applications
On Jan 3, 2:46 am, googlegro...@khinsen.fastmail.net wrote: I probably use monad more than the average programme in my own code, but that's also because I happen to be familiar with them. I could very well live with fewer monads in my code. But once you know monads, they appear magically everywhere you look ;-) Big +1 to that. I've submitted a talk to ClojureWest that partly touches on how to use monads in Clojure. Basically, monads are like design patterns for writing DSL's. Other than that, while they don't let you do anything you couldn't do in other ways, I really like how they eliminate the need for dealing with state held in symbols. I've found that testing is easier and code is cleaner using them. For instance, I showed how a state monad could be used in Chris Granger's Korma library. https://github.com/ibdknox/Korma/pull/35 Jim -- You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en
Re: Do you use Monads in your real clojure applications
Some of the most common uses for monads have pre-existing mechanisms with Clojure to handle them, e.g.: sequence monad (for) state monad (Clojure has many stateful mechansisms) maybe monad (Clojure programmers usually just return nil for failure, and use something like when-let to process it) In terms of higher-level DSLs constructed out of monads, the most useful monadic frameworks I've seen are monads for parsing, and monads for representing probability distributions. If I needed to do one of those things in Clojure, I'd look closely at monad options. But since I haven't needed to do those things, and the common uses for monads are already covered, I haven't found a need to do any monadic style programming in my own code. --Mark -- You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en
Re: Do you use Monads in your real clojure applications
In MVC pattern, Model should take responsibility for business logic. Therefore I write validate function for creating in the model. If creating a instance of the model should be safe, I must validate a parameter in the create function. My problem is that a controller have to validate a parameter twice in the validate function and the create function. Ring handler example (defn handler [{:keys [params] :as req}] (if (person/valid? params) {:status 200 :body (json/generate-string (person/create params))} {:status 400})) I think this might be suited to monads, which I don't fully understand. On Jan 4, 4:35 am, Mark Engelberg mark.engelb...@gmail.com wrote: Some of the most common uses for monads have pre-existing mechanisms with Clojure to handle them, e.g.: sequence monad (for) state monad (Clojure has many stateful mechansisms) maybe monad (Clojure programmers usually just return nil for failure, and use something like when-let to process it) In terms of higher-level DSLs constructed out of monads, the most useful monadic frameworks I've seen are monads for parsing, and monads for representing probability distributions. If I needed to do one of those things in Clojure, I'd look closely at monad options. But since I haven't needed to do those things, and the common uses for monads are already covered, I haven't found a need to do any monadic style programming in my own code. --Mark -- You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en
Do you use Monads in your real clojure applications
Hello, I would like to know do you use Monads in your real clojure applications, and are monads realy useful in impure functional languages like clojure? On the net I read that Impure functional programming doesn't really need monads. and It appears that in the presence of mutable state, a lot of the advantages of monads become moot. ( sources: http://www.reddit.com/r/programming/comments/p66e/are_monads_actually_used_in_anything_except http://marijnhaverbeke.nl/monad.html ) so I am interesting to hear what clojure programmers think about that. Thanks in advance for your help. Best regards, Dragan Radevic -- You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en
Re: Do you use Monads in your real clojure applications
On Mon, 2012-01-02 at 05:18 -0800, Dragan R wrote: and are monads realy useful in impure functional languages like clojure? Clojure's impurity doesn't mean that we wouldn't like to avoid side-effecty ways of doing stuff. Monads can help you there, among other things. The monad idea captures a very high-level abstraction, giving you the stuff that is implemented on that idea for free. For example, if you want an idea of `map' for your data structure, you'll get m-fmap if you write a monad instance. Some of this stuff seeps into more commonplace operators. `for' is essentially a sugary and faster `domonad sequence-m'. Likewise, the terribly useful `-?' from core.incubator is much like `((with-monad maybe-m (m-chain [...])) start)'. That said, Haskell-style evaluation and type inference does make them more useful and easier to use. I would like to know do you use Monads in your real clojure applications, Aside from `-?' and `for', I've implemented one custom monad instance for a production Clojure application. No doubt some of the stuff I've done with dynamic vars would have been cleaner with the reader monad; https://github.com/straszheimjeffrey/The-Kiln will, I think, be a good use case for the reader monad when it's ready. -- Stephen Compall ^aCollection allSatisfy: [:each|aCondition]: less is better -- You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en
Re: Do you use Monads in your real clojure applications
Midje has some of its error handling code implemented with a monad. https://github.com/marick/Midje/blob/master/src/midje/error_handling/monadic.clj#L32 `error-let` is like a regular let, except if there is a validation-error, that error short-circuits out. Alex -- You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en
Re: Errors w/ dynamic symbols in macro-utils or monads?
Does this still happen for you? It appears to still be the case in my environment. Dropping back to Clojure *1.2.1* seems to work but in addition to trying out monads, I need to use a library (clj-webdriver) that relies on Clojure *1.3.0* What to do? -- You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en
Re: Errors w/ dynamic symbols in macro-utils or monads?
ah: http://dev.clojure.org/display/design/Where+Did+Clojure.Contrib+Go clojure.contrib.monads - Migrated to clojure.algo.monads - lead Konrad Hinsenhttp://dev.clojure.org/jira/secure/ViewProfile.jspa?name=khinsen . - Status: latest build statushttp://build.clojure.org/job/algo.monads-test-matrix/, latest release on Mavenhttp://search.maven.org/#search%7Cga%7C1%7Cg%3A%22org.clojure%22%20AND%20a%3A%22algo.monads%22, report bugs http://dev.clojure.org/jira/browse/ALGOM. -- You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en
Re: monads macros
On 12 Jul 2011, at 23:18, Alan Malloy wrote: On Jul 12, 12:01 pm, Konrad Hinsen konrad.hin...@fastmail.net wrote: The composability issue with macros lies in writing them, not using them. Strongly disagree. Macros compose reasonably well when writing them (eg, using let in the implementation of with-open is trivial); it's That's not composition, that's use. What I mean by composition is writing a complex macro in terms of simpler macros and macro composers, just as one writes complex functions in terms of simple functions and higher-order functions. There is no equivalent of higher- order functions in the macro universe, for example. composing already-written macros with other pieces of your codebase that's hard. (reduce and xs) won't test that every element of xs is truthy, because and is a macro and thus can't be used as a higher- order function. That's exactly the kind of problem I was thinking of. So in fact we agree, except for the label to put on the problem. Konrad. -- You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en
Re: monads macros
On 13 Jul 2011, at 05:04, Ken Wesson wrote: One approach that has been proposed to improve composability of macros is to adopt a continuation-passing style. This would make macros a candidate for the continuation monad, so perhaps monads may be of use in implementing complex macros. That popcorn-popping sound you hear is heads exploding out there in the audience. Maybe this article will help understand what I was referring to - noting that this is for Scheme and not Clojure: http://okmij.org/ftp/papers/CPS-Macros.ps.gz Konrad. -- You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en
Re: monads macros
On Wed, Jul 13, 2011 at 7:19 AM, Konrad Hinsen konrad.hin...@fastmail.net wrote: On 13 Jul 2011, at 05:04, Ken Wesson wrote: One approach that has been proposed to improve composability of macros is to adopt a continuation-passing style. This would make macros a candidate for the continuation monad, so perhaps monads may be of use in implementing complex macros. That popcorn-popping sound you hear is heads exploding out there in the audience. Maybe this article will help understand what I was referring to - noting that this is for Scheme and not Clojure: http://okmij.org/ftp/papers/CPS-Macros.ps.gz Oh, I'm not saying my own is exploding -- just that macros can be tough for some people to get their heads around, and monads even more so, so combining the two ... -- Protege: What is this seething mass of parentheses?! Master: Your father's Lisp REPL. This is the language of a true hacker. Not as clumsy or random as C++; a language for a more civilized age. -- You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en
Re: monads macros
On Wed, Jul 13, 2011 at 5:20 AM, Ken Wesson kwess...@gmail.com wrote: Oh, I'm not saying my own is exploding -- just that macros can be tough for some people to get their heads around, and monads even more so, so combining the two ... maybe call them something else and it won't be so bad. when people see the need for something, they are generally willing to pursue it and learn it, i think. the people using clojure are probably somewhat self-selectingly smart enough ;-) as long as you don't call them monads ha ha. -- You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en
Re: monads macros
On Wed, Jul 13, 2011 at 1:37 PM, Raoul Duke rao...@gmail.com wrote: On Wed, Jul 13, 2011 at 5:20 AM, Ken Wesson kwess...@gmail.com wrote: Oh, I'm not saying my own is exploding -- just that macros can be tough for some people to get their heads around, and monads even more so, so combining the two ... maybe call them something else and it won't be so bad. when people see the need for something, they are generally willing to pursue it and learn it, i think. the people using clojure are probably somewhat self-selectingly smart enough ;-) as long as you don't call them monads ha ha. I'd probably be more insulted by being called macro. -- Protege: What is this seething mass of parentheses?! Master: Your father's Lisp REPL. This is the language of a true hacker. Not as clumsy or random as C++; a language for a more civilized age. -- You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en
monads macros
I'm mildly concerned about macros being seen as the secret weapon of clojure(/lisp). In their place, i wish monads would get a wider attention and embrace. Discuss? :-) -- You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en
Re: monads macros
Are monads all that special? My understanding is that even in Haskell its wise to not use monads all that much, since it starts to make the code look a little too imperative if not wielded correctly. They're not really the meat of haskell/fp. Macros on the other hand are an important part of lisp, although their overuse is also discouraged :) On Tuesday, July 12, 2011, James Keats james.w.ke...@gmail.com wrote: I'm mildly concerned about macros being seen as the secret weapon of clojure(/lisp). In their place, i wish monads would get a wider attention and embrace. Discuss? :-) -- You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en -- You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en