Uploaded image for project: 'Scala Programming Language'
  1. Scala Programming Language
  2. SI-9076

Lambda in REPL (using object-wrappers) gives non-termination of Java 8 Stream

    Details

      Description

      The following code is a test of generating and using java.util.Spliterator to create a java.util.stream.Stream:

      package xp
       
      import java.util.Spliterator
      import java.util.function.Consumer
       
      class Aspi(a: Array[String], private val i0: Int, private var i1: Int) extends Spliterator[String] {
        private var i = i0
        def characteristics = Spliterator.SIZED | Spliterator.SUBSIZED | Spliterator.IMMUTABLE
        def estimateSize = i1-i
        override def getExactSizeIfKnown = i1-i
        def tryAdvance(f: Consumer[_ >: String]): Boolean = {
          println(s"Trying at $i [$i0, $i1)")
          if (i >= i1) false
          else { f.accept(a(i)); i += 1; true }
        }
        def trySplit(): Aspi = {
          if (i1-i < 4) {
            println(s"Could not split [$i $i1)")
            null
          }
          else {
            println(s"Splitting from [$i $i1)")
            val child = new Aspi(a, (i+i1+1)/2, i1)
            i1 = child.i0
            child
          }
        }
      }
       
      object Test { def main(args: Array[String]) {
        def nu = new xp.Aspi(Array("one", "two", "three", "four", "five"), 0, 5)
        val st = java.util.stream.StreamSupport.stream(nu, true)
        val c = new java.util.Comparator[String]{ def compare(s: String, t: String) = s compareTo t }
        println(st.map[String]((s: String) => s + s).max(c))
      }}
      

      This compiles and runs successfully. However, when the contents of main are entered in the REPL, the last line hangs. Stack trace:

      "ForkJoinPool.commonPool-worker-1" #14 daemon prio=5 os_prio=0 tid=0x00007f966855f800 nid=0x721f in Object.wait() [0x00007f964a18b000]
         java.lang.Thread.State: RUNNABLE
      	at $line6.$read$$iw$$iw$$anonfun$1.apply(<console>:11)
      	at $line6.$read$$iw$$iw$$anonfun$1.apply(<console>:11)
      	at java.util.stream.ReferencePipeline$3$1.accept(ReferencePipeline.java:193)
      	at xp.Aspi.tryAdvance(Test.scala:14)
      	at java.util.Spliterator.forEachRemaining(Spliterator.java:326)
              ...
      

      Explicitly creating the SAM like so:

      println(st.map[String](new java.util.function.Function[String, String] {
        def apply(s: String) = s + s
      }).max(c))
      

      solves the issue. (Note: I have not tried this on 2.11.5; I assumed 2.12.x was up to date in anything relevant.)

        Attachments

          Issue Links

            Activity

              People

              • Assignee:
                moors Adriaan Moors
                Reporter:
                ichoran Rex Kerr
              • Votes:
                0 Vote for this issue
                Watchers:
                9 Start watching this issue

                Dates

                • Created:
                  Updated: