Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Operator function expressions #107

Open
thinker227 opened this issue Dec 10, 2022 · 0 comments
Open

Operator function expressions #107

thinker227 opened this issue Dec 10, 2022 · 0 comments

Comments

@thinker227
Copy link
Contributor

thinker227 commented Dec 10, 2022

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.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant