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
Inconsistence handling of varargs #2991
Comments
Imported From: https://issues.scala-lang.org/browse/SI-2991?orig=1 |
Aaron Novstrup (anovstrup) said: |
@odersky said: |
@dcsobral said:
I ask this to be reviewed, please, as this doesn't match what is happening. For example: scala> class X {
| def f(x: AnyRef) = x.toString
| def f(x: AnyRef, y: AnyRef*) = y.mkString(x.toString)
| }
defined class X
scala>
scala> new X
res0: X = X@1cdc190
scala> val x : AnyRef = "a"
x: AnyRef = a
scala> res0.f(x, x)
res1: String = a If The problem only happens when a single parameter is passed, so I fail to see why would any conversion to tuple come into play, or why would it matter in selecting the function even if it did. |
@lrytz said:
If you pass a single parameter then both methods are applicable, and the compiler tries to find out which one is more specific. It will find that none of the two is more specific than the other, both are applicable to parameters of types of the other (once via tuple conversion). see spec for When you pass two parameters, only the second one is applicable. (The first one would work through tuple conversion, but this is only tired when no other alternative works). |
@dcsobral said:
I assume that's a conversion into a Tuple1? Why would such a conversion be even considered, given that the type matches? |
@lrytz said:
Sorry, let me try again. object t {
def f(x: AnyRef) = 1 // A
def f(x: AnyRef, xs: AnyRef*) = 2 // B
} if you call
Since both are as specific as the other, the reference to |
@dcsobral said: It is unfortunate, however, that this causes an interoperability problem with Java. |
@dcsobral said: |
Steven Bethard (bethard) said: http://stackoverflow.com/questions/13358705/force-single-argument-in-scala-varargs +1 on adding something to the FAQ. |
@Atry said (edited on Jun 6, 2014 3:22:28 AM UTC):
It's wrong. The Scala Language Specification never said |
@som-snytt said: |
Mikael Ståldal (mikaelstaldal) said: It causes serious interoperability issues with common Java libraries, and even JavaEE specifications. Look at the Configurable interface in JAX-RS 2.0: It is not possible to invoke the one-arg register() method from Scala. |
@Atry said (edited on Jun 27, 2014 12:52:12 PM UTC): |
Hendy Irawan (ceefour) said: |
Arnaud Masson (amasson) said: |
@som-snytt said: This PR offers options: scala/scala#4440 |
Aleksandr Panzin (jalexoid) said: |
@paulp said: |
Davi de Castro Reis (davi) said: This is also the only reason I have java files in my codebase. |
@odersky said (edited on Jan 6, 2016 10:30:38 PM UTC): Here's the test that compiles. class X {
def f(x: AnyRef) = x.toString
def f(x: AnyRef, y: AnyRef*) = y.mkString(x.toString)
}
class Y {
def f(x: Int) = x.toString
def f(x: Int, y: Int*) = y.mkString(x.toString)
}
object Test {
val x: AnyRef = "a"
val res0 = new X
res0.f(x)
val res1 = new Y
res1.f(5)
} |
There seems to be some inconsistent handling of varargs by Scala. Consider these two classes:
The ambiguity with
f
is resolved differently:This problem was brought to my attention by Mockito's
org.mockito.stubbing.OngoingStubbing
interface, which overloads the methodthenReturn
to accept either anObject
, or both anObject
and a vararg of them.The text was updated successfully, but these errors were encountered: