Monads: Easy or Hard?

Executive summary: they are actually both (or neither). It is easy to learn their definition but hard to grasp the consequences. Or we might say they are easy to know and hard to understand (grok). It is vitally important for both teachers and learners to understand and make this distinction.

Background

The plethora of monad tutorials (well-covered elsewhere) has been intimidating Haskell beginners for years. Beginners understandably assume that anything with over thirty wildly different tutorials must be very difficult to learn. Sadly, this attitude is a self-fulfilling prophecy: it is difficult to learn something which intimidates you, independently of its intrinsic difficulty.

Well-meaning members of the Haskell community have sometimes reacted by going to the other extreme, assuring beginners that monads are actually quite easy, and there’s no reason for all the hype. Unfortunately, this can backfire: if someone is really convinced that monads are easy, they are going to be in for a demoralizing shock.

Both attitudes, however, are wrong! The key is to reject the dualistic easy/hard distinction and replace it with something more nuanced.

Profundity

Monads are not hard; they are not easy; so what are they? They are profound. By this I mean that they have very large implications relative to the size of their definition. Here are some examples of other things that are profound in the same sense:

  • Board games like checkers, chess, go, and hex. It takes only a few minutes to learn the rules of these games, yet knowing the rules and being a good player are completely different. The simple rules of these games have many nontrivial and nonobvious "emergent" properties—which, of course, is what makes the games so interesting.

  • The lambda calculus, and Turing machines. Explaining how these work takes all of 30 minutes. Studying the implications, of course, has spawned multiple fields of active research.

  • Algebraic theories like group theory or category theory. Anyone with only a basic mathematical background can be taught the axioms of a group or a category. But, of course, these particular sets of axioms give rise to incredibly rich structure.

Thankfully, monads (as they arise in Haskell) are much less profound than these examples! But I think the analogy is correct. Understanding the definition of monads is simple: a monad is any type m of kind * -> * which supports the operations

return :: a -> m a
(>>=)  :: m a -> (a -> m b) -> m b

subject to some laws. But to really grok all the consequences—common example instances and how they are implemented and used; the relationship to Functor, Applicative, and Monoid; the relationship to the alternative definition in terms of join; all the common combinators like sequence, mapM, (>=>), etc.; and, in the end, to get some sort of intuitive sense for what the monad abstraction is really like—all that takes a long time and a lot of hard work!

Implications for pedagogy

So what does this all mean, practically speaking?

If you are learning about monads: take heart! There is a simple, easily accessible foundation from which to get started, namely, the definition of the Monad type class. Study the Monad methods and their types—and come back to this basic foundation whenever you get confused. But also realize that to gain deep understanding will take hard work over a relatively long period of time.

If you are teaching others about monads: encourage those who are intimidated—but don’t go overboard. Keep directing students back to the fundamental definition, but also provide them with many opportunities to engage with examples. (There is something else important here—examples of implementing monads are on a very different level than examples of using them, and in my experience it’s vitally important that students are explicitly taught to think about the two levels and keep them separate—but that’s a subject for another post.)

Postscript

There’s probably nothing here that hasn’t been said by someone somewhere before, and it seems rather obvious now that I have written it, but I really do think this perspective is sometimes missing from the discussion of pedagogy and Haskell. This perspective really crystallized for me as I was teaching an introductory Haskell course last spring.

Of course, this is much in the same vein as my previous post Abstraction, intuition, and the “monad tutorial fallacy”. I still believe what I wrote there, except for one thing: that post makes it seem like it is possible to have a sudden "aha!" moment where one goes from not understanding monads to understanding monads. I now realize this is wrong, just like no one suddenly goes from "not understanding chess" to "understanding chess". The learning process is simply discontinuous; learners often experience big, sudden jumps in comprehension, and it’s easy to interpret these jumps as going from "not understanding" to "understanding". Immediately after making such a jump, it’s easy to believe that one had no prior understanding at all (which is probably not true), and that there’s nothing more to understand (which is certainly not true).

As a final note, I’ve specifically discussed monads here, but of course everything I’ve said applies to many other concepts as well, such as Applicative, continuations, GADTs, iteratees/pipes/conduits, and so on. I’d love for this to spark more explicit, thoughtful discussion of pedagogy in the community, and not just around monads.

Posted in haskell, learning, teaching | Tagged , , , | 4 Comments

Diagrams mentoring at Hac Phi

Hac Phi is coming up in less than a month, August 3-5 here in Philadelphia: three days of hanging out with awesome people, eating good food, and hacking on Haskell projects. Judging by past instances, I promise you it will be super fun, whether you just started programming in Haskell yesterday or have been for twenty years.

In case you need some extra encouragement and the diagrams project sounds interesting to you, let me explicitly state that if you attend Hac Phi and want to help with the diagrams project, I will personally sit down with you at least once, more likely multiple times, over the course of the weekend and walk through code with you, do some pair programming, whatever is appropriate to get you to the next level of productivity with diagrams and/or Haskell. This applies no matter how much experience you have with diagrams or with Haskell—from absolutely none to quite a lot.

In fact, I would be perfectly happy to spend the entire weekend mentoring others and writing not a single line of code myself. Over the years I have learned that when it comes to a big project like diagrams, fostering collaboration is actually the most important aspect of a hackathon, rather than getting a bunch of coding done myself—I can always go pound out code at home once everyone has left.

So, if that sounds like fun to you, be sure to register (registration closes in a little under two weeks), and let me know you’re coming. I’m also happy to discuss concrete ideas for diagrams-related projects.

Posted in diagrams, haskell, projects | Tagged , , | 3 Comments

BlogLiterately 0.5 release

I have now released version 0.5 of BlogLiterately. (You can read about the 0.4 release here.) This version does uploading of images! Here is proof:

d’awww.

(My previous post explains the problem and solution with image uploads.)

It also allows you to specify expected outputs in a ghci session (a feature suggested by Dan Burton). This block

    [ghci]
    7+6
      13
    9+4
      12

now produces

ghci> 7+6
  13

ghci> 9+4
  13
  12

Outputs that match the expected output are shown normally; outputs that don’t match the expected output are shown with the actual output in red and expected in blue. The idea is that this helps you catch errors in your code before uploading the post. (Of course, you don’t have to specify expected outputs if you don’t want to.)

Another new feature is that BlogLiterately will prompt you for your password if you don’t specify it on the command line (another feature requested by Dan).

Finally, one of the coolest new features (in my opinion) is that the internals are now exposed as a library, and in particular you can easily add your own custom transformation passes (of type Pandoc -> IO Pandoc) to the existing ones. So, for example, you could do something particular with your own specially tagged blocks (like [ghci] blocks), or wrap images in some fancy HTML to produce frames and captions, or automatically turn certain things into links, or whatever you can dream up. If you come up with any transformations you think might be more generally useful, please send them to me so I can include them in future releases for others to use.

Happy blogging!

Posted in haskell, writing | Tagged , , , , , | 3 Comments

New haxr release

I have just uploaded a new version of the haxr package (for writing XML-RPC clients and servers), having become the new maintainer. Here is how it happened.

In a previous post I announced the release of BlogLiterately 0.4, a tool for authoring and uploading blog posts. I mentioned that the image upload feature did not yet work, due to inexplicably closed HTTP connections. After a lot of digging, installing wireshark, and some excellent advice and answers from StackOverflow, I present to you the following basically-technically-accurate transcript of what was actually going on:

BlogLiterately: Hi there!!
Server: Hello. How may I help you?
BL: I would like to upload some data plz kthx!
S: OK, go ahead.
BL (thinking to self): Oh sh**, I haven’t actually computed the data I want to send! Better get started. Hrmrmrmrmmmmm….

…four seconds later…

BL: ..i thunk i can i thunk i can i thunk i can…
S: You are wasting my time. I have better things to do. Goodbye.
BL: …i thunk i can i thunk i can… done!
BL: OK, I’m ready now! data data data data data data data data data …
S: AUUGGH SHUT UP GO AWAY

So the surface problem seemed to be too much laziness, and indeed, forcing evaluation of the data prior to opening the HTTP connection did make it work. However, the deeper problem is that base64-encoding a 28k image should not take four seconds! Indeed, it turned out that haxr was using dataenc to do base64-encoding, which suffered from quadratic runtime due to left-nested list appends. After switching to base64-bytestring, the encoding now takes basically no time at all.

The other change I made to haxr was in the type of the ValueBase64 constructor of the Value type. It used to take a String, but this is silly, since the argument is supposed to represent binary data (which will then be base64-encoded), not text. In the original author’s defense, haxr was written before ByteString existed! But now that we have ByteString, I made it the argument to ValueBase64. This means fewer conversions (in order to provide a String containing binary data, one byte per character, you basically have to read the file as a ByteString in the first place anyway and then unpack it), and also has the nice side benefit of being able to add a new XmlRpcType instance for ByteString, so that ByteStrings can be passed directory to remote, resulting in a base64 parameter. (Previously, to distinguish a base64 parameter the only way was to explicitly wrap it in a ValueBase64 constructor.)

After a bit of discussion about these issues with Gracjan Polak, haxr‘s previous maintainer, he suggested that I take it over since he wasn’t really using it anymore. I’m grateful to Bjorn Bringert (haxr‘s original author) and Gracjan for their work on haxr over the years.

And yes, this does mean that BlogLiterately now supports image uploads—and also a few other new features I’ve added in the meantime. A new release will follow shortly!

Posted in haskell | Tagged , , , , | 2 Comments

BlogLiterately 0.4 release

I have just released version 0.4 of BlogLiterately, a tool for authoring and uploading blog posts (especially Haskelly ones). Rob Greayer authored the first few versions of this useful tool, for which I’m very thankful. However, he doesn’t have the time or interest to maintain it anymore, and I had a few ideas for extending and improving it, so I offered to take over as the maintainer.

The full (dog-fooded) documentation can be found here. This blog post is just to announce the release and show off a few capabilities.

Posts are written in Markdown format (as recognized by pandoc), and BlogLiterately handles converting them to HTML and uploading them to any blog that supports the MetaWeblog API (such as WordPress). Haskell code can be syntax highlighted using hscolour (and any code can be syntax highlighted using highlighting-kate):

> -- An awesome Haskell function
> fib :: Integer -> Integer
> fib 0 = 0
> fib 1 = 1
> fib n = fib (n-1) + fib (n-2)

Special support for WordPress LaTeX is built in: \pi^2 / 6. ghci sessions can be automatically generated from a list of inputs:

ghci> fib 20  
  6765

ghci> [1..10]  
  [1,2,3,4,5,6,7,8,9,10]

The one major planned feature that is still missing is uploading of embedded images. Sadly, this feature ran into a major roadblock in the form of inexplicably closed HTTP connections (can you help answer my StackOverflow question?). Ultimately my goal is to have completely automated support for writing blog posts with inline diagrams code.

Enjoy!

Posted in haskell, writing | Tagged , , , | 9 Comments

Unsubscribing from Wolfram emails (rant)

I have been getting a bunch of emails from Wolfram and decided I wanted to unsubscribe.  No problem, right?  I’ll just scroll to the bottom of the email and click the…

To view our privacy policy, click here:
http://www.wolfram.com/legal/privacy/wolfram-research.html

To update your email, click here:
http://www.wolfram.com/emailchange

…the, uh… hmm. Well, maybe unsubscribing is included in “updating one’s email”? I click on that.

Nope. OK, let’s try “privacy policy”.

Aha, now we’re getting somewhere! I click on “unsubscribe”.

Posted in humor | Tagged , , , | 3 Comments

Announcing diagrams 0.5

I am pleased to announce the release of version 0.5 of diagrams, a full-featured framework and embedded domain-specific language for declarative drawing. Check out the gallery for examples of what it can do!

Naive fibonacci call tree

Highlights of this release include:

  • A new diagrams-contrib package of user-contributed modules, which so far contains code for tree drawing, Apollonian gaskets, planar tilings, "wrapped" layout, and turtle graphics.
  • Experimental support for animation, built on top of the new active library.
  • Numerous small additions and improvements, including more general rounded rectangle shapes and better text support.
  • Much better performance in some common situations, such as laying out a very long list of diagrams using ‘cat’ and related combinators.
  • Added support for GHC 7.4.

See the release notes for complete details, and the diagrams wiki for help migrating code from 0.4 to 0.5 (changes should be minimal).

Try it out

For the truly impatient:

cabal install gtk2hs-buildtools
cabal install diagrams

Diagrams is supported under GHC 6.12, 7.0, 7.2, and 7.4. However, getting cairo to build can be tricky on some platforms; see the diagrams wiki for more information and workarounds regarding specific platforms. (A new native SVG backend is in the works, targeted for the 0.6 release.)

To get started with diagrams, read the quick tutorial, which will introduce you to the fundamentals of the framework.

For those who are even less impatient but want to really dig in and use the power features, read the user manual.

Get involved

Subscribe to the project mailing list, and/or come hang out in the #diagrams IRC channel on freenode.org for help and discussion. Make some diagrams. Fix some bugs. Submit your cool examples for inclusion in the gallery or your cool code for inclusion in the diagrams-contrib package!

Happy diagramming!

Brought to you by the diagrams team:

  • Peter Hall
  • Ian Ross
  • Michael Sloan
  • Ryan Yates
  • Brent Yorgey

with contributions from:

  • Sam Griffin
  • Claude Heiland-Allen
  • John Lato
  • Vilhelm Sjöberg
  • Luite Stegeman
  • Kanchalai Suveepattananont
  • Scott Walck
Posted in diagrams, haskell, projects | Tagged , , , , | Leave a comment