Wednesday, March 23, 2005


Partial functions in OCAML

OCAML supports something called "partial functions". Suppose you define a function that takes two arguments and adds them together:

let adder x y = x + y;;

You can obviously call adder 2 3 and expect to get back 5. OCAML lets you call adder 2 and get back a function that adds 2 to whatever argument you pass it. For example:

let add2 = adder 2;;
let add3 = adder 3;;
Printf.print "%d %d\n" (add2 5) (add3 7);;

You would see "7 10" printed out.

I must admit, my first reaction to this was "Neat. So what?" I am starting to see the usefulness of it, however. In Scheme, if I want to loop through a list and add 5 to every member of the list, I can do something like this:

(map (lambda (x) (+ x 5)) '(1 2 3 4 5 6))

In OCAML, you could do this: (function x -> (x + 5)) [1;2;3;4;5];;

Since I have defined my adder function, though, I can do this instead: (adder 5) [1;2;3;4;5];;

I think the trick to taking advantage of partial functions may be to determine which arguments are likely to change and place those last. For example, if I have a function called heap_consolidate, I can define it as:

let heap_consolidate x heap = (* do something with x and the heap *)

or I can do:

let heap_consolidate heap x = (* do something with x and the heap *)

If I am going to be passing a lot of different x values for the same heap, especially if I want to iterate through a list or an array, I might want to make heap the first parameter so I can do something like this: (heap_consolidate myheap) myheap.root;;

If heap is the second argument, I would have to do: (function x -> heap_consolidate x myheap) myheap.root;;

While partial functions may seem error-prone, I don't think that is the case. If you accidentally omit a function argument, OCAML's type checker will notice that you are using a function type where it is expecting you to use something else. Without type checking, partial functions seem pretty dangerous.

that's a "partially applied function", not a "partial function" :) (also, see currying)
Post a Comment

<< Home

This page is powered by Blogger. Isn't yours?