Why return and throw is expression and not statement?


#1

Why was made a decision for return and throw to be expressions than statements ?

Seems like it make more confusion than help

In general I mean why is it possible to write such horrible code like the following:

fun start(): String {
    return throw return "OK";
}

#2

Because it allows you to write code like

fun fooOffensive(value: String) {
     val number = value.toIntOrNull() ?: throw IllegalArgumentException("The given argument is not a valid number string")
    // do something with number
}

fun fooDefensive(value: String) {
     val number = value.toIntOrNull() ?: return
    // do something with number
}

#3

But it doesn’t seems like a big feature !!
What we have … Small feature and huge variety of bugs and comprehensions

Seems like it does not worth it !!


#4

Okay, even if it is worth it than Grammar should be designed an elimination assignment of return expression to throw expression by adding rule:

If result of expression is Nothing than it cannot take as assignment another Nothing

For example:

Nothing <- Value <- Value <- Nothing (Invalid chain of assignments)
Value <- Value <- Nothing (Valid chain of assignments)


#5

But why? A rule like this would just make the compiler more complex and it’s not like any sane person would write something like return throw return foo.

What bugs? I’d argue this reduces the amount of bugs, because the compile is less complicated and therefore contains less bugs. If someone wants to write bad code they can, but that is true for every language. You can’t prevent bad code.


#6

One of the main purpose of compiler is to detect bad code or code that could produce issue in understanding of code


#7

The other points are right, you need to be able to throw/return where expressions are expected. But, fun fact about Kotlin I didn’t realize until I made a bunch of AST classes for it, nothing is “just a statement” in Kotlin. Every statement is either an expression or a declaration. It is also clear from the (outdated and a bit inaccurate) grammar.


#8

There is already IDE inspection for that.


#9

@Svyatoslav.Kuzmich The language that is useless without IDE it is the useless language … =))

IDE can do anything, but we write code in High-Level Languages only because it makes code more readable, maintainable, easy to modify, otherwise we would write code in assembly language and say that IDE can show some patterns in this code …

This argument is unserious !!!


#10

To clarify that, it’s not an IDE inspection but rather a compiler warning about unreachable code. Thus it is reported even when compiling code without an IDE, like in this example:

//sampleStart
fun testReturn(): Int {
    return throw return error("x")
}
//sampleEnd
fun main() {}

#11

And you think it is enough just to make a warning for it ??

Warnings should be 100% only for code which purpose is not obvious or we are not sure that it is an error.
But if we know that this code is never reachable and also it makes a code less readable then we need to make it an error !!

On the Kotlin site https://kotlinlang.org/docs/reference/evolution/kotlin-evolution.html written:

Language design is cast in stone,
but this stone is reasonably soft,
and with some effort we can reshape it later.
                    
Kotlin Design Team

DO NOT AFRAID TO MAKE IT AN ERROR !! IT IS NOT A FEATURE, IT IS A DESIGN ISSUE !!

You tried this as a feature - you failed !! Flip the next page and make language more consistent, more readable, more obvious !!

It is easy to do with Grama Rule that I have shown earlier


#12

Wow, calm down. Right now he just pointed out that it’s actually a compiler warning and not just an IDE inspection.
Also it’s not as simple as you think. The grammar change you proposed does not solve the problem without creating new ones. If you restrict just the use of Nothing you can no longer use TODO() in your code the way you can right now.

if(someReareCondition) return TODO("fix later, I don't care right now")

So you actually need to restrict just the usage of return, throw, break and continue (I think those are all keyword expressions that are of type Nothing), while ignoring all functions that return Nothing.
I’m not a compiler guy, but I think this would be much more complicated than just changing a warning into an error.

Also you still did not answer my question? Is there any real expression anyone would ever write that could lead to a problem. No tool can stop you writing bad code. The compiler detects the problem and warns you about it. I don’t think restricting Nothing just to change this from a warning to an error is worth destroying the usability of TODO.


Btw, I don’t think you will get the kotlin team to change anything by yelling at them. In my experience with KEEP and this forum, reasonable arguments do the trick just fine.


#13

I just want to say to the JetBrains Kotlin devs, thank you very much for making things like these as warnings. As someone with simple internal code generators that doesn’t want to do reachability analysis or type analysis, I appreciate that this and other things (e.g. unnecessary “!!”/"?.", etc) are warnings. Just thought it’d be worth hearing praise from the other side.