0

I'm trying to reply this answer Kotlin: Specify input-constraints in interface and my idea was to create a function that implements some validation and allowing the function to be validated to be called only in the context of the validation function. Is it possible? That's my current code:

interface MathThing {

    fun mathFunction(x: Int)
}

fun validationContext(x: Int, block: (Int) -> Unit){
    require(x > 0)
    block(x)
}

fun main() {

    val o = object : MathThing {
        override fun mathFunction(x: Int) {
            println(x)
        }
    }

    validationContext(-1, o::mathFunction)

}
Diego Marin Santos
  • 1,923
  • 2
  • 15
  • 29

1 Answers1

1

the problem in your code, is that you don't actually call the o::mathFunction in a block. You rather just reference it. in this case it is just no-op.

You can fix it by passing mathFunction as a param, or explicitly calling it inside the block:

validateContext(1) {
    o.mathFunction(it)
}
// ok. => 1

validateContext(1, o::mathFunction)
// ok. => 1

validateContext(-1, o::mathFunction)
// validation error

update

the short answer is 'no'. you can't easily restrict that, unless your language has dynamically bound execution context.

what you can try, is to throw error, analyze stacktrace and decide if it the needed context function is in call stack. But this would be really slow and painful.

i would do something like this, to be sure the function is always validated

val o = object : MathThing {
    override fun mathFunction(x: Int) = validateContext(x) {
        println(it)
    }
}
leetwinski
  • 17,408
  • 2
  • 18
  • 42
  • My code is working fine. In your first example you are passing 1 as parameter which is fine. If you pass -1 a validation error is gonna happen. The question isn't about how to call the function in a block, but it is about how to enforce that it can only be called in the context of a specific function. – Diego Marin Santos May 12 '20 at 17:13
  • 1
    i guess it doesn't. try `validateContext(1) { o::mathFunction }`, it obviously doesn't print anything – leetwinski May 12 '20 at 17:16
  • 1
    You are right, validation still works, but function isn't executed. Thanks, for the correction, I'm gonna update my question. But the question isn't about it, as I said it is about the possibility of enforcing `mathFunction` to be called only inside `validateContext`. – Diego Marin Santos May 12 '20 at 17:21
  • My idea was to have something like launch `launch` builder which can only be called on a CoroutineScope. I was planning to have a function as receiver of `mathFunction`, but seems that it is not possible. – Diego Marin Santos May 12 '20 at 18:17