Another question that I have. What is the recommen...
# arrow
c
Another question that I have. What is the recommended way of doing dependency injection ? Based on my research, there is the Reader monad based on a article written by Jorge Castillo. There is also this

talk

with Francisco Garcia. And also in the arrow documentation, you can do it using Typeclass. What is the recommended way of doing dependency injection ? what are the advantages of one method over the other ? If this question is not asked to the right channel, feel free to redirect me to the correct one
p
Reader is a more general technique that comes with a runtime cost, and some boilerplate. The other one takes extension functions and makes them into DI elements. It takes a bit more brainpower to get right, and comes without a runtime penalty. Both approaches are purely functional. You still have the global injector frameworks like coin and dagger, depending on how much magic and coupling you'd like in your app.
s
here is one approach with Extension functions in a gist by @raulraja https://gist.github.com/raulraja/97e2d5bf60e9d96680cf1fddcc90ee67
s
@pakoito what is the runtime cost for reader ?
p
You're wrapping and unwrapping into a Reader, even if you have no effects or...either, it'll be
Id
, which is just regular boxing.
Copy code
fun Int.thing(): Int = this

fun thing(): Reader<Int, Int> = Reader {
  ask()
}
s
Right. That I’ve notice a lot while using reader.
s
https://gist.github.com/nomisRev/1f91710ebec1709d4ce8059812482624 Here is another example which uses extensions functions to replace
Reader
, interface delegation to do dependency composition, and uses generic function constraints to define top-level function that can define all there dependencies as non-params.
c
Ok thx for your useful responses
h
The only limitation I've found using the extension functions solution is with anonymous suspend functions. Or maybe I'm not aware of how to declare them...
Copy code
fun <R : Console> doSomething() {
  val myFunction: suspend R.(i: Int) -> Unit = suspend { i: Int -> print("AAA $i") }
(this doesn't compile)
(sorry, I was wrong, it can be defined without problems...)
p
¿?
what was the issue?
h
probably that I was too tired... 🤣 anyway, in the past I had some compatibility problems, e.g with List<>.traverse(). I can traverse a List<IO<A>> but not a List<suspend () -> A>, but maybe now it is fixed.
s
but not a List<suspend () -> A>, but maybe now it is fixed.
You can now 😉
🎉 1