Skip to content

Instantly share code, notes, and snippets.

@som-snytt
Last active November 27, 2018 13:35
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save som-snytt/72630caa134338532e8bd2635dda65ac to your computer and use it in GitHub Desktop.
Save som-snytt/72630caa134338532e8bd2635dda65ac to your computer and use it in GitHub Desktop.
Various proposals for import syntax, or doing things with qualified things
Ref: https://contributors.scala-lang.org/t/proposed-syntax-for-root/1035
Use package for _root_
import _root_.a // now
import package.a // proposed (alternatively just leading dot)
Use underscore for symbol in scope
import a.b // now and forever, no special syntax
import _.a.b // proposed, optional syntax, warn if `a` not a symbol in scope, guard against package.a
Expression syntax
val x = _root_.a.b // now
val x = package.a.b // proposed (alternatively leading dot after left paren)
val x = `package`.a.b // now and forever, package object { val a: { val b: B } = ??? } or arbitrary `package`-named thing
// todo: scalafix rules about package objects
Use tree syntax
import a.{b, c} // now and forever
import a.{b.x, c.y} // proposed
import a.{ // proposed
b.{
x, // comma required? probably
y._
},
c.y
}
Import from enclosing packages
package a { object X ; package b { class C { def f = X } } } // now and forever
package a.b
class C { def f = X } // error now and forever
package a
package b
class C { def f = X } // now
package a with import
package b
class C { def f = X } // proposed
package p { object X } // X of interest in separate compilation unit
package a
package b
class C { import p._ ; def f = X } // with fixed imports, was import shadowed by definition in (any) enclosing package
Stable expression syntax
val x = _root_.a.b // now
val x = package.a.(b) // proposed simple expression
val x = package.a.{b} // proposed block expression
def f: String = ""
val x = { val z = f; import z._; println("hello, world"); length } // now
val x = f.{ println("hello, world"); length } // proposed
val g: String = ""
val x = { import g._; println("hello, world"); length } // now
val x = g.{ println("hello, world"); length } // proposed, looks the same
Scoped imports (parameterized import syntax, for control over where import qualifier resolves to))
import(arg) a.b // ichoran, where arg is absolute, relative, etc, describing behaviors
import[arg] a.b // alt ichoran
import[p] a.b // proposed, import only from a available up to an enclosing scope
import package.a.b // as proposed, the absolute case
import[p] util._ // example, util must be introduced under p scope, but normal shadowing applies
package q { package util { object X } }
package q
package p
class C { import[p] util._ ; def f = X } // example, intend p.util or p.something.util but not q.util
// maybe I have a local util package but sometimes I don't align my package statements correctly.
// Sometimes `Try is not a member of util` or `MyTry is not a member of util`, depending on my mistake and intentions.
// Note: fixing imports as specified takes care of unwanted util in other compilation units (or local dir on
// class path) shadowing scala.util
package paranoid
class C { import[_] util._ ; def f = MyTry(42) } // example, don't use scala.util by accident
1. selection from `package` denotes top-level package, a zero-length path prefix
2. import selectors can be arbitrary stable paths, arbitrarily nested
3. request imports from enclosing package using syntax package p with import
4. brace selection is rewritten to import from stable path. Braces can be parens for simple expressions.
5. scoped imports limit the import qualifier
@nafg
Copy link

nafg commented Jun 3, 2018

seems like too much complexity for little gain... can you convince me the gains are important?

Also, as I mentioned in the thread, an advantage of using a leading dot to indicate absolute paths, besides being analogous to filesystem paths, is that because it's so lightweight it's possible to start using it in imports all the time. package. is more verbose. I doubt people will want to start using it everywhere.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment