scalapuzzlers / scalapuzzlers.github.com

Github Pages behind scalapuzzlers.com
www.scalapuzzlers.com
161 stars 53 forks source link

Single methods need not apply! #125

Closed som-snytt closed 9 years ago

som-snytt commented 9 years ago

From https://gitter.im/scala/scala?at=556e2d86777c17d06a13a90f

and https://gitter.im/scala/scala?at=556e9e5b27d2203776cc5af1

object X extends (() => Any) {val apply = () => 42}
X()
// versus
object X extends (() => Any) {val apply = () => 42 ; def apply(s: String) = 8 }
X()
// bonus points
object X extends (() => Any) {object apply extends (() => Any) { def apply() = 42 }}
X.apply()

I dread bringing it up, because you'll say which really old puzzler it duplicates.

demobox commented 9 years ago

I dread bringing it up, because you'll say which really old puzzler it duplicates.

At first sight, I'd say "none" ;-) Crazy busy this weekend, but looking forward to having a look at this next week, hopefully.

Thanks for sticking with it, @som-snytt! You won't be at SD Amsterdam, by any chance?

som-snytt commented 9 years ago

Not a chance! I wish I'd stuck around SD/SF. At least you provide a place to stick the puzzlers we're stuck on.

demobox commented 9 years ago

but looking forward to having a look at this next week, hopefully

@som-snytt: From the Gitter threads, I wasn't quite sure what conclusion you came to - @retronym explained it as follows:

  1. The val apply is regarded as a valid implementation of Function0's abstract apply method since it's type-compatible
  2. The val apply is not considered for apply injection because, roughly speaking, it's not a def. Jason mentioned that the compiler is apparently looking for either a type or a value parameter list, but things seem to work with def apply = () => 42, so it would seem that the val is required to make this fail.
  3. Adding the second def apply(...) allows the compiler to find some possible candidates for apply injection. It then uses overloading resolution to discard the def and pick the val instead.

Agree with @Alefas that the inconsistency feels like a bug, but it looks as though everything is spec compliant as things stand.

I'd say WE HAVE A PUZZLER! ;-)

som-snytt commented 9 years ago

OK, took me a second to get you. Yeah, the spec says "an apply method defined by f", 6.6.

Recently, I noticed the spec isn't clear on why vals override defs. The section on matching members seemed to exclude it; I don't remember if I figured that out or just fell asleep.

Yeah, your 3 might be right. Once it's committed to taking X() as X.apply(), there's no going back, and overload resolution picks the val as applicable. That's why I come to the puzzlers, for answers!

I wonder what dotty does. You know the O/C button in scaladoc, you'll need a button to switch between the scalac explanation and the dotc.

demobox commented 9 years ago

See 8460e35c2750774cb3230cc2ecf52e6bf8efd79d and http://scalapuzzlers.com/#pzzlr-057. Thanks, @som-snytt!

som-snytt commented 9 years ago

@demobox The puzzler always turns up wearing a disguise, I never recognize it. You really have to post the source as above, since it's the first gittered puzzler:

https://gitter.im/scala/scala?at=556e2d86777c17d06a13a90f

demobox commented 9 years ago

You really have to post the source as above, since it's the first gittered puzzler:

Sorry, missed that - see b60fa4b053e2c6bf572e1c6cf2e6c5ef64efc1e1. Thanks for the reminder!