Re: [Haskell-cafe] Callback functions?

On 7/2/07, Hugh Perkins
Anyway, so the question is: how do we write callback functions in FP/Haskell? Can someone provide a simple, but functional example?
What makes a callback different from any other kind of function? In Haskell, as in other functional programming languages, you're completely free to pass functions into other functions and store them in datastructures. Take a look at the 'callbacks' used in the HOpenGL examples. They're just ordinary functions: http://cvs.haskell.org/cgi-bin/cvsweb.cgi/fptools/libraries/GLUT/examples/Re... -- Dan

http://cvs.haskell.org/cgi-bin
/cvsweb.cgi/fptools/libraries/GLUT/examples/RedBook/
Ok, I'll take a look
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 :-)
On 7/3/07, Dan Piponi
On 7/2/07, Hugh Perkins
wrote: Anyway, so the question is: how do we write callback functions in FP/Haskell? Can someone provide a simple, but functional example?
What makes a callback different from any other kind of function? In Haskell, as in other functional programming languages, you're completely free to pass functions into other functions and store them in datastructures. Take a look at the 'callbacks' used in the HOpenGL examples. They're just ordinary functions:
http://cvs.haskell.org/cgi-bin/cvsweb.cgi/fptools/libraries/GLUT/examples/Re... -- Dan _______________________________________________ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe

On 7/2/07, Hugh Perkins
Well... what about inside monads? Does this break purity??? Does this require adding IO to the monad if the callback function does IO?
Check out the documentation for the HOpenGL callbacks here: http://www.haskell.org/HOpenGL/documentation/GLUT/Graphics.UI.GLUT.Callbacks.... I think they do exactly what you are talking about in terms of doing I/O. If, the callback needs to perform I/O then the callback itself will likely be a function that returns an instance of IO, just like any other function that does I/O. Any function that calls the callback will likely also return an instance of IO because if a function is 'tainted' by IO, then so are its callers (usually). But in a sense you don't really need to talk about callbacks in Haskell because passing functions into other functions so that they can be called is the norm rather than the exception in Haskell. You don't need to give them a special name. (The HOpenGL API probably does so because it's inheriting from an underlying C API that calls them callbacks.) -- Dan

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.
participants (3)
-
Albert Y. C. Lai
-
Dan Piponi
-
Hugh Perkins