kivikakk.ee

Curry of evil

I had an amusing thought in bed last night, and I was fortunate enough to remember it:

What if currying wasn’t all good?

# let f x =
    let now = CalendarLib.Time.now ()
    in
    fun y ->
      if CalendarLib.Time.now () <> now then
        x - y (* !! *)
      else
        x + y;;
val f : int -> int -> int = <fun>
#

The type-signature is sure innocuous.

Hence:

# f 1 2;;
- : int = 3
# f 100 ~-123;;
- : int = -23
# let add100 = f 100;;
val add100 : int -> int = <fun>
# add100 77;;
- : int = 23
# (* !! *)

I don’t know what convinced me to do this, but I was thinking along the lines of, “OCaml makes all functions curryable, so someone seeing a type-signature of int -> int -> int is so used to thinking of it as a (curryable) function that “takes two arguments”, that they might forget that real things could happen between “fixing” arguments one and two.”

This demonstration is somewhat poor (relying on CalendarLib.Time), but it still gives me pause for thought.