I consider myself a “mostly functional” programmer. I
think about programs in terms of data flow and transformations and
mappings from input to output. I avoid side effects and mutable
state where it isn’t necessary. But I’m not a purist.
I’m happy to setf
an instance slot when it makes
sense.
Monads are the darling of the functional programming community. To hear it, they are the key to understanding the universe. They provide a way to encapsulate side effects and mutable state in a pure functional way.
But I don’t often use them.
There are a few reasons for this. I don’t work in Haskell, where monads are a ubiquitous part of the language. If you use Haskell, you’re going to use monads. But what about the languags that I do use? Monads of course “work” in any language that supports higher-order functions, but they are not always idiomatic or the obvious way to accomplish a task.
The primary use of monads is to mimic the look and feel of an
imperative language, with its sequential execution, side effects and
mutable state, in a language that is purely functional. Monads are
a way to implement progn
and setf
in
Haskell. But Lisp already has progn
and setf
.
And an imperative programming style is largely inferior to a
functional programming style. I prefer to not think imperatively
and write imperative code. I've seen many Haskell programs that
used monads just so they could use do
notation and
write code that looked like C. That seems like a step backwards.
Monads are complicated. They essentially come down to functional
composition of curried functions hidden behind some syntactic sugar.
So long as you don’t have to look under the hood, they are
reasonably easy to use. But when you do have to look under the
hood, you’ll find a maze of twisty, turny, higher-order
procedures. In Lisp, a well placed setf
can cut
through this functional Gordian knot.
No comments:
Post a Comment