Note: This feature is not intended for consideration for the first few versions of the language, as it requires (among other things) traits to be implemented, and it generally isn't a feature that should be prioritized as of now.
This is a suggestion for a minor convenience feature which would allow treating operators as functions. Since operators to a large extent are already in most languages functions treated specially by the compiler, mostly in terms of syntax, taking the step to to some degree unify functions and operators would be logical. And yes, this idea is lifted directly from Haskell, don't @ me.
Proposed syntax
opFuncExpr = "(" unaryOp | binaryOp ")" ;
Operator function expressions would be an atomic expression, with the lowest possible precedence. Since this pattern of tokens cannot occur in other parts of the language, the syntax itself would not be ambigous. I am personally not knowledgable enough about other languages with this feature or features similar to it to be able to propose other possible syntaxes, although if anyone has other ideas, I'll add them here.
Example
val add = (*);
println(add(2, 5));
In the above example, (*) is used to get the binary multiplication operator, as a function, which is then called using the arguments 2 and 5. The variable add would be inferred to have the type (int32, int32) -> int32 (function type syntax provisional). More generally, (+) would have the type (T, T) -> T, where T would be constrained to be a numeric type. How this constraint would be implemented is likely through a trait down the line.
A slightly more practical example
val xs = [1, 2, 3, 4, 5];
val sum = xs.reduce((+));
Here, (+) is used as the function for binary addition. This is opposed to having to write something like xs.reduce((a, b) -> a + b), merely a convenience.
A side-effect of allowing operator function expressions to be regular expressions is that (+)(1, 2) (kinda Polish notation) would be a perfectly valid, albeit odd, way of writing 1 + 2. I see this as more of an unintended side-effect of this feature, although an argument could be made that it could degrade the language to some degree.
Issues
The major issue with operator function expressions is the ambiguity that arises with (+) and (-), since + and - can be both unary and binary. This could likely be resolved through an approach similar to overload resolution at the type inferrence stage. However, val f = (+); on its own would be ambigous.
Since this feature stems largely from a language which has currying and partial function application as first-class language features, its addition to Draco would be somewhat watered down by the lack of these features. The rather concise xs.map((*2)) would be impossible, for instance.
The syntax admittedly looks a bit strange.
If further issues are mentioned, I'll add them here.
This is a suggestion for a minor convenience feature which would allow treating operators as functions. Since operators to a large extent are already in most languages functions treated specially by the compiler, mostly in terms of syntax, taking the step to to some degree unify functions and operators would be logical. And yes, this idea is lifted directly from Haskell, don't @ me.
Proposed syntax
Operator function expressions would be an atomic expression, with the lowest possible precedence. Since this pattern of tokens cannot occur in other parts of the language, the syntax itself would not be ambigous. I am personally not knowledgable enough about other languages with this feature or features similar to it to be able to propose other possible syntaxes, although if anyone has other ideas, I'll add them here.
Example
In the above example,
(*)
is used to get the binary multiplication operator, as a function, which is then called using the arguments2
and5
. The variableadd
would be inferred to have the type(int32, int32) -> int32
(function type syntax provisional). More generally,(+)
would have the type(T, T) -> T
, whereT
would be constrained to be a numeric type. How this constraint would be implemented is likely through a trait down the line.A slightly more practical example
Here,
(+)
is used as the function for binary addition. This is opposed to having to write something likexs.reduce((a, b) -> a + b)
, merely a convenience.A side-effect of allowing operator function expressions to be regular expressions is that
(+)(1, 2)
(kinda Polish notation) would be a perfectly valid, albeit odd, way of writing1 + 2
. I see this as more of an unintended side-effect of this feature, although an argument could be made that it could degrade the language to some degree.Issues
(+)
and(-)
, since+
and-
can be both unary and binary. This could likely be resolved through an approach similar to overload resolution at the type inferrence stage. However,val f = (+);
on its own would be ambigous.xs.map((*2))
would be impossible, for instance.