language icon indicating copy to clipboard operation
language copied to clipboard

Infix function

Open MarcelGarus opened this issue 4 years ago • 4 comments

Being able to add an infix keyword before methods in order to be able to use them like a method b instead of a.method(b) would make the syntax cleaner in cases where both a and b have the same role/importance in the operation, such as in most mathematical forms. In contrast to #607, this feature request doesn't aim to allow any arbitrary character as operators but instead only the usual method identifiers. Here are some examples of how the syntax could be used:

  • Dot products like vec dot otherVec instead of vec.dot(otherVec).
  • Ranges like 1 to 5 or 2 until 5 instead of 1.to(5) and 2.until(5), just like in Kotlin.

MarcelGarus avatar Jul 13 '20 10:07 MarcelGarus

After this, make operators proper functions, so, for example a + b would be +(a, b) infixed function. This would allow for cleaner code like [1, 2, 3].reduce(+) instead of [1, 2, 3].fold((a, b) => a + b).

mateusfccp avatar Jul 13 '20 11:07 mateusfccp

The big issues here are:

  • Parsing
  • Precedence

Dart currently combine both for operators. They have special grammar rules that both ensure that x + y is parsed as that, and that the precedence of + is different from *.

If we allow any identifier to be used as an infix operator, then we need to parse e1 foo e2 as an operators invocation. That introduces ambiguity. Currently we can write int foo(x)=>2 to declare a function. However, that can also be parsed as (int) foo ((x)=>2) which is an "infix operator foo" applied to the Type object of int and a function literal. "Obviously", Type doesn't have a foo operator, but equally obviously we want user-defined operators to work with extensions too, so nothing prevents someone from adding a foo infix method to Type. We only know that after parsing, so we can't let parsing rely on knowledge of whether something might be declared as an infix method.

Dart is in the C-syntax family (and, e.g., Kotlin is not), which means that adjacent identifiers only occur in declarations. Something like int get foo; is possible to parse, even though get is not a reserved word, because it can't possibly be anything except a declaration, it's the only case where adjacent identifiers can validly occur. Allowing un-quoted identifiers as infix operators is very, very unlikely to be even possible without a complete overhaul of the entire language syntax.

#607 is much more likely. So is a quoted syntax like 1 `add` 2, but that then runs into the issue that all such operators have the same precedence (we really do not want you to declare the precedence, because the need to understand the declarations before we can parse the expressions, and the way Dart type inference works, we need to parse some expressions to find the type of declarations). If all infix methods have the same precedence, then you need a lot of parentheses, and then x.foo(y) doesn't seem that much worse than (x `foo` y).

lrhn avatar Jul 13 '20 13:07 lrhn

I understand the appeal, but I don't think this feature carries its weight. It eliminates some punctuation, but that's really all it accomplishes. In return, it opens the door to what can be very difficult to read code. This is valid Scala code:

ape bat cat dog eel fox

How many readers at a glance can tell which of those identifiers are receivers, parameters, or methods?

One of the nice things about Dart (and most other languages) is that even if you don't know what various identifiers resolve to, you can at least mostly visually parse it and understand the nesting structure correctly. I wouldn't want to give that up.

munificent avatar Jul 17 '20 20:07 munificent

Having ability to do something doesn't means encourage use that for everthing.

if someone use infix function/operator override to writing code like

ape bat cat dog eel fox

that means he/she what that. The author of code should be responsible for what he/she has written not the designer of language. As far as I known Kotlin's ecosystem doesn't appear lots of infix override, ever infix I met is just perfect when it is be used.

For more, your Records spec may need this infix operator for Pair

xanahopper avatar Sep 01 '22 02:09 xanahopper