# Allow any literal outside parentheses if last parameter?

**URL:** <https://discuss.kotlinlang.org/t/allow-any-literal-outside-parentheses-if-last-parameter/10837>\
**Category:** Language Design\
**Created:** [December 19, 2018, 3:37pm UTC](https://discuss.kotlinlang.org/t/allow-any-literal-outside-parentheses-if-last-parameter/10837 "2018-12-19T15:37:33Z")\
**Posts on this page:** 17\
**Page:** 1

<div class="post-metadata">

**Author:** ![user1](https://avatars.discourse-cdn.com/v4/letter/u/5daacb/32.png) [@user1](https://discuss.kotlinlang.org/u/user1)\
**Post date:** [December 19, 2018, 3:37pm UTC](https://discuss.kotlinlang.org/t/allow-any-literal-outside-parentheses-if-last-parameter/10837/1 "2018-12-19T15:37:33Z")

</div>

Why is the last parameter to a function only allowed outside of the parentheses if it’s a lambada? I understand that this is where the biggest gain is, but allowing any type - or at least literals - to go outside the argument list if it’s the last parameter would also improve the readability of DSLs. For example, converting a Groovy Gradle script to Kotlin requires adding a lot of parentheses that are optional in Groovy, and conventionally omitted to improve readability.

---

<div class="post-metadata">

**Author:** ![user1](https://avatars.discourse-cdn.com/v4/letter/u/5daacb/32.png) [@user1](https://discuss.kotlinlang.org/u/user1)\
**Post date:** [December 23, 2018, 8:59am UTC](https://discuss.kotlinlang.org/t/allow-any-literal-outside-parentheses-if-last-parameter/10837/2 "2018-12-23T08:59:45Z")

</div>

Nobody for or against?

---

<div class="post-metadata">

**Author:** ![darksnake](https://sea1.discourse-cdn.com/flex019/user_avatar/discuss.kotlinlang.org/darksnake/32/2479_2.png) [@darksnake](https://discuss.kotlinlang.org/u/darksnake)\
**Post date:** [December 23, 2018, 9:08am UTC](https://discuss.kotlinlang.org/t/allow-any-literal-outside-parentheses-if-last-parameter/10837/3 "2018-12-23T09:08:50Z")

</div>

You did not present any actual examples, so nobody will seriously consider the proposal.

---

<div class="post-metadata">

**Author:** ![user1](https://avatars.discourse-cdn.com/v4/letter/u/5daacb/32.png) [@user1](https://discuss.kotlinlang.org/u/user1)\
**Post date:** [December 23, 2018, 10:22am UTC](https://discuss.kotlinlang.org/t/allow-any-literal-outside-parentheses-if-last-parameter/10837/4 "2018-12-23T10:22:17Z")

</div>

Borrowed from [https://github.com/ktorio/ktor-samples/blob/master/app/youkube/build.gradle](https://github.com/ktorio/ktor-samples/blob/master/app/youkube/build.gradle)

```auto
dependencies {
    compile "org.jetbrains.kotlin:kotlin-stdlib-jdk8:$kotlin_version"
    compile "io.ktor:ktor-server-netty:$ktor_version"
    compile "io.ktor:ktor-auth:$ktor_version"
    compile "io.ktor:ktor-locations:$ktor_version"
    compile "io.ktor:ktor-html-builder:$ktor_version"
    compile "ch.qos.logback:logback-classic:$logback_version"
    compile "org.ehcache:ehcache:3.0.0.m4"
    compile "com.google.code.gson:gson:2.7"
    testCompile "io.ktor:ktor-server-test-host:$ktor_version"
    testCompile "io.mockk:mockk:$mockk_version"
}

```

instead of

```auto
dependencies {
    compile("org.jetbrains.kotlin:kotlin-stdlib-jdk8:$kotlin_version")
    compile("io.ktor:ktor-server-netty:$ktor_version")
    compile("io.ktor:ktor-auth:$ktor_version")
    compile("io.ktor:ktor-locations:$ktor_version")
    compile("io.ktor:ktor-html-builder:$ktor_version")
    compile("ch.qos.logback:logback-classic:$logback_version")
    compile("org.ehcache:ehcache:3.0.0.m4")
    compile("com.google.code.gson:gson:2.7")
    testCompile("io.ktor:ktor-server-test-host:$ktor_version")
    testCompile("io.mockk:mockk:$mockk_version")
}

```

Not a major difference (although it looks more significant in the context of a complete build file), but the restriction to lambadas seems to be needlessly making a special case out of something that would be more useful in the general case.

---

<div class="post-metadata">

**Author:** ![fatjoe79](https://sea1.discourse-cdn.com/flex019/user_avatar/discuss.kotlinlang.org/fatjoe79/32/4221_2.png) [@fatjoe79](https://discuss.kotlinlang.org/u/fatjoe79)\
**Post date:** [December 23, 2018, 10:27am UTC](https://discuss.kotlinlang.org/t/allow-any-literal-outside-parentheses-if-last-parameter/10837/5 "2018-12-23T10:27:40Z")

</div>

The above is already possible in DSLs with an infix function declared on the lambda’s receiver. However currently you need to write `this foo "bar"`. Maybe it could be considered to allow omitting “this” in such case.

---

<div class="post-metadata">

**Author:** ![user1](https://avatars.discourse-cdn.com/v4/letter/u/5daacb/32.png) [@user1](https://discuss.kotlinlang.org/u/user1)\
**Post date:** [December 23, 2018, 10:32am UTC](https://discuss.kotlinlang.org/t/allow-any-literal-outside-parentheses-if-last-parameter/10837/6 "2018-12-23T10:32:25Z")

</div>

I humbly propose that this ought to be fixed at the language level - making lambadas a special case brings no benefits and imposes an unnecessary restriction.

---

<div class="post-metadata">

**Author:** ![fatjoe79](https://sea1.discourse-cdn.com/flex019/user_avatar/discuss.kotlinlang.org/fatjoe79/32/4221_2.png) [@fatjoe79](https://discuss.kotlinlang.org/u/fatjoe79)\
**Post date:** [December 23, 2018, 10:34am UTC](https://discuss.kotlinlang.org/t/allow-any-literal-outside-parentheses-if-last-parameter/10837/7 "2018-12-23T10:34:54Z")

</div>

The general solution might be complex to parse. If it means a huge factor in compilation time, I would take my proposal over the general one.

Also my proposal was in reply to the only example you have given, which can be done with my proposal also.

---

<div class="post-metadata">

**Author:** ![user1](https://avatars.discourse-cdn.com/v4/letter/u/5daacb/32.png) [@user1](https://discuss.kotlinlang.org/u/user1)\
**Post date:** [December 23, 2018, 10:37am UTC](https://discuss.kotlinlang.org/t/allow-any-literal-outside-parentheses-if-last-parameter/10837/8 "2018-12-23T10:37:58Z")

</div>

Limiting this to literals shouldn’t have a significant impact on parsing, and is still much more useful than just lambadas.

---

<div class="post-metadata">

**Author:** ![Wasabi375](https://sea1.discourse-cdn.com/flex019/user_avatar/discuss.kotlinlang.org/wasabi375/32/4741_2.png) [@Wasabi375](https://discuss.kotlinlang.org/u/Wasabi375)\
**Post date:** [December 23, 2018, 12:07pm UTC](https://discuss.kotlinlang.org/t/allow-any-literal-outside-parentheses-if-last-parameter/10837/9 "2018-12-23T12:07:09Z")

</div>

I don’t think the restriction on lambdas is an unnecessary restriction. I like the idea of a more flexible syntax for DSLs but I don’t think it’s a good idea to allow this in general. I like @fatjoe79’s idea of allowing for an implicit this when using infix function or maybe even a new keyword for those kind of functions:

```auto
dsl fun Foo.foo(arg: String) {}

```

IMO this should however be restricted to functions with a single argument and only work with functions that are declared that way. I for one would not like to see something like pythons (2.x) print statement `print 42` instead of `print(42)`. While I agree that a “dsl” syntax without parentheses would be amazing for DSLs like kotlin gradle, it would make the language much harder to read when used in a normal programming environment.

* * *

One argument against reusing the `infix` keyword is that `infix` as a term is associated with a binary operation. Therefor I don’t think we should use it here, because we are talking about unary operations, which happens within a context. This would also mean that we maybe should prohibit the following

```kotlin
dsl fun Foo.foo(arg: String) {}
val f = Foo()
f foo "test" // this is bad?! f is the context of and not a part of the operation
with(f){
    foo "test" // this is ok
}

```

---

<div class="post-metadata">

**Author:** ![user1](https://avatars.discourse-cdn.com/v4/letter/u/5daacb/32.png) [@user1](https://discuss.kotlinlang.org/u/user1)\
**Post date:** [December 24, 2018, 9:45am UTC](https://discuss.kotlinlang.org/t/allow-any-literal-outside-parentheses-if-last-parameter/10837/10 "2018-12-24T09:45:49Z")

</div>

Why is `f "string"` so much harder to read than `f { doSomething }` ?

---

<div class="post-metadata">

**Author:** ![Wasabi375](https://sea1.discourse-cdn.com/flex019/user_avatar/discuss.kotlinlang.org/wasabi375/32/4741_2.png) [@Wasabi375](https://discuss.kotlinlang.org/u/Wasabi375)\
**Post date:** [December 24, 2018, 9:56am UTC](https://discuss.kotlinlang.org/t/allow-any-literal-outside-parentheses-if-last-parameter/10837/11 "2018-12-24T09:56:41Z")

</div>

Code already tends to become complex. This will only become worse if there are multiple ways to do something as basic as calling a function. As long as it’s a single line of code it does not matter, but it becomes problematic in more complex situations

```kotlin
fun foo(arg: String) ...
val foo: String = ...
fun bar(arg1: String, arg2: String = "") ...

bar(foo "foo")

```

This would be a correct way to call `bar`. The question is, did you just forget to add a comma or not? It’s a very hard to spot bug.

---

<div class="post-metadata">

**Author:** ![darksnake](https://sea1.discourse-cdn.com/flex019/user_avatar/discuss.kotlinlang.org/darksnake/32/2479_2.png) [@darksnake](https://discuss.kotlinlang.org/u/darksnake)\
**Post date:** [December 24, 2018, 12:28pm UTC](https://discuss.kotlinlang.org/t/allow-any-literal-outside-parentheses-if-last-parameter/10837/12 "2018-12-24T12:28:52Z")

</div>

The proposition is quite close to Groovy syntax and kotlin developers rejected the idea at the start. I think that it was a good decision. I like Groovy very much, and it is really very good for DSLs, but not so good for statically typed language. Luckily, it is quite easy to use Groovy DSL parser on top of Kotlin, so you really can write a DSL in groovy and all important parts in kotlin.

---

<div class="post-metadata">

**Author:** ![user1](https://avatars.discourse-cdn.com/v4/letter/u/5daacb/32.png) [@user1](https://discuss.kotlinlang.org/u/user1)\
**Post date:** [December 24, 2018, 7:52pm UTC](https://discuss.kotlinlang.org/t/allow-any-literal-outside-parentheses-if-last-parameter/10837/13 "2018-12-24T19:52:15Z")

</div>

@Wasabi375 how is your example different from this valid code?

```auto
fun foo(arg: () -> String) = arg()
val foo: () -> String = { "foo" }
fun bar(arg1: String, arg2: () -> String = { "" }) = arg1 + arg2()

bar(foo {"foo"})

```

---

<div class="post-metadata">

**Author:** ![Wasabi375](https://sea1.discourse-cdn.com/flex019/user_avatar/discuss.kotlinlang.org/wasabi375/32/4741_2.png) [@Wasabi375](https://discuss.kotlinlang.org/u/Wasabi375)\
**Post date:** [December 24, 2018, 10:44pm UTC](https://discuss.kotlinlang.org/t/allow-any-literal-outside-parentheses-if-last-parameter/10837/14 "2018-12-24T22:44:35Z")

</div>

`bar(foo()) { ... }` or even `bar(foo) { ... }` is much harder to confuse with `bar(foo { ... })`

---

<div class="post-metadata">

**Author:** ![dalewking](https://sea1.discourse-cdn.com/flex019/user_avatar/discuss.kotlinlang.org/dalewking/32/1496_2.png) [@dalewking](https://discuss.kotlinlang.org/u/dalewking)\
**Post date:** [December 25, 2018, 12:00am UTC](https://discuss.kotlinlang.org/t/allow-any-literal-outside-parentheses-if-last-parameter/10837/15 "2018-12-25T00:00:40Z")

</div>

The argument against this and the implicit this is that it very quickly leads to ambiguous code that can only be interpreted based on the definitions that are in scope. You already have that a little with infix operators but that is very limited.

Consider a line like:

```
foo bar baz

```

If these two proposals were allowed there are many meanings for that code.

---

<div class="post-metadata">

**Author:** ![fatjoe79](https://sea1.discourse-cdn.com/flex019/user_avatar/discuss.kotlinlang.org/fatjoe79/32/4221_2.png) [@fatjoe79](https://discuss.kotlinlang.org/u/fatjoe79)\
**Post date:** [December 25, 2018, 6:15am UTC](https://discuss.kotlinlang.org/t/allow-any-literal-outside-parentheses-if-last-parameter/10837/16 "2018-12-25T06:15:35Z")

</div>

Thanks for the insight @dalewking. First I thought that it should be fixable with precedence like for the expression `foo + bar * baz`. But it seems to be a bigger problem. There arr potentially 2 ways to interprete this example with operators, but there are quite some more ways to interprete your example. The tokenizer cannot even be sure whether bar is an infix function or a regular function taking 1 argument.

---

<div class="post-metadata">

**Author:** ![user1](https://avatars.discourse-cdn.com/v4/letter/u/5daacb/32.png) [@user1](https://discuss.kotlinlang.org/u/user1)\
**Post date:** [December 25, 2018, 8:05am UTC](https://discuss.kotlinlang.org/t/allow-any-literal-outside-parentheses-if-last-parameter/10837/17 "2018-12-25T08:05:46Z")

</div>

@dalewking that was why I suggested (in my original proposal - I’m not sure if you were referring to that) that this could be limited to literals, making it no harder to parse than the current state of limiting it to lambadas.
