Qualified imports, if possible with aliasing

Viewed 204

I am learning Scala and have a package with no dots in the name: test. I now want to import stuff from this package into another Scala file, but I

  • do not want to use wildcard imports because I want to prevent name clashes (so no import test._)
  • do not want to import individual classes (so no import test.{My, Manually, Maintained, List, Of, Classes})
  • do want to keep test as a top level package (so no package nested.test)
  • would like to alias the package to a shorter name (something like import {test => t})

I have played around but was not successful until now. I compile with scalac a.scala b.scala:

  • file a.scala
package test
class A {}
  • experiments with file b.scala, none of which did work:
import _root_.{test => t} // error: _root_ cannot be imported
class A extends t.A {}
import _root_.test // error: _root_ cannot be imported
class A extends test.A {}
import test // error: . expected
class A extends test.A {}
import test.A // warning: imported `A` is permanently hidden by definition of class A
class A extends A {} // error: illegal cyclic reference involving class A
import {test => t} // error: identifier expected but '{' found.
                   // error: . expected
class A extends t.A {}

In python I could achieve what I want like this

import test as t
class A(t.A): pass

and in Haskell I could do

import qualified Test as T
type A = T.A

Question: Can something like this be achieved in Scala? What could I do to get close to this?

1 Answers

If test is the fully qualified name of your package you don't need to import it at all. Just use it:

class A extends test.A

Going a bit more into detail. In Scala a package is available by name simply if it is present on the compilation classpath. And it is the build tool that decides what is on the classpath (or yourself, if you use commandline scalac, which I wouldn't recommend but for the most trivial experiments).

Imports in Scala (and most—if not all—other languages on the JVM) are not really about telling the compiler or interpreter which "module" you want to use, like in Python. Their main purpose is to allow you to use the short name of classes and objects (Foo, bar) instead of their fully qualified names (org.example.project.Foo, org.example.project.bar).

Aliasing a package that's in the _root_ namespace unfortunately doesn't seem to be possible in Scala 2. In Scala 3 import _root_.{test => t} actually appears to work. At least in the preview snapshot I am currently using.

Related