Try the advanced stuff

January 5, 2020

I’m stumped about what things to learn. I really don’t know what concepts to prioritise.

Recently there’s been a lot of posts arguing that you don’t need to use the advanced features of Haskell. The problem is that many of them have strayed into arguing that that also implies that you should never (or very rarely) use the advanced features of Haskell, as if they’re something that newcomers to the language need to be protected from. Some examples of this line of argumentation are Marco Sampellegrini’s and Matt Parson’s recent posts.

I myself have argued that it’s possible to get “real stuff” done using fairly simple parts of the language. However, what I don’t agree with is this attitude that newcomers should be treated like skittish lambs, carefully herded away from any big bad type extensions lest they get scared and run away.

If you’re coming into the language and this is the sort of discourse you see around helping beginners, it can feel rather condescending; here you are, interested in seeing mind-blowing, otherworldly concepts make a real difference in writing better code. Instead, people are telling you to not touch any of it, like someone saying that you’re not smart enough or skilled to make sense of it. Come learn our language, but you have to go sit at the kid’s table.

If you’re someone coming to Haskell in the first place, you’re probably naturally curious and inquisitive. You’d rather have them be able to explain it to you, pros, cons, and all, so that you can make your own decision. You’re intelligent; it’s just that you don’t know where to start. And that’s okay.


The truth is that a lot of the concepts in the usual Haskell discourse aren’t really all that complicated individually. It’s just that there’s a lot of them, and as a newcomer, you have no idea what’s important and what’s not. It’s easy to get the feeling that it’s all necessary, pick one at random, get unlucky, and start going down the wrong rabbit hole. You’ve finished Learn You a Haskell, but you’re still not confident in writing practical code. And then you reach it: the sheer cliff edge dropoff of learning resources after the total beginner stuff. Do you try to work through Real World Haskell, or do you put your eggs in the Haskell in Depth basket, even though it’s not finished yet? Everyone you talk to acknowledges that right now everything is scattered across a bunch of different blog posts and tribal knowledge and says that the current situation isn’t great. Eventually you say “screw it” and have to pick something to try to learn. It turns out that what you picked isn’t a natural place to go after learning the fundamentals of the language, has terrible documentation, or both. You spend a week or two banging your head against the compiler, ending up with nothing but a useless set of code fragments that don’t typecheck. You come out the other end neither particularly enlightened nor particularly inclined to trust anything that Haskellers recommend to you. If you have one brain-melting like this that doesn’t lead anywhere, it’s easy to assume that everything will end up the same way. You get discouraged, you go spend your time doing something that feels less inimically futile.

That’s a real shame, because I don’t think that it needs to be this way. Just because some people have bad experiences with the Haskell learning curve doesn’t mean we should conclude that we need to truncate the learning curve entirely and remove anything which might frighten people. That’s like arguing we shouldn’t ever use power tools and instead only use screwdrivers and hammers, solely because power tools can cause much more gruesome injuries. Instead, we add safeguards and make it so that usage is explained well, we make power tools more intuitive and remove gotchas. In the same way, what we need is not a blanket ban on language features, what we need is to ease the path for people to figure things out for themselves. What we need is signposts, not roadblocks.

What’s needed isn’t coddling, it’s better foundations, ways to build up from the simpler stuff to the crazy tower of abstractions that Haskell provides. We need a gentle hiking path upwards; what we have instead is one that crumbles away into a steep rocky outcrop approximately around the end of Learn You a Haskell and monad tutorials. Lichen-spotted erratics dot the landscape, and one wrong step sends you careening down into the needle-straight pines far below. Some have climbed it anyways, suffering lacerations and gashes on their way up. Instead of putting a skull on the trailhead, why can’t we look back down and pave it so the way is clearer for everyone who comes after us? Write better documentation for the libraries we have.1 If you see people behind you on the trail, point them to the best places to go next. Don’t tell them to simply turn around and go back; we all came here for the same reason. One day our footfalls will be the teachers in our stead. The path we’ll end up will be longer and end up reaching a higher peak than the surrounding mountains. But so what? What matters isn’t the length, but the slope.

Still, for you the reader, you the intrepid climber, that doesn’t change the fact of how things are today. Perhaps someone in the future will be greeted by a dirt path instead of bare rock, but that gives no comfort to the present you.

So, my advice is this: first, don’t be scared of the concepts that get slung around in the typical Haskell dicussion, but please bear with us. A lot of them you’ll be able to figure out aren’t actually necessary for you, and a lot of others you’ll figure out aren’t actually that hard. Follow your curiousity where it leads you and try things out. At the same time, if something’s not making sense, don’t force it. Ask questions when you get stuck, but remember that a lot of concepts aren’t necessary immediately (or ever!) So don’t feel bad about putting something down if it’s not clicking, because chances are you won’t need it anyways. If learning it has helped you stretch your gray matter, it’s done its job. And if something ends up frustrating you, I hope that that won’t color your perception of the entirety of the language and community. Please trust that the things the Haskell community talks about all exist because someone was trying to solve a real problem, even if it’s not obvious how. Follow your nose and keep an open mind.

Second, as my own small way of paving the path upwards, here are some concrete recommendations for concepts to learn first, once you’re past the “total beginner” stage. I think the 3 things below are both relatively easy to pick up and will give you the biggest bang for your buck:

  • Foldable/Traversable
  • Semigroups/Monoids
  • Monad transformers

Found this useful? Still have questions? Talk to me!


Footnotes

↥1 If you really want to improve the state of documentation, one thing you could do is find well-used libraries and actually write documentation for them! Submit a PR so that everyone else coming along the same path will benefit as well.


Before you close that tab...