-
Notifications
You must be signed in to change notification settings - Fork 1.1k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Scala Wart: Classes cannot have only implicit parameter lists #2576
Comments
I think this will be affected by the |
This bug hit me pretty hard recently, I was looking to curry the type signature of a function with three types. One is supplied by the user, and the other two derived from function arguments. I used code that looks like
(see http://caryrobbins.com/dev/scala-type-curry/) Problem is, that the No big deal, I thought, I'll just insert some classtag implicit evidence, and do the The only reason I'm doing this hack is so I can have curried type parameter lists. |
That's also something we'll hopefully also support directly, if there isn't an issue feel free to create one. |
Hi, I get hit by this one: trait Encoder[T] {
def apply(o: T): String
}
object Encoder {
implicit val intEncoder: Encoder[Int] = _.toString
}
trait Creatable[Resource: Encoder] {
def create(resource: Resource): Unit = ???
}
case class PodsOperations() extends Creatable[Int] The last line won't compile. case class PodsOperations() extends Creatable[Int]() Thanks |
It turns out this is can alternatively be seen as the problem of old-style implicits taking regular arguments. If we move to
Classes without a leading regular parameter list still assume But if creator applications take a |
I'm reopening this issue because the syntax has evolved quite a bit since it was closed and the situation is now "wart-y" again in my opinion: given Int = 1
class Foo(using x: Int)
new Foo // compiles
new Foo() // compiles
new Foo(using 1) // compiles
new Foo()(using 1) // compiles The fact that there's some sort of optional empty parameter list is fairly weird, but it gets weirder when combined with the fact that we can now have a regular parameter list after a using parameter list: class Bar(using x: Int)(y: String) // For a more realistic usecase, see https://github.com/lampepfl/dotty-feature-requests/issues/133
new Bar("") // ERROR: too many arguments for constructor Bar: ()(using x: Int)(y: String): Bar
new Bar()("") // compiles
new Bar(using 1)("") // compiles
new Bar()(using 1)("") // compiles Here in particular, the fact that one cannot write |
Fixes scala#2576 As the discussion in scala#2576 shows, we still have some problems with the implicitly inserted empty parameter lists for class constructors. We do need that empty list to support syntax like `C()` and `new C()`. But it gets in the way if a class has using clauses. Example from the issue: ```scala class Bar(using x: Int)(y: String) given Int = ??? def test = new Bar("") ``` Here, an implicitly inserted `()` in front makes the last line fail. We'd need `new Bar()("")`. If a class has only using clauses as parameters we now insert a `()` at the end instead of at the start. That makes the example compile. For old-style implicit parameters we don't have a choice. We still need the `()` at the start since otherwise we'd change the meaning of calls with explicit arguments for the implicit parameters.
Fixes scala#2576 As the discussion in scala#2576 shows, we still have some problems with the implicitly inserted empty parameter lists for class constructors. We do need that empty list to support syntax like `C()` and `new C()`. But it gets in the way if a class has using clauses. Example from the issue: ```scala class Bar(using x: Int)(y: String) given Int = ??? def test = new Bar("") ``` Here, an implicitly inserted `()` in front makes the last line fail. We'd need `new Bar()("")`. If a class has only using clauses as parameters we now insert a `()` at the end instead of at the start. That makes the example compile. For old-style implicit parameters we don't have a choice. We still need the `()` at the start since otherwise we'd change the meaning of calls with explicit arguments for the implicit parameters.
Opening this issue, as suggested by Martin, to provide a place to discuss the individual warts brought up in the blog post Warts of the Scala Programming Language and the possibility of mitigating/fixing them in Dotty (and perhaps later in Scala 2.x). These are based on Scala 2.x behavior, which I understand Dotty follows closely, apologies in advance if it has already been fixed
This doesn't work:
But this does:
This one straddles the line between "Wart" and "Bug", but definitely should
be fixed so that a class defined with one argument list doesn't magically
sprout two.
The text was updated successfully, but these errors were encountered: