edrd
06/17/2021, 3:46 PMedrd
06/17/2021, 5:02 PMelizarov
06/17/2021, 8:40 PMRob Elliot
06/18/2021, 9:16 AMthis
, but I’m not looking forward to trying to understand other people’s code written with multiple receivers / context.edrd
06/18/2021, 12:22 PMelizarov
06/18/2021, 12:57 PMRob Elliot
06/18/2021, 1:17 PMedrd
06/18/2021, 4:11 PMelect
06/19/2021, 8:31 PMUlrik Rasmussen
06/24/2021, 9:38 AMusing
/ given
mechanism. But unlike Scala's similar mechanism, doesn't this potentially run into problems when there are multiple instances of the same generic type in the context? E.g. context(Monoid<A>, Monoid<B>)
. I don't think I can use the typealias
workaround mentioned in the proposal to resolve the label ambiguity here.elizarov
06/24/2021, 3:47 PMMonoid<A>
and Monoid<B>
are different types, and there should not be any problems for a type-system to distinguish between them. However, assuming that Monoid
declared id()
function, you will not be able just to all id()
there, since there will be an ambiguity of which Monoid’s id()
function to call. The only workaround we propose at the moment is to declare a typealias and use it with a qualified-this expression to disambiguate the call.Ulrik Rasmussen
06/25/2021, 12:05 PMtypealias Monoid1<X> = Monoid<X>
and typealias Monoid2<X> = Monoid<X>
and then declare context(Monoid1<A>, Monoid2<B>)
. It's a bit tedious, but it works, and it is still nice to be able to have a context with monoid instances for different generic types. That is not possible with receivers because the type system does not allow me to say object MyInstance : Monoid<A>, Monoid<B>
because of type erasure.Ulrik Rasmussen
06/25/2021, 12:07 PMcontext(Monoid<A>, Monoid<B>)
over fun foo(using monoidA: Monoid<A>, using monoidB: Monoid<B>)
?Fudge
06/27/2021, 11:30 AMUlrik Rasmussen
06/28/2021, 4:31 AMtypealias
because the type name also serves as the binder of the context receiver object.Ulrik Rasmussen
06/28/2021, 4:34 AMfun foo(using monoid: Monoid<A>)
then an instance of foo
in a context where there is an instance myInstance: Monoid<A>
could be seen as a specialization of foo
with the signature fun foo(monoid: Monoid<A> = myInstance)
. This could be shown as a hint in intelliJ, which I as a programmer would welcome, as it would tell me directly how implicit parameters are resolved.Fudge
06/28/2021, 9:54 AMBut they are parameters, except that they are implicitly resolved from the context.They are parameters, but they are not passed as parameters. This is why declaring them as if they are passed normally is syntactically inconsistent.
It just seems unfortunate that one has to essentially apply hacks viaThere are ideas in the proposal to add abecause the type name also serves as the binder of the context receiver object.typealias
context(rec: Receiver)
named context syntax, but currently they don't find enough use case for it. After all you're only supposed to use it as a context, not as a normal parameter.
This could be shown as a hint in IntelliJYes, that could be an upside of your idea, however I feel that a hint (looking different, but) serving the same purpose can be implemented with the current proposal.
Ulrik Rasmussen
06/28/2021, 10:00 AMthis
, so they are much closer related to parameters than regular receivers are. I understand that this style may be preferred for consistency with the rest of the Kotlin language, but otherwise I don't think I see the advantage of this style over something like Scala3's using/given
approach.