Just curious, why is it impossible for overload re...
# announcements
n
Just curious, why is it impossible for overload resolution to distinguish these:
Copy code
operator fun<R> R.rem(transform: (R) -> R) = transform(this)
operator fun<R> R.rem(transform: R.() -> R) = this.transform()
I'm not even allowed to declare both
r
I’d guess they get compiled to identical byte code - isn’t it a compiler trick to treat this as the argument to transform in the second?
n
Possibly, I don't know much about byte code
But if the types are different that still seems like a bug in Kotlin effectively
e
it's Function1<R, R> either way, the compiler simply "remembers" when you write the lambda that "this" is the first argument
you are allowed to pass a
(R) -> (R)
to a function taking a
(R).() -> (R)
and vice versa
https://github.com/JetBrains/kotlin/blob/master/spec-docs/function-types.md
Extension function type
T.(P) -> R
is now just a shorthand for
@ExtensionFunctionType Function2<T, P, R>
.
kotlin.extension
is a type annotation defined in built-ins. So effectively functions and extension functions now have the same type, which means that everything which takes a function will work with an extension function and vice versa.
(it's not only JVM, but that's where it was introduced)
n
weird
• > Shape of a function literal argument or a function expression must exactly match the extension-ness of the corresponding parameter. You can't pass an extension function literal or an extension function expression where a function is expected and vice versa. If you really want to do that, change the shape, assign literal to a variable or use the 
as
 operator.
this seems pretty dubious
they're the same in the underlying implementation, ok, but nto really the same
e
they are the same, it's just that if you write a
{ -> }
lambda in-place, it always takes the declared shape
not sure how you would answer "is this no-arg lambda working on
this
receiver or taking an implicit receiver
it
?" otherwise
n
you're right about them being the same
despite the wording above,, which seems to contradict that
to answer your question though, you wouldn't
it would be ambiguous
but not all cases would be ambiguous
At any rate I guess if you can pass either then I don't have much reason to have overloads
a
They were the same 3 months back 😛
You can call
lambda = { a -> }
as
instance.lambda()
back in the days, not now but they are still the same in the bytecode level I guess.