1

It seems that Kotlin does not support getting local functions etc. Please see the example below:

fun <T> MutableList<T>.filterOnCondition(condition: (T) -> Boolean): MutableList<T> { // For the printline, trying to get the function name, // which in this case is passedAsCondition println(condition.reflect()!!.instanceParameter!!.name) } fun passedAsCondition (number: Int, multipleOf : Int): Boolean { return number % multipleOf == 0 } numbers.filterOnCondition { passedAsCondition(it, 5) } 

Kotlin returns this error as it has not been mapped out yet:

"kotlin.reflect.jvm.internal.KotlinReflectionInternalError: Introspecting local functions, lambdas, anonymous functions and local variables is not yet fully supported in Kotlin reflection"

(https://github.com/JetBrains/kotlin/blob/master/core/reflection.jvm/src/kotlin/reflect/jvm/internal/EmptyContainerForLocal.kt#L41)

BUT, surely this is possible to do via Java, is it not?

3
  • I can write Arrays.asList(5, 6, 10, 13, 15, 24).stream().filter(x -> x % 5 == 0).forEachOrdered(System.out::println); - not sure what you're asking... something about passing a function to filter? Commented Feb 16, 2018 at 7:15
  • I am trying to get the name of the function that is passed into filterOnCondition. For the println(), I would like to see passedAsCondition returned. Commented Feb 16, 2018 at 7:19
  • @Lander, You're reflecting on the lambda. passedAsCondition is in the lambda body. Commented Feb 16, 2018 at 7:26

1 Answer 1

1

It's an anonymous function, thus it's name will be <anonymous>:

val x: (Int) -> Boolean = { passedAsCondition(it, 5) } println(x.reflect()?.name) //prints <anonymous> 

When you have a lambda { passedAsCondition(it, 5) } how would you expect the reflection to work here? passedAsCondition is a simple call made inside the lambda, but you're invoking the reflect on an unnamed, anonymous, lambda, which does not have a name.

Ordinary functions can be used with method references which of course do have a name:

fun x(a: Int): Boolean { passedAsCondition(a, 5) return true } println(::x.name) //gives x 

As a result, making use of proper reflection, the following works:

fun main(args: Array<String>) { mutableListOf(1).filterOnCondition(::passedAsCondition) } fun <T> MutableList<T>.filterOnCondition( condition: KFunction2<@ParameterName(name = "number") Int, @ParameterName(name = "multipleOf") Int, Boolean> ) { println(condition.name) } fun passedAsCondition(number: Int, multipleOf: Int): Boolean = number % multipleOf == 0 
Sign up to request clarification or add additional context in comments.

5 Comments

Thank you, s1m0nw1. I'm quite new to Kotlin here. Is it possible to get the function name of passedAsCondition from within the lambda?
FWIW, if the question sounds unorthodox, you can actually do this in C#, where it used to be semi-common for passing a property name without using a hardcoded string.
An example of what @chris is referring to: this
@s1m0nw1: I see, but would you not lose the ability to pass params into passedAsCondition?
You can still invoke the function, but the arguments need to be passed as extra parameters but it quickly gets ugly tbh. What’s your use case anyways

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.