[Haskell-cafe] Callback functions?
Albert Y. C. Lai
trebla at vex.net
Mon Jul 2 20:49:48 EDT 2007
Hugh Perkins wrote:
> > What makes a callback different from any other kind of function?
> Well... what about inside monads? Does this break purity??? Does this
> require adding IO to the monad if the callback function does IO?
> As I'm writing this I kindof have this sense inside me that this is a
> really newbie-ish question. That the answer is no it doesnt break
> purity, yes it does require adding IO to the monad, but I'm asking
> anyway just to check :-)
The question exists only because of a cultural difference.
Let f, g be functions (actions, procedures, methods, subroutines...)
such that "f(g)" is legal and means f may invoke g.
Mainstream programmers say g is a callback function, f is a function
that accepts a callback function.
Functional programmers say f is a higher-order function, g is a function.
Its use is pervasive in functional programming and especially Haskell.
Already in the second or third lesson, one meets
map h [1,2,3]
foldl (+) 0 [1,2,3]
where map calls h, and foldl calls (+). It does not matter that all of
them are pure functions, since, in mainstream programming, g is still a
callback function whether pure or side-effecting, cf. qsort and bsearch
Some callback functions are intended to be side-effecting. To do IO
actions and handle exceptions, we write like
catch my_action my_handler
catch calls my_action; if an exception is raised, catch furthermore
calls my_handler. Thus my_action and my_handler are callbacks, and catch
is a higher-order function. This is remarkably different culturally from
mainstream programming: In mainstream programming, exception handling is
a special syntax, not a library function taking handlers as callbacks
(let alone the major action); in Haskell programming, exception handling
is just another higher-order function, not a special syntax.
It doesn't stop there. Whenever you write
do a <- m
which is desugared to
m >>= \a -> n a
the >>= is a function that calls m, then uses its return value to call
(\a -> n a). Thus m and (\a -> n a) are callbacks, and >>= is a
higher-order function. Sequential execution, the daily bread of every
imperative programmer, is yet another library function (this time even
possibly user-defined function) rather than special syntax in Haskell.
Therefore you have most likely used callbacks alot in Haskell without
thinking about it.
More information about the Haskell-Cafe