Iām aware, but what Iām proposing is more general (infix function require an explicit right hand argument, my proposal does not, and my proposal could be generalised to omit any function call parentheses except for argumentless calls, so f(a, b, c) could become f a, b, c.
That would be very interesting in my opinion. Another option would be adding a function modifier like infix (prefix would be a good name) that would allow us to use the function without the parentheses.
Yeah, certainly the single parameter is the cleaner usage, but still āsetOf 1, 2, 3ā looks pretty clesn and DSLish to me.
Sad to hear that Groovy has problems with it (but the groovy feature is even more complex since it allows removing dot access, which Iām not proposing here). Besides that, I naively donāt see the problem with parsing: whenever you wncounter a function identifier followed by an expression, instert an open paren in the parse tree and set a boolean flag to true. Whenever the next token is an end of statement, insert a close paren. This disallow nested parenless functions, but thatās sensible in my view.
These 2 line are equivalent, but second one can use any method applicable to both last parameter and return type of the method.
Of cause the priority of operations can help, but it is complex and confusing as is without adding the function call into them. It also makes code less readable.
Iām also not a fan of this idea. The problem as @cabman pointed out is that this will make anything but the most basic calls a nightmare to read and understand.
We already have a similar problem with infix functions, because there is no way of specifying precedence for them.
I see why this would be great for DSL like constructs but I donāt think itās worth adding this just for that alone especially as it degrades the language if used for anything else.
In lights of your comments, Iāve become inclined to enable this behaviour with a keyword/modifier akin to the infix modifier. That way, msking this behaviour available would be responsability of whoever creates the function, not whoever uses it.
As for precedence, please excuse me if Iām being naive, but I see it this way: if the parser sees a token that is a function identifier, and the next relevant token is not an open paren, then all the text until the next coma or statement terminator should be understood as a single expression. Thus
fun 1 + 2 is unambiguously interpreted as fun(1 + 2) and if you wanted other interpretation you would have to use parens.
I fear I donāt understand whatās the problem with the list examples.
An statement terminator is either a semicolon or an endline in kotlin (setting aside comments) (not sure if āterminatorā is used in the kotlin spec but I see the term often in defining programming lsnguages).
As per one of my previoud comments, my idea is that the list examples would be understood as in your second translation.
Thanks for the second example, since it helps me flesh out my idea. As per my previoud reply, that snippet would be not only confusing, but illegal. However, func1 2.0, (3+5) would be legal.
fun func1(i: Int = 0, r: Double = 0.0) {
val
x
=
i *
5
}
is very legal 2line expression.
The example you mentioned in last paragraph is legal inside functionās parentheses. Also as I said code func1 (3+5), 2.0 should also be valid, but compiler should look forward for comma to understand how to interpret expression in parentheses.
I think one way to resolve the ambiguity is to let the user explicitly opt-in for this feature.
For example, we can make it only doable in a closure since itās basically a feature for DSL.
The user has to do something like
fun closureExample(@AllowPrefix c: Foo.() -> Unit) { ... }
In @sam.zhou case there is not much ambiguity in the first place. However one of the problem is if the actual parameter provided as complex expression. This is the same problem as with infix function.
The more complex problem I donāt want to have is when function takes multiple parameters.
Also original request was to make parentheses optional. This is not a case with infix function and suggestion by @sam.zhou sounds like to follow the same pattern: if developer provided modifier prefix then no parentheses allowed, otherwise they are required.
Kotlin developers decided against omitting braces based on Groovy experience. It produces a lot of problems and the only place it could be used is gradle-like dsl. For that one can always use groovy wrapper, especially because it much lighter than kotlin compiler. Using brace-less syntax in actual non-dsl code is a terrible mistake.
If Kotlin had builtins for arrayOf/listOf then I donāt think Iād see a big need for this feature. In general I find that infix functions can be used in DSL context to provide a marginally more verbose, but much more readable, DSL syntax:
collect { data from source into dest } ā infix fns from, into defined in scope of collect DSL closure.
i one up this, inbuilt functions without use cases that would bring a lot of confusion and frusturation should have this, also imo @cabman 's example should be directly interpreted as func1(10)+15 if this were to be implemented, also, it shouldnt be applicable for varargs arguments, only ones that you can directly infix when making a normal function should be applicable
I agree with others that this is probably a bad idea but one thing similar I would like to see is the ability to call infix functions that exist on āthisā without having to use the keyword this.
So instead of having to say
this inFixFunction value
You could drop the this. But I could see how it could cause confusion in some cases