Rationalizating Pure Functions on Kotlin

Have you proposed this to Kotlinlang foundation?

We had a rather heated discussion about purity yesterday. The purity makes sense if everything in the language is pure. Otherwise it introduces a lot of limitations without actual benefits. As for optional purity, it could probably be done with contracts.

1 Like

I would love to see a pure function keyword in Kotlin, it’s one of the best features of the D language and I wish more languages had it.

For calling non-kotlin code, we could either assume everything is impure, or have purity not checked (similar to how null/nonnull works today). And maybe have an annotation that Kotlin understands, like @Pure in pure4j: GitHub - pure4j/pure4j: Compile-Time Purity and Immutability Semantics For The Java Language

1 Like

The purity makes sense if everything in the language is pure. Otherwise it introduces a lot of limitations without actual benefits.

There are actual benefits, though.

For instance, the results of pure functions being invoked on compile-time-constant parameters can be evaluated at compile time. Functions like String.trimIndent (which gets invoked on constant multiline strings, for instance) could be a big win for this.

Use of pure functions may also enable compiler optimizations that wouldn’t otherwise be possible such as allowing this:

val x = pureFunc(42) + pureFunc(42) 

to be simplified to this:

val x = pureFunc(42) * 2

These types of optimizations can get quite complex if a lot of pure functions are being invoked, and can result in a lot of code savings.

I think that the compiler probably can’t do an adequate job of identifying pure functions, and it would be necessary to have a ‘pure’ keyword or something similar so that the user could tell the compiler what things should be treated as pure. In some cases, however, the compiler could identify if a function marked ‘pure’ was doing something fundamentally impure, and could issue an error message. This would be very useful.

Note, by the way, that recent versions of C++ have been introducing a lot of purity-related features involving the ‘constexpr’ keyword (C++11) and ‘consteval’ keywords (C++20).

Unfortunately this is not valid on the JVM in many cases, and when it is, the JVM can do it itself.

Basically pureFunc cannot be guaranteed to be pure and if it is not a local function could be replaced by literally anything else (without going into debugging or nasty classloader shenanigans). At the same time there is nothing stopping the JIT/JVM from determining that the function is effectively pure and can be optimized as such.

As such, for now the only benefits for Kotlin on the JVM is that the compiler can enforce the code property, but it cannot use it for optimization except in local cases (and if the method is private it could already do so - but Kotlin for now relies on the JVM to do this).

2 Likes

Maybe you could first introduce a immutable keyword for classes that only have val attributes.

Then, functions with keyword pure would only accept objects from immutable classes?

That would only cover a subset of pure functions, but based on the use cases that could still be very useful.

The immutable classes should require that their attributes are not only val, but are also not used anywhere else (except if they are immutable too).

Regardless of purity, I think adding immutability as a language feature would be pretty nice.

3 Likes