[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 
in C.

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
        n a

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 mailing list