int count() {
static int count = 0;
count++;
return count;
}
This feature leads to much more concise code, the equivalent in kotlin would be:
var count = 0
fun count(): Int {
count++;
return count;
}
In kotlin, this unecessarily polutes the classes namespace, leads to problems with variable name clashing, and can give the impression that the variable is applicable to the whole class, when in fact it is only applicable to the function.
Static local variables would easily allow definitions of variables that are only applicable to a certain function, but still need to preserve their state between multiple invocations.
The compilation for this would be easy, for JVM just create a private field at class level perhaps prepended with the function name.
Drawbacks:
It may be confusing for people transitioning from java to understand that the variable keeps its value between invocations.
I personally find this to be far less concise. It breaks the rules of where field-declarations can be made and the current-way of doing it is far cleaner in my opinion.
Kotlin tries to discourage people from writing non-pure top-level functions, functions that depend on some mutable state. Kotlin has classes and objects to encapsulate mutable state and to work with it. C-style programming with mutable global state is still supported in Kotiln for a variety of reasons (you are allowed to write a top-level var, which is essentially static). However, it is non-goal for Kotlin to make this C-style programming easier. The ability to declare static variables inside functions is missing in Kotlin by design, not by omission.
I haven’t had the need for such a feature but don’t you think giving me the option would be good? Should we not let the programmer decide how he’ll use the language instead of vice versa?
JetPack Compose basically has static locals with some weird workaround, look at the following code:
@Composable
@Preview
fun app() {
val basicallyStaticLocal = remember { mutableStateOf(true) }
MaterialTheme {
// UI code here
}
}
fun main() = application { Window(onCloseRequest = ::exitApplication, title = "Example") { app() } }
So if JetBrain’s modern UI framework has a need for it, why not support it normally so it doesn’t have to be done weirdly like it is in Jetpack Compose? I just don’t get why the same company that’s limiting that functionality is also using it in something new and modern if it’s a really bad idea like as you claim it is.
In my case, static locals would be quite nice for immutable objects, such as Pairs, Regexes and Lists. Thus, I could encapsulate them in a method where they are used without repeated allocation of new ones.
You need reusing the same value all the time, like a constant, but with a non constant expression. Theoretically the compiler could execute the code at compile time, if this is possible (no external references).
Instead the “counter” example needs a one time initialization and changes the value later.
If it’s not static, the value will start at the same initial value on each invocation.
Also, in your other thread it’s not discussed, why extracting all the resuse expressions can be a bad thing.
The main problem from my POV is not so much the work to move the wannabe-constants to some other file (e.g. we have a Constants.kt for that), but it breaks encapsulation.
From my POV you should be able to encapsulate constructs, that are only used inside a function (or even inside a block). It’s another kind of scoped variables. This makes completely clear to the reader, that he does not need to look if there is another usage of that thing, because it’s clearly not visible outside of the scope.
Another consequence is, that I can use the same name for the same thing in each function.
It just doesn’t make sense to have patternXYZ, patternABC, etc. if it’s always the same thing and the context makes the difference.
Something like this:
fun f1() {
static val thing = initThing1()
thing = doAction1With(thing)
}
fun f2() {
static val thing = initThing2()
thing = doAction2With(thing)
}
fun main() {
f1()
f1()
f2()
f2()
}