Pre-SIP: allow importing this

While trying out the syntax for Dotty, I found myself repeating this pattern over and over and over:

import Foo
import Foo.given
import Bar
import Bar.{bar,given}
import Baz
import Baz.{_, given}

A really useful capability would be the ability to import a symbol and members of that symbol in the same import statement.

For the above, this could look like this:

import Foo.{this,given}
import Bar.{this,bar,given}
import Baz.{this, _, given}
3 Likes

Just for my own understanding, you’re talking about a regular old import like import com.example.Foo, right? And this is not some crazy new dotty feature I haven’t heard about yet?

:point_up: this! :laughing:

For reference, Rust has this (using its self, which is our this): https://doc.rust-lang.org/reference/items/use-declarations.html

See similar discussion here

Also, note that you can have multiple imports in one statement. So you can do

import Foo, Foo.given

etc.

3 Likes

Basically, you want


import foo.this

to mean


import foo

so that you can combine it with other imports into the same line. I like the intention, but I don’t like to use this for that purpose, because it would literally mean that you import a symbol that will now be available as this, which would be incorrect. How about using instead `` (an empty pair of backticks), because it could be read as nothing, and that would be correct, because you want foo followed by nothing, e.g.


import foo.{``, _}

We could then also do things like


import foo.{bar => ``}

import baz.{`` => blub}

which would rename foo.bar into foo and baz into baz.blub.

2 Likes

It wouldn’t have to mean that. It could just mean exactly what we want it to mean.

1 Like

Yep, just a regular import.

Due to the separation of given imports and opaque type aliases defining their API via extension methods this may come up more often than in Scala 2, but conceptually there’s nothing particularly new here.

Looks like this still works when Foo has to be qualified, which is really handy:

package wrapper {
  object Test {
    final val t1: Int = 0
    given Int = 1
  }
}

package runner {
  object Main extends App {
    import wrapper.Test, Test.{_, given}
    
    println(Test.t1)
    println(t1)
    println(summon[Int])
  }
}

Live version

This should do the trick, thanks :+1:

The key thing in what you are saying is followed. When you are writing import foo.{bar, rab}, you are adding bar and rab not followed by foo but by themselves.

Thus, your suggestion has the same irregularity as with this.