Using the underscore for wildcards in types was unfortunate, because it causes a notational discrepancy for types and for values.
C[_] means an existential: ex(T).C[T]c(_) means a universal: x => c(x).We'd also like to use some notation for projecting types, but _ is already taken. So @non's kind projector uses ? instead. But now things get really confusing.
F[_], but for partial applications it's F[?].? is the same as Java's wildcard, but Java's wildcard means _ in Scala._ for terms but ? for types.It seems we have everything wrong here and it's no wonder people are confused.
Everything would be so much nicer if we could go back in time and express wildcards with ? instead of _.
_ as a placeholder for type parameters.F[_] and f(_) mean the same thing.F[_] produces a higher-kinded type at definition sites as well as use sites.Changing to dotty might give us the one and only chance to actually achieve that.
_ to ?._ for kind projector's ?.It's still a large step, though. So I am on the fence whether we should do it.
I wholeheartedly agree that this would be better. I think the main argument against this is cross-compilation support (which is something that we haven't spent enough time thinking about yet I think). Assuming the old syntax is supported under -language:Scala2 by dotty, then everyone will continue using it until they can drop support for Scala 2.x, this means that both syntax will survive in the wild for a very long time which will make the situation even more confusing. If we commit to getting the new syntax implemented in Scala 2.11/2.12/2.13 under a flag like -Xfuture, then the situation may be somewhat better. My opinion is that the amount of energy that this will require (not just for the implementation, remember Wadler's law) could be better applied elsewhere.
However, there is one thing which I think is worth trying to fix: preventing people from writing foo[M[_] <: List[_]] when they meant foo[M[X] <: List[X]], I opened an issue for that some times ago: https://github.com/lampepfl/dotty/issues/1809
Yes, foo[M[_] <: List[_]] highlights the most glaring problems of the status quo. Let's think about migration. Here's a possible strategy:
? as an alternative for _, and offer rewrites under -language:future._, and offer rewrite in normal mode._._ as partial application. Kind projector would not work during this transition (and would not be needed afterwards because the compiler does it natively). There's less need for kind projector in dotty anyway because we have native type lambdas instead of the atrocity involving structural types. But if it's useful one could port a version of kind-projector that uses (say) ?? instead of ?.
@odersky, as most people will be migrating from Scala 2.12-2.13 to Dotty 1.0\Scala 3.0,
I think that depredations should affect Scala2.
@adriaanm, would it be possible to consider adding support for ? syntax and providing deprecation warnings for the _ in 2.12? Better by default, but otherwise under a flag.
I support the direction, but I don't think we can deprecate this in 2.12. We could support the ? wildcard notation for existentials in 2.13 (or possibly 2.12) under a flag (in addition to _), but cross-compilation will cause drag here for a while, as smarter said.
If we had ? under an -Xfuture flag we could deprecate _ and rewrite in the first version of dotty, which would speed up the conversion.
The same holds for with --> &. If we could get & under -Xfuture we could deprecate and rewrite immediately in dotty.
I'd welcome a PR implementing those under -Xsource:dotty in 2.12.3 (the 2.12.2 queue is closing soon, and I'd prefer not to rush this) or 2.13.0-M1.
A discussion about coding convention of higher kinded type declaration:
https://gitter.im/scala/contributors?at=5a2f68980163b02810269751
We can change the style documentation right now, to avoid accidentally written foo[M[_] <: List[_]].
I very much agree with this proposal, because I've repeated the use of _ for many times, I think reducing the meaning of _ can reduce beginners' confusion.
Closed in favor of https://github.com/lampepfl/dotty/issues/5379 where the discussion can continue
Most helpful comment
However, there is one thing which I think is worth trying to fix: preventing people from writing
foo[M[_] <: List[_]]when they meantfoo[M[X] <: List[X]], I opened an issue for that some times ago: https://github.com/lampepfl/dotty/issues/1809