https://kotlinlang.org logo
#coroutines
Title
# coroutines
s

snowe

04/29/2020, 4:40 AM
I'm trying to use Roman Elizarov's deep recursion implementation with coroutines (https://medium.com/@elizarov/deep-recursion-with-coroutines-7c53e15993e3), but am having a bit of an issue with calling methods from within the recursion function. I'm attempting to use the implementation without modifying it (in the hopes that it is added to the stdlib some day. Say I have this setup.
Copy code
private suspend fun DeepRecursiveScope<Any?, Unit>.ppAny(obj: Any?) {
    DeepRecursiveFunction<Any?, Unit> { obj ->
        ppObj(obj)
    }
}

private suspend fun DeepRecursiveScope<Any?, Unit>.ppObj(obj: Any) {
    ppAny(obj)
}
I need to declare both as suspend and both as extension functions in order for them to be callable from within the DeepRecursiveScope. But
ppAny
is not callable from within
ppObj
, with the error
[NON_LOCAL_SUSPENSION_POINT] Suspension functions can be called only within coroutine body
Now, I understand the issue (I think), in that I need to be calling from within a context with,
with(this@DeepRecursiveScopeImpl)
, but I do not have access to
DeepRecursiveScopeImpl
. Can I use another scope for this? If not, how can I get access to this scope to call my method with? Am I doing stuff completely wrong here???
e

elizarov

04/29/2020, 7:15 AM
What exactly are you trying to achieve? I cannot decipher your intent from the code you've posted. What is its goal?
s

snowe

04/29/2020, 5:49 PM
@elizarov the goal is to simply call other methods from within the recursion. You can see my library code here https://github.com/snowe2010/pretty-print/blob/master/src/main/kotlin/com/tylerthrailkill/helpers/prettyprint/PrettyPrint.kt The entry point into the recursion is here: https://github.com/snowe2010/pretty-print/blob/master/src/main/kotlin/com/tylerthrailkill/helpers/prettyprint/PrettyPrint.kt#L63 You can see that
ppAny
calls different methods at this spot https://github.com/snowe2010/pretty-print/blob/master/src/main/kotlin/com/tylerthrailkill/helpers/prettyprint/PrettyPrint.kt#L91-L96 and then those methods call back to
ppAny
like so https://github.com/snowe2010/pretty-print/blob/master/src/main/kotlin/com/tylerthrailkill/helpers/prettyprint/PrettyPrint.kt#L139 But if I switch to the DeepRecursiveFunction, I cannot call those methods. I have to add them as extension methods on DeepRecursiveFunction. If I do that, then I cannot call
callRecursive
because the scope is not correct.
e

elizarov

04/29/2020, 6:44 PM
There are two ways to declare recursive functions in this framework:
Copy code
val first = DeepRecursiveFunction<A,B> { a -> .... }
suspend fun DeepRecursiveScope<*, *>.second(a: A): B { ... }
You need to at least one of the first kind to call it from the outside of your recursive computation via
first(a)
. Now inside any of those functions you call the first one via
first.callRecursive(a)
and the second one via
second(a)
. That's it.
If you are just calling utility functions that are not calling into the recursion you don't have to do anything -- these are just regular functions.
s

snowe

04/29/2020, 7:18 PM
ah, ok, let me try that. Thank you.
I think I must still be misunderstanding something, as I am still getting that error.
@elizarov any clue what I'm doing wrong here?
e

elizarov

05/01/2020, 10:03 PM
The lambda that you pass to ppContents function must be declared as an extension suspending function on DeepRecursiveScope. Alternatively, you can mark ppContents as inline.
s

snowe

05/02/2020, 5:46 AM
Awesome. Got that working with your help thank you!. Now I can run out of heap space rather than Stack Overflows 😂
6 Views