[bitc-dev] Function arity (again)

Jonathan S. Shapiro shap at eros-os.org
Sat Mar 27 22:23:42 PDT 2010


As some of you know, I've gone back and forth on currying. The other
night I realized that there are really two separate issues involved:

1. Support for partial application (i.e. application in which not all
arguments are provided). This actually is not difficult.
2. Making sure the programmer is able to understand which applications
will incur heap allocations. This is somewhat harder.

While currying is useful, and provides key idiom support in ML and
Haskell, it's something that the programmer would mostly like to avoid
in systems code. This brings me to two issues:

REPORTING/RESPECTING ARITY

Once you introduce curried-style types and syntax, there really isn't
a good way to declare arity anymore. For example, in O'Caml:

# let multiply x y = x * y;;
val multiply: int -> int -> int = <fun>    // correct, and expected
# let multiply2 x = (fun y -> x * y);;
val multiply2: int -> int -> int = <fun>  // correct, but undesired

The problem with this is that the information about arity has been
lost. Given that correct use of native calling conventions actually
relies on this knowledge, it's moderately awkward to have lost it. For
the second type, I would have preferred to see:

val multiply2: int -> (int -> int) = <fun>  // correct, but undesired

I fully understand that the two types are mathematically identical,
but annotating which arrow distinguishes call from return nonetheless
seems like a good and useful thing in a systems-oriented language, and
seems fairly harmless to those accustomed to ML/Haskell. Would people
coming from ML/Haskell find this impossibly strange?

AVOIDING ALLOCATION

When partial applications are permitted, there is still a strong
desire to avoid performing them inadvertently. Unless an explicit
application syntax is introduced to indicate that partial application
is intended, I see no good way to deal with this. I can see two
sensible ways to annotate this intent:

  1. With a module-level annotation indicating that the module makes
intentional use of currying
  2. With an explicit application syntax, e.g.
        multiply . x

Given the ability to write a lambda explicitly, I'm actually not very
convinced that partial applications are critical, and they pose a real
danger of unintended use. Input and suggestions?


Jonathan


More information about the bitc-dev mailing list