Does Kotlin have something like static variable inside a function? - kotlin

I'm wondering if it has something that works like static variable inside a function in C.
In C language we have this:
void next_x()
{
static int x = 0;
x++;
}
Variable x is declared and initialized inside a function. As far I know C - it can be used only in the scope of this function and it is initialized only in first call of this function.
I need something like this in Kotlin. I have code similar to this:
private val x: Int = 0
fun getNextX() : Int {
x++;
return x;
}
and I would like to have something like this:
fun getNextX() : Int {
static val x: Int = 0 // this is not Kotlin code
x++;
return x;
}
I want to:
Limit x variable scope to emphasize that this object is only used by this function and protect it from changes from outside
Initialize it only once
Keep value/state between function calls
Example above was simplified. In fact I need something like this for ArrayList with limited scope, but retaining state.
I realize that we have singleton pattern which is almost perfect for such needs (except limited scope), but maybe Kotlin offers something else?

There isn't anything similar to that in Kotlin, but to simulate a similar effect, you can declare an object with all your static variables as properties, and put the function body in an invoke operator:
object NextX {
private var x = 0
operator fun invoke() = x++
}
You basically create an object, but syntactically, it works like a function that you can call:
fun main() {
println(NextX()) // 0
println(NextX()) // 1
println(NextX()) // 2
}
If you think of the entire object as your function, then x is indeed only accessible within the "function".

Functions in Kotlin are stateless, so this is not possible out of the box.
You can get creative though, by having an object with a function which returns the function you desire.
val foo: () -> Int = object {
var x = 0
fun createFunc() = fun() = x++
}.createFunc()
foo() // 0
foo() // 1
Note how x doesn't even have to be private, because the object itself cannot be referenced.
This would meet your criteria.

Related

Why am I able to have null values in non-null variables?

Here is my kotlin class:
class Test{
val x: String = run {
y
}
val y: String = run {
x
}
}
The variables x and y both end up as null, despite being declared as non-nullable strings.
You can run it here. As you can see, you end up with null pointer exceptions from trying to call methods on x or y.
Why is this possible? How can you really have null safety with this in mind?
Well this is what your class decompiles to in Java:
public final class Test {
#NotNull
private final String x;
#NotNull
private final String y;
#NotNull
public final String getX() {
return this.x;
}
#NotNull
public final String getY() {
return this.y;
}
public Test() {
Test $this$run = (Test)this;
int var3 = false;
String var5 = $this$run.y;
this.x = var5;
$this$run = (Test)this;
var3 = false;
var5 = $this$run.x;
this.y = var5;
}
}
So your backing fields, x and y are declared first. They're not assigned a value yet so, in Java, that means their value is null because that's the default for an unassigned object reference.
After the getters, you have the constructor which is where the assignation is taking place. There are a few weird variables going around, but
Test $this$run = (Test)this;
is basically creating a variable that refers to this, the current object. And we can kinda reduce the assignment code down to
this.x = this.y // y is null, so x is set to null
this.y = this.x // x is null, so y is set to null
Because that default value for object references is null, whichever of your assignments runs first will always be reading a null value from the other variable (which, remember, you haven't explicitly assigned a value to yet).
Basically the order of initialisation matters in Kotlin, you can't refer to something that hasn't been declared yet. Like this won't work either:
class Thing {
val a = b
val b = "hi"
}
On the line where a is being assigned, the value of b is currently undefined. It won't run on the JVM either, because that code decompiles to basically this:
public final class Thing {
#NotNull
private final String a;
#NotNull
private final String b;
public Thing() {
this.a = this.b;
this.b = "hi";
}
}
and that this.a = this.b line will fail because "b may not have been initialised yet". You can get around that with the same trick in the decompiled version of your code, with the other variable assigned to this:
public Thing() {
Thing thing = (Thing) this;
this.a = thing.b;
this.b = "hi";
}
which will run, but a ends up assigned with the default value of null.
So basically, the code you're using is a tricky way to get around that kind of error and ultimately give you unexpected behaviour. Obviously your example is unrealistic (the results of a = b = a are inherently undefined), but it can happen with this kind of code too, where initialisation goes through other functions:
class Wow {
val a = doSomething()
val b = 1
fun doSomething() = b
}
In this case a ends up 0 on the JVM, the default value for an int, because when assigning a it basically goes on a detour through a function that reads b before that's been assigned its value. Kotlin (currently) doesn't seem to be capable of checking the validity of this kind of thing - so you'll run into problems trying to initialise things via functions sometimes:
class Wow {
// unassigned var
var a: Int
val b = 1
init {
// calls a function that assigns a value to a
doSomething()
}
fun doSomething() { a = 5 }
}
That will fail because it can't determine that a has been initialised, even though the init block does so, because it's happening as a side effect of another function. (And you could bury that assignment in any number of chained calls, which is probably why it's not a thing that's been "fixed" - if you start making guarantees about that kind of thing, it needs to be consistent!)
So basically, during initialisation you can do things which the compiler isn't able to catch, and that's how you can get around things like non-null guarantees. It doesn't come up often, but it's something to be aware of! And I'm only familiar with the JVM side, I'm assuming the undefined behaviour is platform-specific.
According to the Kotlin docs, "Data inconsistency with regard to initialization" can result in a NullPointerException.
Here are a couple links related to the topic:
https://kotlinlang.org/docs/null-safety.html#nullable-types-and-non-null-types
https://kotlinlang.org/docs/inheritance.html#derived-class-initialization-order
Edit: An example of a wrong answer! It's not circular: x is initialised to null because y is null at the time x is initialised (being uninitialised).
Well, it's circular. x is not null because y is not null which is not null because x is not null.
So it's not a valid program. Meaningful type inference can only be applied to valid programs.

Are Kotlin scope function blocks effectively inline?

I'm writing a Kotlin inline class to make Decimal4J more convenient without instantiating any objects. I'm worried that scope functions might create lambda objects, thereby making the whole thing pointless.
Consider the function compareTo in the following example.
/* imports and whatnot */
#JvmInline
value class Quantity(val basis: Long) {
companion object {
val scale: Int = 12
val metrics: ScaleMetrics = Scales.getScaleMetrics(scale)
val arithmetic: DecimalArithmetic = metrics.defaultArithmetic
}
operator fun compareTo(alt: Number): Int {
with(arithmetic) {
val normal = when (alt) {
is Double -> fromDouble(alt)
is Float -> fromFloat(alt)
is Long -> fromLong(alt)
is BigDecimal -> fromBigDecimal(alt)
is BigInteger -> fromBigInteger(alt)
else -> fromLong(alt.toLong())
}
return compare(basis, normal)
}
}
}
Does the with(arithmetic) scope create a lambda in the heap? The docs on kotlinlang.org consistently refer to the scoped code as a lambda expression. Is there any way to use scope functions without creating objects?
All of the built-in scoping functions, including with, are marked inline, which means the implementation gets planted directly in the code that's calling it. Once that happens, the lambda call can be optimized away.
To be more concrete, here's the implementation of with (with the Kotlin contracts stuff removed, since that's not relevant here)
public inline fun <T, R> with(receiver: T, block: T.() -> R): R {
return receiver.block()
}
Extension methods are, and always have been, syntax sugar resolved at compile time, so this is effectively
public inline fun <T, R> with(receiver: T, block: (T) -> R): R {
return block(receiver) // (with `this` renamed by the compiler)
}
So when we call
operator fun compareTo(alt: Number): Int {
with (arithmetic) {
println("Hi :)")
println(foobar()) // Assuming foobar is a method on arithmetic
}
}
The inline will transform this into
operator fun compareTo(alt: Number): Int {
({
println("Hi :)")
println(it.foobar()) // Assuming foobar is a method on arithmetic
})(arithmetic)
}
And any optimizer worth its salt can see that this is a function that's immediately evaluated, so we should go ahead and do that now. What we end up with is
operator fun compareTo(alt: Number): Int {
println("Hi :)")
println(arithmetic.foobar()) // Assuming foobar is a method on arithmetic
}
which is what you would have written to begin with.
So, tl;dr, the compiler is smart enough to figure it out. You don't have to worry about it. It's one of the perks of working in a high-level language.
By the way, this isn't just abstract. I just compiled the above code on my own machine and then decompiled the JVM bytecode to see what it really did. It was quite a bit noisier (since the JVM, by necessity, has a lot of noise), but there was no lambda object allocated, and the function was just one straight shot that calls println twice.
In case you're interested, Kotlin takes this example function
fun compareTo(alt: Number): Unit {
return with(arithmetic) {
println("Hi :)")
println(foobar())
}
}
to this Java, after being decompiled,
public static final void compareTo-impl(long arg0, #NotNull Number alt) {
Intrinsics.checkNotNullParameter((Object)alt, (String)"alt");
long l = arithmetic;
boolean bl = false;
boolean bl2 = false;
long $this$compareTo_impl_u24lambda_u2d0 = l;
boolean bl3 = false;
String string = "Hi :)";
boolean bl4 = false;
System.out.println((Object)string);
int n = so_quant.foobar-impl($this$compareTo_impl_u24lambda_u2d0);
bl4 = false;
System.out.println(n);
}
Quite a bit noisier, but the idea is exactly the same. And all of those pointless local variables will be taken care of by a good JIT engine.
Just some additional info to help clear up the terminology that led to your confusion.
The word “lambda” is defined as a syntax for writing a function. The word does not describe a function itself, so the word lambda has nothing to do with whether a function object is being allocated or not.
In Kotlin, there are multiple different syntaxes you can choose from to define or refer to a function. Lambda is only one of these.
// lambda assigned to variable
val x: (String) -> Unit = {
println(it)
}
// anonymous function assigned to variable
val y: (String) -> Unit = fun(input: String) {
println(input)
}
// reference to existing named function assigned to variable
val z: (String) -> Unit = ::println
// lambda passed to higher order function
“Hello World”.let { println(it) }
// anonymous function passed to higher order function
“Hello World”.let(fun(input: Any) { println(input) })
// reference to existing named function passed to higher order function
“Hello World”.let(::println)
// existing functional reference passed to higher order function
“Hello World”.let(x)
There is actually no such thing as a lambda object that can be passed around. The object is a function that could have been defined using any of the above syntaxes. Once a functional reference exists, the syntax that was used to create it is irrelevant.
With inline higher order functions, as the standard library scope functions are, the compiler optimizes away the creation of the functional object altogether. Of the four higher order calls in my example above, the first three will compile to the same thing. The last is a bit different because the function x already exists so it will be x itself that is invoked in the inlined code. Its contents don’t get hoisted out and called directly in the inlined code.
The advantage of using lambda syntax for higher order inline function calls is that it enables you to use keywords for the outer scope (non-local returns), such as return, continue, or break.

How to pass a variable from main function to another function and modify it? (Kotlin)

I am aware that an argument passed to a function will be seen as "val", even if the variable was initialized as "var". But this has been a problem for me. In this example code below, I want to modify the value of variable "num" by using the function "changeNum". But of course, Kotlin won't allow me to modify it. How do I get around this? How can I use the function "changeNum" to modify the variable "num"?
fun main() {
var num: Int = 5
changeNum(num)
}
fun changeNum(num: Int){
num += 2
print(num)
}
Kotlin is pass-by-value, so you can't do that directly with primitive types like Int.
The usual approach is to just return a new value instead of modifying what you receive as argument (a functional approach). It makes it clearer from the calling code's perspective:
fun main() {
var num: Int = 5
num = changeNum(num)
}
fun changeNum(num: Int): Int {
val newValue = num + 2
print(newValue)
return newValue
}
If you really want to mutate the variable instead of returning a new value, here are 2 approaches I'm thinking of to do this:
put all the code operating on this value into a class, and make the local variable a property of that class (this is the OO approach)
put this primitive variable into a class, and pass an instance of that class
Option 1 would look like this:
class SomeClass(var num: Int) {
fun changeNum() {
num += 2
print(num)
}
}
fun main() {
val container = SomeClass(5)
container.changeNum()
}
Option 2 would look like this:
class SomeMutableContainer(var num: Int)
fun main() {
val container = SomeMutableContainer(5)
changeNum(container)
}
fun changeNum(container: SomeMutableContainer) {
container.num += 2
print(container.num)
}
It's possible to do this in Kotlin with a property
import kotlin.reflect.KMutableProperty0
var num = 1
fun main() {
println(num)
changeNum(::num)
println(num)
}
fun changeNum(numProperty: KMutableProperty0<Int>) {
numProperty.set(12345)
}
>> 1
>> 12345
A KMutableProperty0 represents a basic var, so you can pass in a property reference using the ::num syntax (same as how you'd pass a function reference). That way, instead of passing the current value, you're providing the function with a reference to the property itself, and then you can call set on it.
But the question is, do you really want to do this? Or are you overcomplicating something that should be done in a more simple way, or a more readable one? You can't actually do this with a variable, like you're trying to do inside fun main(), only properties on an object (top-level vars, basically) - but even if you could, why wouldn't you just do this instead?
fun main() {
var num: Int = 5
...
num = changeNum(num) // this would need renaming but y'know
}
it's still a one-line call, your changeNum function can still have side effects, do validation etc, it just returns the result instead of setting it as a side effect. This is a lot easier to follow, especially when it's the usual way of setting a value on a thing.
If you really want to use references, but making them top-level in your class is messy, then maybe consider creating a state object instead:
import kotlin.reflect.KMutableProperty0
data class AllThemNums(var num1 :Int = 1, var num2: Int = 9999)
fun main() {
val nums = AllThemNums(num1 = 5)
changeNum(nums::num1)
println(nums)
}
fun changeNum(numProperty: KMutableProperty0<Int>) {
numProperty.set(numProperty.get() + 2)
}
>> AllThemNums(num1=7, num2=9999)
you could even put the changeNum function inside the data class!
Im my project, I've defined a generic type for enclosing all scalar types, both primitives and user-defined.
data class pTp<T>(var v: T)
So I can create
fun PercAcumNorm(percAcum:pTp<Double>, perc:pTp<Double>,
valor:Double, Soma:Double)
{
perc.v = valor/soma
parcAcum.v += perc.v
}
Then one just needs to call
....
var pAcum:pTp<Double> = pTp(0.40)
var p = 0
var valor = 5
var soma = 100
percCalc(pAcum, p, soma, valor)
println(pAcum.v) // it prints 0.45
It's not the cleanest solution, but it's what can be done without using Kotlin's built-in features, which may be modified in the future.

Pass an Integer by Reference in Kotlin

I am trying to create a swap function which takes in two parameters as shown below:
fun swap(a :Int, b:Int) {
}
I call it like this:
var a = 10
var b = 5
swap(a,b)
// a should be 5
// b should be 10
The problem is that even if I swap the values inside the swap function it won't be reflected on the caller's side because it is passed as a copy and not as a reference.
Is there anyway to pass value types to swap function and allow the function the ability to change them.
There is absolutely no way to do it directly. Kotlin copies a value for scalar types (Double, Float, Boolean, Int, etc.). So any internal changes are lost.
For any other type, Kotlin copy a reference of parameter passed to the function. So any property/field alteration of parameter, also changes the caller parameter.
There is no way to change this behaviour.
After trying many ways to overcome the impossibility of passing scalar by reference, as happens in Kotlin, Java and some other languages; my current strategy is using for any scalar type a plain and generic wrap, as an above comment suggest.
Recently, I'm using this trick for everything, including inside a function that otherwise would demand that I return multiple values. The alternative is joining the returns in a artificial class or destructuring declarations: val (a, b, c) = function-call() syntax. However, I hate articial classes and destructuring declaration is for local variables only, and it's annoying when some needs visibility out of current block of commands.
My code is very simple:
data class p<T>( // It's a generic wrap class for scalar type T
var v:T
)
fun <T>swap(a:p<T>, b:p<T>){ // It's a generic swap for scalar types
var aux:p<T> = a.copy()
a.v = b.v
b.v =aux.v
}
fun main() {
var a:p<Int> = p<Int>(2) // 'a' is a kind of 'Int' variable
var b:p<Int> = p<Int>(3) // and so is 'b'
swap(a,b) // Exchange 'a' and 'b' values
println(a.v) // 3
println(b.v) // 2
}
The only drawback is not being able to use syntax sugar of a real scalar type.
I am forced to add .v on any use of a scalar variable.
I only uses that for variables that I need pass by reference in some function and it's not so common. I try, when possible, avoid collateral effects.
You can have a function that gets the references of variables
var x = 10
var y = 20
fun main() {
println("x=$x, y=$y") // x=10, y=20
swap(::x, ::y)
println("x=$x, y=$y") // x=20, y=10
}
fun <T> swap(firstRef: KMutableProperty0<T>, secRef: KMutableProperty0<T>) {
val temp = firstRef.get()
firstRef.set(secRef.get())
secRef.set(temp)
}
and you can pass the references of properties of some class like this swap(someClass::x, someClass::y)
the only limitation is that you can't pass references of local variables which is not the end of the world.
if you don't like the messy syntax you can always define a typealias and make it pretty:
typealias Ref<T> = KMutableProperty0<T>
fun <T> swap(firstRef: Ref<T>, secRef: Ref<T>) {
...
}
I know that OP didn´t ask for this, but idiomatic Kotlin would look like:
var a = 1
var b = 2
a = b.also { b = a }
Seems like Kotlin behaves pretty much like Java does:
Is Kotlin "pass-by-value" or "pass-by-reference"?
simple way to swap is make support class
private fun swap(pair: Pair) {
pair.a += pair.b
pair.b = pair.a - pair.b
pair.a = pair.a - pair.b
}
private data class Pair(var a: Int, var b: Int)
fun main() {
val pair = Pair(10, 5)
swap(pair)
println(pair)
}

Why is the method strikethrough?

I have defined a class like this:
internal class C {
internal func method() -> Void {
print("method called")
}
}
If I declare a closure from that method, the method is shown strikethrough
let closure = C.init().meth
let closure2 = C.meth
The same happens if I use it in the autocasting paranthesis \(...)
print("\(C.init().meth)")
Xcode examples:
The strike-through is happening because your function method() returns nothing. The contexts that you're trying to complete in (assignment and interpolation) both expect values, so a method that returns Void is not recommended there.
You will see the same strikethrough if you try to assign the result of system functions that returns nothing e.g. if you do:
var arr = [1,2,3]
arr.append(4) // no strikethrough
let result = arr.append(5) // you will see strikethough on 'append'