Question about import

for this code:

scala> import java.util._
import java.util._

scala> import scala.collection.mutable._
import scala.collection.mutable._

scala> HashMap[String,String]()
val res0: scala.collection.mutable.HashMap[String,String] = HashMap()

Both imported packages have the member HashMap.
Why HashMap in second package was used?

Thanks

The one that is imported last seems to be in use. If you import scala first, then java, then the java one is in use. (I don’t know Java HashMap syntax so I failed below)

 ➜ scala
Welcome to Scala 3.1.0 (11.0.13, Java OpenJDK 64-Bit Server VM).
Type in expressions for evaluation. Or try :help.
                                                                                                                                       
scala> import scala.collection.mutable.*
                                                                                                                                       
scala> import java.util.*
                                                                                                                                       
scala> val x = HashMap('a' -> 1)
-- Error:
1 |val x = HashMap('a' -> 1)
  |        ^^^^^^^
  |        None of the overloaded alternatives of method apply in object HashMap with types
  |         [K, V](x$0: java.util.Map[?, ?]): java.util.HashMap[K, V]
  |         [K, V](): java.util.HashMap[K, V]
  |         [K, V](x$0: Int): java.util.HashMap[K, V]
  |         [K, V](x$0: Int, x$1: Float): java.util.HashMap[K, V]
  |        match arguments ((Char, Int))

REPL goes backward looking for imports to use on the current line. Here, it’s looking for HashMap, and sometimes it will stop there, other times it will use imports that may introduce implicit values. It is best-effort.

Generally, later definitions shadow earlier.

-Dscala.repl.debug can help. (Alternatively, regular -Vprint:typer.)

scala> HashMap[String,String]()
package $line5 {
  sealed class $read extends _root_.scala.Serializable {
    def <init>() = {
      super.<init>;
      ()
    };
    import _root_.scala.tools.nsc.interpreter.$u007B$u007B;
    import java.util._;
    import _root_.scala.tools.nsc.interpreter.$u007B$u007B;
    import _root_.scala.tools.nsc.interpreter.$u007B$u007B;
    import scala.collection.mutable._;
    import _root_.scala.tools.nsc.interpreter.$u007B$u007B;
    sealed class $iw extends _root_.java.io.Serializable {
      def <init>() = {
        super.<init>;
        ()
      };
      val res0 = HashMap[String, String]
    };
    val $iw = new $iw.<init>
  };
  object $read extends scala.AnyRef {
    def <init>() = {
      super.<init>;
      ()
    };
    val INSTANCE = new $read.<init>
  }
}
Set symbol of res0 to val res0: mutable.HashMap[String,String]

package $line5 {
object $eval {
  lazy val $result = $line5.$read.INSTANCE.$iw.res0
  lazy val $print: _root_.java.lang.String =  {
    val _ = $line5.$read.INSTANCE.$iw

""  + "val res0: scala.collection.mutable.HashMap[String,String]" + " = " + _root_.scala.runtime.ScalaRunTime.replStringOf($line5.$read.INSTANCE.$iw.res0, 1000)

  }
}}
Invoking: public static java.lang.String $print()
val res0: scala.collection.mutable.HashMap[String,String] = HashMap()

The special imports are for nesting depth, so shadowing works.

1 Like