Is There Anybody Out There?
I have met thousands of people in my life. Of all those people, each can be described in one of four ways:
- The person understands monads and would never, without duress, use an imperative programming language
- The person does not understand monads, would like to and has embarked on doing so in some form
- The person does not understand monads and would not like to (my doctor for example)
- The person does not understand monads and in an attempt to do so, has created erroneous simplifications since “not knowing” should be defended at all costs - even if it implies the creation of a false and somewhat convenient reality
I implore any person not to fall into the latter category, but I do understand that this imploration is based on my value system, which has a strong emphasis on the philosophy of epistemology. If the phrase, “ignorance is bliss” (without the negative connotation), is valuable to you, then so be it. I am also very keen to know of any persons who cannot be described this way, but to date, I have found none.
My school friends were sad when they found out that Santa Claus was not real - I was angry.
December 1st, 2006 at 12:04 pm
Hope you don’t mind me replying to everything..
I understand monads, and still use an imperative programming language, so that’s none of your 4. However, they’ve taught me (or rather, confirmed) that I really should strongly separate state from stateless. I might even go so far as to make them be in completely separate packages or sub-projects.
I have a tree of mainly mutable objects in my IP network simulator, and I’m gradually working through, making them immutable. In Java terms, that seems to be using Sequences (my own immutable LinkedList equivalent, based on Haskell’s lists) and avoiding any classes having fields. No, really. If a class has a final field, that can be declared as a local variable in the method the class is contained in. Yes, that means my instantiable classes are anonymous classes.
I strongly recommend reading Tackling the Awkward Squad, by Simon Peyton Jones, of Microsoft (yes, *that* Microsoft, are you listening, Spolsky?) - http://research.microsoft.com/~simonpj/papers/marktoberdorf/
December 1st, 2006 at 9:41 pm
You left out #5 - The person has no idea what you are talking about but is curious what you’re on about
and
#6 - The person has no idea what you are talking about but doesn’t really care.
If the post was an intentional echo chamber, ignore this. If you want to spread the word about monads, explaining them, however briefly, would go a long way to turning #5s into #2s.
I’m just saying.
December 5th, 2006 at 10:22 pm
Hi Ricky,
Note I mentioned “would never use an imperative language without duress”. I don’t think you’d be understanding monads and using an imperative language voluntarily or without some other agenda. In any case, you point out “separate state from stateless”. This is an unfortunate and common misunderstanding of monads, since they have nothing (if at all) to do with this.
It is common (I believe) because most Haskell beginners are first introduced to the IO monad - from which they extrapolate their understanding of monads. The IO monad is a poor example of a monad and I discourage it for use in demonstrating monads to a beginner (but not necessarily IO). Likewise, I emphasise once more that monads and “separating state from stateless” are orthogonal issues. It seems to also be a trend among “Lisp users who don’t quite understand Haskell” to somehow think that monads violate the property of referential transparency (is this because of a poor understanding of a poor example of a monad (IO)?)
This is a bit funny because two things occurred just today:
1) I had a similar conversation where someone tried to explain to me (and some people who were learning) that within the IO monad, “things” happen one after the other. Of course, we know that this is just a consequence of the nature of lazy evaluation, but nevertheless, this is related to what I think is your misunderstanding.
2) The Haskell Weekly Newsletter made a reference to the restricted IO monad.
Finally, once you make all your Java objects immutable and without any updates (even local ones), I would be interested to see what will happen on the Sun VM - in fact, I can conjecture
given the status of that “years old RFE”. I’ve been following that one ever since and it is encouraging to see your communication with former Java compiler authors who suggest that it might happen, but you’ll excuse me for being a skeptic given the past record.
December 5th, 2006 at 10:28 pm
Hi Tom,
I think my #3 encompasses your #5. For example, if you do not understand monads and you are curious, this would mean that you have embarked on finding out, just by the act of expressing curiosity - even if it is extremely low on your priority list to take it any further. I also think my #4 encompasses your #6 - I agree, there are many people who do not know or care - the example I gave was my doctor who would fall into this category - after all, he is a doctor.
I don’t think an explanation of monads on here is really necessary. There have been so many metaphorical examples flying past on http://programming.reddit.com/ lately that I think the issue is exhausted. I am also not creative enough, or more so, I struggle to sacrifice accuracy in my explanation by using these metaphors. That is, if I were to use a metaphor, the analogy is likely to be lossy and I cannot bring myself to do this.
If someone has read all those examples, applied, reflected and repeated to still make no progress, I really don’t know what I could do to alleviate this.
December 5th, 2006 at 10:40 pm
Ricky,
I thought you might be interested to see some work I did a while back. I think the following output should summarise it well. I also wrote some monads and functors over various types. I have also had a request to explain why the monadic operations cannot be generalised with Java’s type system, so I plan on doing that some time (soon? yeah right).
You will note the repeating function names that return F to provide for (poor man’s) partial application and that some of the (very meaningful) generic information is lost.
Here is some fun - ever counted how many design patterns[1] exist in GoF because the language(s) that it is using (despite erroneous claims to be entirely agnostic) does not provide partial application?
[1] Euphemism Alert!
$ javap FList Compiled from "FList.java" public final class list.FList extends java.lang.Object{ public static list.List append(list.List, list.List); public static F append(); public static list.List concat(list.List); public static F concat(); public static list.List cons(java.lang.Object, list.List); public static F cons(); public static maybe.Maybe cycle(list.List); public static F cycle(); public static maybe.Maybe drop(java.lang.Integer, list.List); public static F drop(); public static list.List dropWhile(F, list.List); public static F dropWhile(); public static list.List empty(); public static list.List filter(F, list.List); public static F filter(); public static java.lang.Object foldl(F, java.lang.Object, list.List); public static F foldl(); public static java.lang.Object foldr(F, java.lang.Object, list.List); public static F foldr(); public static maybe.Maybe head(list.List); public static F head(); public static maybe.Maybe index(java.lang.Integer, list.List); public static F index(); public static maybe.Maybe init(list.List); public static F init(); public static list.List inits(list.List); public static F inits(); public static list.List intersperse(java.lang.Object, list.List); public static F intersperse(); public static java.lang.Boolean isEmpty(list.List); public static F isEmpty(); public static list.List iterate(F, java.lang.Object); public static F iterate(); public static maybe.Maybe last(list.List); public static F last(); public static java.lang.Integer length(list.List); public static F length(); public static list.List map(F, list.List); public static F map(); public static list.List repeat(java.lang.Object); public static F repeat(); public static list.List reverse(list.List); public static F reverse(); public static list.List scanl(F, java.lang.Object, list.List); public static F scanl(); public static list.List scanr(F, java.lang.Object, list.List); public static list.List single(java.lang.Object); public static F single(); public static maybe.Maybe tail(list.List); public static F tail(); public static list.List tails(list.List); public static F tails(); public static maybe.Maybe take(java.lang.Integer, list.List); public static F take(); public static list.List takeWhile(F, list.List); public static list.List zipWith(F, list.List, list.List);