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

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

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.

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.

Related

How to know if a method has been defined in an interface

Given the following code:
interface MyInterface {
fun foo() {
// body
}
fun bar() {
// body
}
}
class MyInterfaceImpl: MyInterface {
override fun bar() {
// body
}
}
I need to know at runtime that bar() has been overridden and foo() hasn't. How to do this using reflection?
Note: java.lang.reflect.Method#getDeclaringClass() always returns MyInterfaceImpl::class.java and java.lang.reflect.Method#isDefault() always returns false. I did not find the solution in KClass.
From what I know, where are two ways to achieve that dubious goal.
I'll demonstrate easy one, and discuss idea behind the harder one.
Easy one is based on simply calling toString() on the method:
val functions = MyInterfaceImpl::class.functions
val bar = (functions.toList()[0])
val foo = (functions.toList()[2])
println(bar.toString()) // fun MyInterfaceImpl.bar(): kotlin.Unit
println(foo.toString()) // fun MyInterface.foo(): kotlin.Unit
As you can see, you can figure if the method was overridden or not by parsing the string.
Harder solution would be to dig into KFunctionImpl, which has delegate member, which has dispatchReceiverParameter
That's a lot of nasty reflection, which is even more nasty, because most of those classes are internal and lazily initialized.
We can compare MyInterfaceImpl::class.declaredFunctions and MyInterface::class.declaredFunctions.
This property lists all functions declared in this class.

Kotlin Either monad: Refactoring a constructor call to handle CPS

I am an absolute beginner in functional programming and Kotlin, trying to solve exercises that I created from questions I'm asking myself; my current question being "How to put in practice functional programming onto real world applications using a Ports and Adapters architecture?"
Currently learning about the Either monad, I have the following function in which Perhaps<T> is just a renamed Either<Err, T> for use with exception handling.
This function takes a RequestModel containing arbitrary HTTP parameters, and may Perhaps return a CountBetweenQuery which is just a data class containing two LocalDate.
private fun requestCountBetweenQueryA(model: RequestModel): Perhaps<CountBetweenQuery> {
return try {
Perhaps.ret(CountBetweenQuery(extractLocalDateOrThrow(model, "begin"), extractLocalDateOrThrow(model, "end")))
} catch (e: UnsupportedTemporalTypeException) {
Perhaps.Fail(Err.DATE_FORMAT_IS_INVALID)
} catch (e: DateTimeException) {
Perhaps.Fail(Err.DATE_FORMAT_IS_INVALID)
}
}
private fun extractLocalDateOrThrow(it: RequestModel, param: String): LocalDate =
LocalDate.from(DateTimeFormatter.ISO_DATE.parse(it.parameters.first { it.key == param }.value))
In an OO language, I would refactor this so that exception handling either way below in a common exception handler, or higher above (where duplicated code is extracted into a single method). Naturally, I want to turn my extractLocalDateOrThrow into a perhapsExtractLocalDate as part of my exercise:
private fun perhapsExtractLocalDate(it: RequestModel, param: String): Perhaps<LocalDate> = try {
Perhaps.ret(LocalDate.from(DateTimeFormatter.ISO_DATE.parse(it.parameters.first { it.key == param }.value)))
} catch (e: UnsupportedTemporalTypeException) {
Perhaps.Fail(Err.DATE_FORMAT_IS_INVALID)
} catch (e: DateTimeException) {
Perhaps.Fail(Err.DATE_FORMAT_IS_INVALID)
}
I have struggled for an hour trying to figure out how to call the constructor of CountBetweenQuery while preserving the continuation passing style.
This is what I came up with:
private fun requestCountBetweenQueryB(me: RequestModel): Perhaps<CountBetweenQuery> {
val newCountBetweenQueryCurried: (begin: LocalDate) -> (end: LocalDate) -> CountBetweenQuery =
::CountBetweenQuery.curried()
return Perhaps.ret(newCountBetweenQueryCurried)
.bind { function -> perhapsExtractLocalDate(me, "begin").map(function) }
.bind { function -> perhapsExtractLocalDate(me, "end").map(function) }
}
At first I had expected to use return and apply because the two method calls perhapsExtractLocalDate are independent, therefore I would use an applicative style. Instead I was unable to figure out how to avoid using bind, which is from my understanding implies a monadic style.
My questions are:
If my understanding is correct, how can I turn this into applicative style?
Are there any gross mistakes made in the implementations above? (i.e. idioms, misuse of currying)
I believe I understood what was wrong.
In FP examples written in a proper functional programming language, applicative style is written like someFunction map a apply b but in Kotlin, because we are dealing with methods of objects, this is written in the reserve order when reading from left to right, but in the correct order in terms of argument evaluation. This confused me very much.
private fun requestCountBetweenQueryC(me: RequestModel): Perhaps<CountBetweenQuery> {
val newCountBetweenQueryCurried: (begin: LocalDate) -> (end: LocalDate) -> CountBetweenQuery =
::CountBetweenQuery.curried()
val a = perhapsExtractLocalDate(me, "begin")
val b = perhapsExtractLocalDate(me, "end")
return b.apply(a.map(newCountBetweenQueryCurried))
}
If my understanding is correct, this is also known as the lift2 function.

Access Kotlin Delegate Type without an Instance

I have read Access property delegate in Kotlin which is about accessing a delegate from an instance. One can use KProperty::getDelegate since Kotlin 1.1, however this will return the instance of the delegate and therefore needs an instance of the class first.
Now I want to get the type of the delegate without having an instance of the class. Consider a library with a custom delegate type CustomDelegate that want's to get all properties of a class that are delegated to an instance of CustomDelegate:
class Example
{
var nonDelegatedProperty = "I don't care about this property"
var delegatedProperty1 by lazy { "I don't care about this too" }
var delegatedProperty2 by CustomDelegate("I care about this one")
}
How can I, given I have KClass<Example>, but not an instance of Example, get all properties delegated to CustomDelegate?
How can I, given I have KClass<Example>, but not an instance of
Example, get all properties delegated to CustomDelegate?
You can do it in two ways depending on your needs.
First of all, you have to include the kotlin-reflect dependency in your build.gradle file:
compile "org.jetbrains.kotlin:kotlin-reflect:1.1.51"
In my opinion, you should use the first solution if you can, because it's the most clear and optimized one. The second solution instead, can handle one case that the first solution can't.
First
You can loop an the declared properties and check if the type of the property or the type of the delegate is CustomDelegate.
// Loop on the properties of this class.
Example::class.declaredMemberProperties.filter { property ->
// If the type of field is CustomDelegate or the delegate is an instance of CustomDelegate,
// it will return true.
CustomDelegate::class.java == property.javaField?.type
}
There's only one problem with this solution, you will get also the fields with type CustomDelegate, so, given this example:
class Example {
var nonDelegatedProperty = "I don't care about this property"
val delegatedProperty1 by lazy { "I don't care about this too" }
val delegatedProperty2 by CustomDelegate("I care about this one")
val customDelegate = CustomDelegate("jdo")
}
You will get delegatedProperty2 and customDelegate. If you want to get only delegatedProperty2, I found an horrible solution that you can use if you need to manage this case.
Second
If you check the source code of KPropertyImpl, you can see how a delegation is implemented. So, you can do something like this:
// Loop on the properties of this class.
Example::class.declaredMemberProperties.filter { property ->
// You must check in all superclasses till you find the right method.
property::class.allSuperclasses.find {
val computeField = try {
// Find the protected method "computeDelegateField".
it.declaredFunctions.find { it.name == "computeDelegateField" } ?: return#find false
} catch (t: Throwable) {
// Catch KotlinReflectionInternalError.
return#find false
}
// Get the delegate or null if the delegate is not present.
val delegateField = computeField.call(property) as? Field
// If the delegate was null or the type is different from CustomDelegate, it will return false.
CustomDelegate::class.java == delegateField?.type
} != null
}
In this case, you will get only delegatedProperty2 as result.

Kotlin class literals with empty left hand side are not yet supported?

I am trying to check if a type conforms to a another type with an if expression like so:
if (String::class is Any::class)
This gives me the error class literals with empty left hand side are not yet supported. Can anyone elaborate on that error and/or tell me how I should be doing this check?
edit (clarification): I can't do an equality check because I need to know if the class on the left either matches the class on the right or is a subclass of it. So if an instance of the class on the left can be safely cast to the class on the right.
Basically I need the equivalent of:
if ("A string" is Any)
But without having a String instance, String just being used an example here.
I guess it wouldn't be clear if Kotlin used the is operator differently between a KClass and another KClass as it does between an instance and a type which is why what I was trying to do doesn't work. Anyway I made this little infix function to imitate the functionality. However it only works with JVM target of course since it's using Java reflection. This is going off of the answer given in this SO post.
infix fun <T : Any, C : Any> KClass<T>.can(comparate: KClass<C>) =
comparate.java.isAssignableFrom(this.java)
This will allow you to do exactly what I was trying to do but with the can function instead of the is operator like so:
if(String::class can Any::class)
Your error message is that the is check expects a class name and not a reference to a KClass on the right side. The message itself might be a little unclear. But the same applies in Java, you would not use instanceOf operator but instead would call isAssignableFrom.
For help on solving the problem, you have examples that can be found in Github...
In the Klutter library are examples of a lot of combinations of instanceOf style checking between Class, KClass, Type and KType as well as primitives. You can copy ideas from there. There are many combinations that you might want to have covered in the long run.
Here is a sampling of a big mix of extensions for checking if one type is assignable from the other. A few examples are:
fun <T : Any, O : Any> KClass<T>.isAssignableFrom(other: KClass<O>): Boolean {
if (this.java == other.java) return true
return this.java.isAssignableFrom(other.java)
}
fun <T : Any> KClass<T>.isAssignableFrom(other: Class<*>): Boolean {
if (this.java == other) return true
return this.java.isAssignableFrom(other)
}
fun KClass<*>.isAssignableFromOrSamePrimitive(other: KType): Boolean {
return (this.java as Type).isAssignableFromOrSamePrimitive(other.javaType)
}
fun KClass<*>.isAssignableFromOrSamePrimitive(other: Type): Boolean {
return (this.java as Type).isAssignableFromOrSamePrimitive(other)
}
fun Type.isAssignableFromOrSamePrimitive(other: Type): Boolean {
if (this == other) return true
if (this is Class<*>) {
if (other is Class<*>) {
return this == other.kotlin.javaObjectType || this == other.kotlin.javaPrimitiveType ||
this.isAssignableFrom(other)
}
return this.isAssignableFrom(other.erasedType())
}
return this.erasedType().isAssignableFrom(other.erasedType())
}
// ... and so on for every permutation of types
See the linked source for all permutations.
And you will need this erasedType() extension used by the above samples -- which goes from a Type back to a Class (after type erasure):
#Suppress("UNCHECKED_CAST") fun Type.erasedType(): Class<Any> {
return when (this) {
is Class<*> -> this as Class<Any>
is ParameterizedType -> this.getRawType().erasedType()
is GenericArrayType -> {
// getting the array type is a bit trickier
val elementType = this.getGenericComponentType().erasedType()
val testArray = java.lang.reflect.Array.newInstance(elementType, 0)
testArray.javaClass
}
is TypeVariable<*> -> {
// not sure yet
throw IllegalStateException("Not sure what to do here yet")
}
is WildcardType -> {
this.getUpperBounds()[0].erasedType()
}
else -> throw IllegalStateException("Should not get here.")
}
}

extending structs with (relatively) unknown/arbitrary methods, go reflection(or avoiding reflection)

The below does not work obviously:
Arbitrary := struct {
field1 string
field2 string
}{"a", "b"}
fmap := make(map[string]func(string) string)
fmap["fone"] = func(s string) string { fmt.Printf("function fone: %s", s) }
fmap["ftwo"] = func(s string) string { fmt.Printf("function ftwo: %s", s) }
// probably ok, as simple examples go, to this point where reflection needs to be used
// the below does not work
Arbitrary.fone = fmap["fone"]
Arbitrary.fone("hello")
The above is the core of what I'm trying to do: create a struct with values, and then create methods on the struct from a map of functions, or functions passed in. Basically I have a structure with data & ambiguous behavior that needs to be extended with methods unknown until creating the type.
I'm looking for the obvious & inevitable:
How to do this in Go
Why this shouldn't be done, or can't be done in Go (its possible with the reflect package, I just haven't found examples or reasoned thorough it yet)
How this should be done in Go (some sort of interface construct I've not figured out wholly. I've tried an interface which can handle the behavior; but it doesn't account for other behaviors that might be added, at the least I haven't figured out interface usage fully yet which is part of the issue)
If you're a person needing complexity here is the start of the actual task I'm trying to accomplish, making that structs behavior extendable.
I completely misunderstood the question.
NO, you can't create a new struct out of thin air and assign fields to it, also even if you could, for the love of everything that's holy, don't do that.
You can use multiple interfaces for example:
type Base interface {
Id() int //all structs must implement this
}
type Foo interface {
Base
Foo()
}
type Bar interface {
Base
Bar()
}
then make a map[string]Base, and you can assert the value later.
//leaving the original answer as a different approach to the problem.
While usually that kind of stuff is done using reflection, if you have a limited number of accepted "callbacks" you can use type assertion and an interface{} map, dropping the need for reflection.
var ctx = &Ctx{"Hello"}
var funcs = map[string]interface{}{
"m3": ctx.Do,
"m4": func(c *Ctx) { fmt.Println("ctx:", c) },
}
type Ctx struct {
Name string
}
func (c *Ctx) Do() {
fmt.Printf("Do: %+v\n", c)
}
func call(m string) {
if f, ok := funcs[m]; ok {
switch fn := f.(type) {
case func():
fn()
case func(*Ctx):
fn(&Ctx{"Hello world"})
default:
panic(fn)
}
}
}
playground

Resources