Writing a Kotlin util function which provides self-reference in initializer

kotlin reflection example
kotlin method reference
kotlin lambda
kotlin kclass generic
kotlin extension function
kotlin generics
kotlin reflection create instance
kotlin apply

I'm trying to generalize my hack from an answer to another question.

It should provide a way to reference a value which is not constructed yet inside its initializer (of course, not directly, but in lambdas and object expressions).

What I have at the moment:

class SelfReference<T>(val initializer: SelfReference<T>.() -> T) {
    val self: T by lazy {
        inner ?: throw IllegalStateException("Do not use `self` until initialized.")
    }

    private val inner = initializer()
}

fun <T> selfReference(initializer: SelfReference<T>.() -> T): T {
    return SelfReference(initializer).self
}

It works, see this example:

class Holder(var x: Int = 0,
             val action: () -> Unit)

val h: Holder = selfReference { Holder(0) { self.x++ } }
h.action()
h.action()
println(h.x) //2

But at this point the way in which initializer references the constructed value is self property.

And my question is: is there a way to rewrite SelfReference so that initializer is passed an argument (or a receiver) instead of using self property? This question can be reformulated to: is there a way to pass a lazily evaluated receiver/argument to a function or achieve this semantics some way?

What are the other ways to improve the code?


UPD: One possible way is to pass a function that returns self, thus it would be used as it() inside the initializer. Still looking for other ones.

The best I have managed to produce while still being completely generic is this:

class SelfReference<T>(val initializer: SelfReference<T>.() -> T)  {
    val self: T by lazy {
        inner ?: throw IllegalStateException("Do not use `self` until initialized.")
    }

    private val inner = initializer()
    operator fun invoke(): T = self
}

Adding the invoke operator lets you use it in the following way:

val h: Holder = selfReference { Holder(0) { this().x++ } }

This is the closest I got to make it look like something you would "normally" write.

Sadly I think it is not possible to get completely rid of a explicit access to the element. Since to do that you would need a lambda parameter of type T.() -> T but then you wouldn't be able to call that parameter without an instance of Tand being T a generic there is no clean and safe way to acquire this instance.

But maybe I'm wrong and this helps you think of a solution to the problem

Reflection. Reflection is a set of language and library features that allows for The most basic reflection feature is getting the runtime reference to a Kotlin class. In this article, you will learn about constructors in Kotlin (both primary and secondary constructors) as well as initializer blocks with the help of examples. A constructor is a concise way to initialize class properties. It is a special member function that is called when an object is instantiated (created).

is there a way to rewrite SelfReference so that initializer is passed an argument (or a receiver) instead of using self property? This question can be reformulated to: is there a way to pass a lazily evaluated receiver/argument to a function or achieve this semantics some way?

I'm not sure I completely understand your use case but this may be what you're looking for:

fun initHolder(x: Int = 0, holderAction: Holder.() -> Unit) : Holder {
    var h: Holder? = null
    h = Holder(x) { h!!.holderAction() }
    return h
}

val h: Holder = initHolder(0) { x++ }
h.action()
h.action()
println(h.x) // 2

This works because holderAction is a lambda with a receiver (Holder.() -> Unit) giving the lambda access to the receiver's members.

This is a general solution since you may not be able to change the signature of the respective Holder constructor. It may be worth noting this solution does not require the class to be open, otherwise a similar approach could be done with a subclass using a secondary constructor.

I prefer this solution to creating a SelfReference class when there are only a few number of classes that need the change.

You may want to check for null instead of using !! in order to throw a helpful error. If Holder calls action in it's constructor or init block, you'll get a null pointer exception.

We can reference the function itself by prefixing its name with :: , and we can assign it to a Like in Python, you can write lambda expressions: unnamed function declarations with a very which is similar to Python's generators and allows for lazy evaluation. def node(self, name, initialize=None): Nice utility functions. Unit Testing in Kotlin is fun and tricky at the same time. We can benefit a lot from Kotlin’s powerful language features to write readable and concise unit tests. But in order to write idiomatic Kotlin test code in the first place, there is a certain test setup required.

I'm pretty sure you can achieve the same results in a more readable and clear way using something like this:

fun <T> selfReferenced(initializer: () -> T) = initializer.invoke()
operator fun<T> T.getValue(any: Any?, property: KProperty<*>) = this

and later use

val valueName: ValueType by selfReferenced{
    //here you can create and use the valueName object
}

Using as example your quoted question https://stackoverflow.com/a/35050722/2196460 you can do this:

val textToSpeech:TextToSpeech by selfReferenced {
TextToSpeech(
        App.instance,
        TextToSpeech.OnInitListener { status ->
            if (status == TextToSpeech.SUCCESS) {
                textToSpeech.setLanguage(Locale.UK)
            }
        })
    }

Inside the selfReferenced block you can use the outer object with no restrictions. The only thing you should take care of, is declaring the type explicitly to avoid recursive type checking issues.

A good example is the functional programming idiom fold for collections, which Function references can also be used for higher-order function calls: member, or extension property: List<Int>::size ,; a constructor: ::Regex Sometimes it is beneficial to use inline functions, which provide flexible control  How to reference a lambda from inside it? In Kotlin (not accepting "this"): Writing a Kotlin util function which provides self-reference in initializer.

The result is an object which represents a reference to the property (the "Platonic ideal" Using this, we can start writing functions that manipulate properties without e.g. what properties and functions it contains and which annotations exist on them. Constructor references are effectively factory functions for creating new  Kotlin allows removing the unnecessary wrapping util class and use top-level functions instead. Often, we can additionally leverage extension functions, which increases readability. This way, our code feels more like “telling a story”.

In such a class some standard functionality and utility functions are often the following members from all properties declared in the primary constructor: Providing explicit implementations for the componentN() and copy() functions is Since 1.1, data classes may extend other classes (see Sealed classes for examples). Kotlin considers a property uninitialized until the end of its initializer, therefore it cannot be used inside its own initializer, even in lambdas. This semantics is similar to the limitation of local variable usage inside its initializer .

It contains well written, well thought and well explained computer science and programming articles, 'this' is a reference variable that refers to the current object. Using this() to invoke current class constructor Using 'this' keyword as method parameter RecursiveTask class in Java with Examples · Java.util.​function. As in Java, classes in Kotlin may have type parameters: In general, to create an instance of such a class, we need to provide the type arguments: But if the parameters may be inferred, e.g. from the constructor arguments or by some other means, one is allowed to omit the type arguments: One of the most tricky parts of Java's type system is

Comments