I won’t speak in the name of the language designers. However, constructors have stronger properties than general functions. They
- are injective,
- have a fixed arity,
- do not execute arbitrary code,
- and allocate a memory block (except in some optimized cases).
So it makes sense to distinguish them syntactically.
Point 2 means that you can apply them totally, without building nor calling any closure. In a way you are inlining the constructor, seen as a function, but point 3 and 4 say that the code of the function is straightforward (it simply allocates and initializes a value block). In fact, there is no need for a function in memory that represents the constructor.
Thus, by forcing constructor applications to be total, you can have a faster compilation scheme, that also better evidences allocations when reading your OCaml code. This is appreciated by some, as allocations are among the prime things monitored by performance-concerned OCaml programmers.
The syntax Constr (a,b,c)
resembles that of regular tuples (a,b,c)
on purpose: it does mostly the same thing, only with a different type (and with the tag of the constructor, different from the implied tag of tuples). In this example the constructor does not take one tuple argument, but rather it takes three arguments a
, b
and c
where parentheses and commas are part of the syntax of the constructor. So the syntax token Constr
cannot be treated as (fun abc -> Cons abc)
. In other words, uncurried syntax does not lead naturally to a syntax for partial application (including no-application), which is on purpose.
The tuple syntax in patterns also evidences better injectivity, I think. In pattern-matching, you are actually destructing a tuple, you are not magically finding the unique values for the arguments of an injective function such that the application of said function yields the matched value. But that is more minor.
That said, conflating constructors and functions is perfectly reasonable too. Coq does it, even though its syntax draws on Caml. OCaml constructors not behaving as proper functions is a recurring subject of complaint, for example, you may skim the discussion of this pull request.