Proposed syntax for _root_

It seems like on the one hand, we want to encourage people to use absolute imports whenever possible, but on the other hand we don’t want to change the meaning of existing code, nor impose verbose changes everywhere.

It sounds to me like using a leading dot to denote an absolute path comes the closest to satisfying all the objectives. It’s not an eyesore, it’s intuitive because it’s analogous to how filesystem paths work, and it’s not hard to see people using it as the default everywhere (if we were to strongly encourage it). At the same time we don’t have to change the meaning of existing code; paths without a leading dot would continue to be relative.

Whether it should be possible to denote an absolute path in arbitrary expressions, other than import, is a separate question (although if anyone is using root outside of imports, then an important question). There most conservative approach would be to disallow it (for the time being anyway), the next most conservative approach would be to allow it but require parentheses around it so the dot doesn’t attach it to the previous word, and the least conservative approach would be to only require parentheses when there is ambiguity (without parentheses such cases would have to keep their meaning unchanged).

2 Likes

Although this doesn’t need to be a deal breaker I think we should be aware that in python:

import .pkg

imports pkg relative to the containing package (leading dot means “parent” roughly). Where as,

import pkg

imports pkg as an absolute name (the default). We should be careful of having the exact opposite semantics in Scala.

import .pkg

looks feasible. It’s a pity that it clashes with Python’s convention, but I also would not see it as a deal breaker. I’d in that case also be in favor of allowing leading . in parenthesized expressions. I.e.

(.scala.Predef)

instead of

_root_.scala.Predef
4 Likes

There was already a summation for folks just back from Tahiti, but I had the pleasure of re-reading this thread this morning. I was disappointed the emoji proposal went nowhere.

Here is my summary. I have arbitrarily preferred package to dot for absolute paths, for reasons of Haoyi.

  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

Just the gist, ma’am.

The gist shows current and proposed syntax.

Besides absolute package, it includes optional lead underscore for relative, import[mypackage], import tree syntax, stable import expressions x.{ f(); y } and explicit import from enclosing package package p with import.

Apologies in advance if I left anyone out. These are also what I would go for, exclusive of emojis and the shrugging guy.

Bonus points for import[_] p._.

I don’t address implicit import, implicit val _, for (implicit _ <- g) or other valuable locutions.

I would have used settings.{ language.enable(languageFeatures.postfixOps) } recently.

After seeing all the suggestions here, I still think using a leading dot (e.g. import .scala.collection.immutable) for absolute imports is the simplest and most consistent way to solve the original problem. Using a keyword like package to me is less appealing than _root_ since package has other meanings in Scala and is more verbose.

The fact that it’s different from Python doesn’t bother me. Python chose to go against the standards set by DNS, file system paths, etc., and Scala is already rather different from Python in numerous other ways.

4 Likes