Closed yoeluk closed 9 years ago
@yoeluk and team: nice! How about the following slight variation, which uses two different ways of getting a Seq
from the Java list, and uses a method to make it a little more clear how you're likely to get hold of such a list in Scala code in the first place?
import java.util.{List => JList, LinkedList}
import scala.collection.JavaConversions._
def listFromJava: JList[Int] = {
val jlist = new LinkedList[Int]()
jlist.add(1)
jlist.add(2)
jlist
}
def printHeadOrEmpty(s: Seq[_]) = s match {
case hd :: _ => println(hd)
case _ => println("Empty :-(")
}
printHeadOrEmpty(listFromJava.toSeq) // Empty :-(
printHeadOrEmpty(Seq(listFromJava: _*)) // 1
Very nice @demobox ! I'll update the PR with your code. Just to give you a context we came across this when reading from a config file in an Akka application. It was hard to find the bug within a large application. Many thanks!
Just to give you a context we came across this when reading from a config file in an Akka application
Ah, thanks for explaining. Or should I say: "thank you Akka"? ;-)
Thanks also for updating the PR...
I was just taking a look at this again and noticed that it's not actually necessary to call
printHeadOrEmpty(listFromJava.toSeq)
since it's possible to simply pass the list in directly
scala> printHeadOrEmpty(listFromJava) // Empty :-(
On the other hand, there is more symmetry between listFromJava.toSeq
and Seq(listFromJava)
than between listFromJava
and Seq(listFromJava)
.
That leaves us with three choices:
listFromJava
and Seq(listFromJava)
listFromJava.toSeq
and Seq(listFromJava)
@yoeluk What do you think..?
Also, I'm not sure the explanation is totally correct: from what I can see, the reason JavaConversions
turns the Java list into a Buffer
is because that is the only supported conversion to a (subtype of) Scala Seq.
If printHeadOrEmpty
is declared to expect specifically an immutable Seq
, the conversion does not work:
def printHeadOrEmpty(s: collection.immutable.Seq[_]) = s match {
case hd :: _ => println(hd)
case _ => println("Empty :-(")
}
scala> printHeadOrEmpty(listFromJava)
<console>:18: error: type mismatch;
found : java.util.List[Int]
required: scala.collection.immutable.Seq[_]
printHeadOrEmpty(listFromJava)
^
But it does work if we specifically require a mutable Seq
:
def printHeadOrEmpty(s: collection.mutable.Seq[_]) = s match {
case hd +: _ => println(hd)
case _ => println("Empty :-(")
}
scala> printHeadOrEmpty(listFromJava)
1
I totally agree! I think that we should include all three possibilities since it is nice to show the example with higher symmetry. Good find! I don't think the team checked the Scala sources of the JavaConversions, which was an oversight of course! I will update the PR as soon as I get a chance. Let me know if anything else comes to mind!
Let me know if anything else comes to mind!
Nothing for now - thanks for the response!
Merged to master: 6a30c18e3ce9cd81f7f747eae471006a0160cb79. See http://scalapuzzlers.com/#pzzlr-061.
Thanks @yoeluk and everyone on the Razorfish Scala team!!
Thanks for submitting this, @yoeluk and Razorfish team!
Just a heads-up that I'm travelling this and next week so I probably won't be able to look at this immediately, but will try to get round to this as soon as I can.