Proposal: `where` blocks to allow adding local bin...
# language-proposals
f
Proposal:
where
blocks to allow adding local bindings to single-expression functions without creating a block (similar to Haskell's where)
Copy code
fun greet(hourOfDay: Int, name: String) = println(greeting + name)
    where {
        val greeting = when {
            hourOfDay < 10 -> "Good morning, "
		    hourOfDay < 12 -> "Good day, "
		    hourOfDay < 17 -> "Good afternoon, "
  		    else -> "Good evening, "
        }
    }
d
If you are after the single expression body you can do
Copy code
when {
            hourOfDay < 10 -> "Good morning, "
		    hourOfDay < 12 -> "Good day, "
		    hourOfDay < 17 -> "Good afternoon, "
  		    else -> "Good evening, "
        }.let { println(it + name) }
d
What this feature can that regular block body can't?
f
It's mostly a stylistic choice. It allows you to put the "main" expression (the expression that gets returned) at the top, while putting any auxiliary logic in a separate block. The
where
block should only allow
val
bindings, encouraging creation of well-named intermediary values
d
This contradicts with readability principle "declarations should be put before usage", which is always true right now for local context
f
Hmm, there's some truth about that, I never thought about it that way. I was mainly looking for opinions here out of pure interest if there was a way to introduce a language feature into Kotlin that allows introducing bindings into a function while still keeping a terse, single expression syntax
d
New language features should solve some real use-cases and pain points in the first place
And in my personal opinion, expression bodies for functions were a mistake
👀 2
🤯 2
👎 3
âž• 1
k
If it was like this:
Copy code
fun greet(hourOfDay: Int, name: String) = println(greeting(hourOfDay) + name)

private fun greeting(hourOfDay: String) = when {
    hourOfDay < 10 -> "Good morning, "
    hourOfDay < 12 -> "Good day, "
    hourOfDay < 17 -> "Good afternoon, "
    else -> "Good evening, "
}
Would you prefer
fun greeting
to be declared before its use? Normal Kotlin practice is to define it after first use. So the readability principle of "declaration before use" is not universal. Having said that, I quite like the use of
where
in Haskell - it does greatly improve readability in my opinion - but I don't think it quite fits into intuitive Kotlin syntax.
d
And in my personal opinion, expression bodies for functions were a mistake
I'm curious what your reasoning is for this. I can certainly see how they can be abused, but when used correctly they can greatly simplify and clarify code.
âž• 7
j
@dmitriy.novozhilov why expression bodies were a mistake? A lot of functions do not have any variable in the body
d
Okay, maybe this statement was too harsh I just dislike functions with expression bodies from stylish POV But allowing to write a overridable function/property without explicit type is huge pain from the compiler perspective and source of quite hardly discoverable issues from user side
nod 1
👀 1
j
Ah, makes sense, in my case I always add the type. But I do this everywhere except when the linter says it is not necessary (constructor calls for example)
d
Yep, that's more understandable. While it's probably too late to change it now, it would make sense if open/abstract functions always required explicit type. FWIW, I usually do that anyway for other reasons.
l
@dmitriy.novozhilov see explicit API mode I agree,
open
functions and properties should always have explicit types.
d
I know about it, thanks
✅ 1