On Thu, Feb 12, 2015 at 8:08 AM, Keean Schupke <[email protected]> wrote:
> On 12 Feb 2015 15:54, "Jonathan S. Shapiro" <[email protected]> wrote: > Primitive functions use tuples for their arity like: > > primitive_add_int32 :: (int32, int32) -> int32 > > These get wrapped into an overloaded type class, but we can omit that > detail and have simply: > > (+) a b = primitive_add (a, b) > I think that the root of our disconnect is a little clearer now. What you suggest above is very similar to what F# does, and it is certainly workable. It has the very real advantage that arity is being explicitly encoded in the tuple syntax, which is also a simplifying thing. One effect of this in F# is that *programmers* seem to get divided into two camps. One camp comes from the functional programming world. That camp is comfortable with the curried application syntax, and will use it preferentially. The other camp comes from the world of C. That camp will also gravitate toward what is familiar, which is to say the tuple syntax. The two groups will tend to build libraries in mutually incompatible style, which raises a concern that the user base will ultimately bifurcate. One purpose of the present discussion about arity-aware function types was to see if we could satisfy the needs of both groups with a single surface syntax. Just incidentally, the tuple approach violates your view that types and implementation should be kept separate. While the tuple remains a product type here, the rationale for this design choice is that the compiler is going to treat "function accepting tuple" as a distinct implementation case. And note, *not* "function being *passed* a tuple. that is: f( : 'a -> 'b) (1, 'c') is not called using the native calling convention merely because the argument type is a tuple, but (g : ('a, 'b) -> 'c) (1, 'c') IS called using the native convention.[*] [*] Another option is to decide the calling convention after specialization, in which case f actually *would* get called using the native convention. Anyway, the purpose of the current discussion was to see if we might be able to successfully cary arity *explicitly* on the function type without breaking the type system. Given that we lose most general types in the process, I'm concluding that the answer is "no", and that we will probably need to adopt the tuple story. I don't see any reason the compiler to not provide the curried versions > automatically. I'm not entirely sure what you mean by this. Do you mean that given def f (x, y) = ... the compiler will automatically know what to do with an expression f 1 ? That would be equivalent to inserting an automatic coercion, which will play havoc with type inference. Do you instead mean that in your example above the + method is curried while the primitive_add function is not? Do you perhaps mean a third thing? The compiler uncurrying pass knows the original primitive type (or > imported function type) and it would be a compile error if we cannot > sufficiently uncurry. > If we proceed on the assumption that uncurrying never increases allocations (which may not be right), then uncurrying can only make things better. But the problem here is the adoption of curried syntax in the first place. The problem with curried syntax is that it places the programmer in the habit of preferring an idiom that (by default) *inserts* non-obvious allocations and then applying best-effort to get rid of them again. Both parts of that statement are bad for systems codes. shap
_______________________________________________ bitc-dev mailing list [email protected] http://www.coyotos.org/mailman/listinfo/bitc-dev
