For example look at this way to do DI type checked...
# arrow
r
For example look at this way to do DI type checked by the compiler and eliminating the need for DI frameworks:
Copy code
interface Context<A> {
  fun A.config(): Config
}
Copy code
package prod

object ProdContext: Context<Service> {
  fun Service.config(): Config = ProdConfig
}
Copy code
package test

object TestContext: Context<Service> {
  fun Service.config(): Config = TestConfig
}
Copy code
package prod

service.config() // ProdConfig
Copy code
package test

service.config() // TestConfig
d
What can't be done now with regular Kotlin from this example? I'm not catching...
r
Given the same object and imports in scope the instance providing the configuration is different and lack of its evidence is a compile time error when attempting to use
config()
d
Do how should it be provided, I mean, what syntax are you adding to do that resolution? I don't see a difference in the sample code you posted?
r
ProdContext and TestContext are two different instances that add the
Context
behavior to all
Service
types.
if you import the prod instance into scope
config()
returns
ProdConfig
if you import the test instance it returns instad
TestConfig
d
If one does that now (before this new feature is implemented, it'll be an error? I understand what you're trying to obtain, I'm just not understanding the syntax difference, and what's missing from the way things work now...
r
yes there is not current support in Kotlin for type classes
d
@raulraja Sorry for the question, but which part of the code above do you call
type classes
? The `object`s already exist in the lang., maybe you mean
type object ProdContext: Context<Service>
?
r
Type classes is when you provide an instance of a paramteric interface where the type argument is a type
and then the compiler resolves that instances for you automatically
this allows you to add new behaviors a la cart where needed
it also allows you to add ad hoc polymorphism
Copy code
fun <A> config(): Config given Context<A> = A.config()
Copy code
config<ProdService>() //compiles
config<TestService>() //compiles
config<CloudService>() //does not compile because no `Context<CloudService>()` is found in scope.
The KEEP has many other examples of potential usages
Basically with type classes you don't need a DI framework because the compiler can resolve your dependency graph at compile time
That is why in Scala and other langs that support type classes or implicits nobody uses Dagger, Guice,...
The compiler provides Dependency Injection based on instance evidences
d
I'm starting to understand, thanks! Where's that KEEP?
r