A few months back I was motivated to dive back into Haskell and, after surveying the recent landscape, picked up Haskell Programming from First Principles. It’s a book that promises a soup-to-nuts approach to Haskell, staring from the mathematical concepts underscoring the language (Lambda calculus) and moving through to a full-blown production-ready project. I’ve so far gotten a few chapters in, and, while I haven’t learned anything new, the authors’ approach to the basics – data types, constructors, etc – are fairly conversational and comprehensive, and they do a good job of answering the questions that arise naturally while reading. (I’ll ignore the likelihood that these same authors are leading into these questions, and answering them, to make me feel better about myself while reading. Why? Because it makes me feel better about myself, that’s why. Well done, authors!)
Reading through this book I reflected on my first runthrough of Learn You a Haskell For Great Good when it came out (iirc it was early 2013). My programming career hasn’t swerved headllong into functional programming; I’m coding Ruby now instead of the Python I was slinging back then, but these are still pretty apples-to-apples as far as languages go. I liked LYAHFGG a lot – it’s fun and thorough too – but while set comprehensions and string operations made sense, I wasn’t really making the jump from Python to typeclasses. The book that did help me crack into functional programming concepts was Functional Programming in Scala, not LYAHFGG. Here are some possible reflections why:
- Haskell syntax is very spare, rather like poetry to Scala’s prose; FPIS, by virtue of it’s medium, surrounds novel FP concepts with familiar programming syntax (ie extra parens and curlys). This may not matter to everybody, but it seems to have been a bridge I needed.
- Pattern matching, a concept at the core of Haskell’s type definitions, doesn’t really make sense in languages based on duck typing. Python and Ruby, lacking type constructors, can only can go as far offer some degree of tuple destructuring based on positional assignment. Scala and Haskell are solidly in the world of type constructor pattern matching, which is a vital concept on the road to understanding type classes.
- Guards, ‘where’, and 'let’ make sense to anybody with a discrete mathematics backrground, and 'expressions’ are familiar from languages like Lisp and Scheme, but none of these are that present prevalent in Python. Ruby does have stronger support for expression syntax (ie assigining an entire 'if’ or 'begin/rescue’ statement to a variable).
Some other random notes:
- The quicksort algorithm is the go-to for demonstrating Haskell’s declarative power, and the quicksort section in LYAHFGG does a great job showing that. Algorithms in Haskell translate cleanly from general computer sciance. They tend to be composed definitions, not recipes.
- I get that (+3) is a partial function adding 3 to whatever is passed in. I understand that it’s really (+) 3. But it’ll likely never be as clear to me as (\x -> x + 3), because that explicitness makes more sense. Once again, poetry vs prose.
- FPIS nailed home the constructor-pattern matching thing in a way that made sense to my Java-related brain.