Suggestion: Static local variables

C has static local variables, e.g.:

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.

3 Likes

You can easily simulate that with an object:

object Counter {
  private var counter = 0
  fun count(): Int = counter++
}

I don’t think adding a feature for this to be much worthwhile.

4 Likes

Source compatible:

object count {
    private var count = 0;
    operator fun invoke() = ++count
}
5 Likes

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.

1 Like

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.

11 Likes
fun count() = Count()
private object Count {
    private var count = 0
    operator fun invoke() = ++count
}

This would be better as you’re then not breaking any Kotlin naming conventions.

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?

Static locals is a really bad idea.

5 Likes

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.

1 Like

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.

1 Like

+1
I created a similar thread few months ago : Auto extract final objects from code

A language should always provide a way to make optimized code at least as easily as badly optimized code.

1 Like