It's tedious to have to import scala.annotation._ just to get things like @tailrec. See https://github.com/scala/bug/issues/11888.
We could move more annotations to scala or Predef but this has the downside of polluting top-level namespaces even further.
A more refined approach would open the scala.annotation scope after encountering an @. That way we could refer to all annotations in scala.annotation without needing an import.
When typechecking an annotation @id... the identifier id is resolved in a context where import scala.annotation._ is available as a predefined root import. The precedence of this new root import sits between Predef and the other root package imports. I.e. root imports for annotations are searched in the following order:
scala.Predef._
scala.annotation._
scala._
java.lang._
Once this is done, we should move all annotations in scala to scala.annotation. To support migration, the versions in scala should stay around as deprecated aliases.
The precedence of this new root import sits between
Predefand the other root package imports.
What's the reasoning for this choice? As an example, why not have it as the last fallback instead?
@dwijnand If it was the last fallback, deprecated aliases in scala would take precedence
Isn't that too much, adding a new name resolution rule just to avoid a few (standard) annotation names? I think this isn't the worth the cost of teaching people & teaching IDEs compared to just adding a few typealiases to Predef
This seems like a very ad hoc rule in the compiler to remove some arguably boilerplate-y imports of the standard library. What about other libraries defining annotations in their subpackages xyz.annotation._? If we're not addressing custom annotations in libraries, I don't see the point of addressing the few annotations in the stdlib. And if we're arguing that the ones in the stdlib are so commonly used that they deserve less boilerplate, then I really don't see why we can't put them in scala.
Here's the list of annotations in scala.annotation:
elidable
implicitAmbiguous
implicitNotFound
showAsInfix
strictfp
switch
tailrec
unspecialized
unused
varargs
And here's the one in scala:
deprecatedInheritance
deprecatedName
deprecatedOverriding
inline
native
noinline
specialized
throws
transient
unchecked
volatile
I note two things:
scala or scala.annotation.scala. There are some very common names that would be injected into everyone's scope that way.Note also that _no annotations_ are currently defined in Predef. So adding some would create another irregularity.
I don't see the point of adding another language rule, but if you're going
to, here's a simpler one, that addresses @sjrd's point about libraries:
An annotation @a refers to a if it is available in the current scope,
otherwise it is expanded to @annotation.a and that is tried as well.
This works for scala.annotation because scala._ is imported
so @annotation.tailrec is valid. It also could be used by libraries, e.g.
if I do import lib._ and there is a lib.annotation package then @a could
resolve to @lib.annotation.a.
Of course, in that case scala.annotation would presumably be shadowed, so
you'd have to be careful about your imports, but that isn't really anything
new.
That said, I think Dotty already adds way too many language rules for one
version bump, so I would be against adding anything for this in 3.0.
On Mon, Mar 2, 2020 at 11:49 AM odersky notifications@github.com wrote:
Note also that no annotations are currently defined in Predef. So
adding some would create another irregularity.—
You are receiving this because you are subscribed to this thread.
Reply to this email directly, view it on GitHub
https://github.com/lampepfl/dotty/issues/8419?email_source=notifications&email_token=AAAYAUCLLCDKTGUVIESMVRTRFPPSLA5CNFSM4K7RVG72YY3PNVWWK3TUL52HS4DFVREXG43VMVBW63LNMVXHJKTDN5WW2ZLOORPWSZGOENQBRUQ#issuecomment-593500370,
or unsubscribe
https://github.com/notifications/unsubscribe-auth/AAAYAUEWWBYUG7O7BXF4U2DRFPPSLANCNFSM4K7RVG7Q
.
Another option (also not necessary to go into 3.0) is that we make a new
package scala.annot, deprecating scala.annotation (exports can help). Then
it's just @annot.tailrec. I don't consider that very noisy.
On Mon, Mar 2, 2020 at 12:00 PM Naftoli Gugenheim naftoligug@gmail.com
wrote:
I don't see the point of adding another language rule, but if you're going
to, here's a simpler one, that addresses @sjrd's point about libraries:An annotation
@arefers toaif it is available in the current scope,
otherwise it is expanded to@annotation.aand that is tried as well.This works for scala.annotation because scala._ is imported
so @annotation.tailrec is valid. It also could be used by libraries, e.g.
if I do import lib._ and there is a lib.annotation package then @a could
resolve to @lib.annotation.a.Of course, in that case scala.annotation would presumably be shadowed, so
you'd have to be careful about your imports, but that isn't really anything
new.That said, I think Dotty already adds way too many language rules for one
version bump, so I would be against adding anything for this in 3.0.On Mon, Mar 2, 2020 at 11:49 AM odersky notifications@github.com wrote:
Note also that no annotations are currently defined in Predef. So
adding some would create another irregularity.—
You are receiving this because you are subscribed to this thread.
Reply to this email directly, view it on GitHub
https://github.com/lampepfl/dotty/issues/8419?email_source=notifications&email_token=AAAYAUCLLCDKTGUVIESMVRTRFPPSLA5CNFSM4K7RVG72YY3PNVWWK3TUL52HS4DFVREXG43VMVBW63LNMVXHJKTDN5WW2ZLOORPWSZGOENQBRUQ#issuecomment-593500370,
or unsubscribe
https://github.com/notifications/unsubscribe-auth/AAAYAUEWWBYUG7O7BXF4U2DRFPPSLANCNFSM4K7RVG7Q
.
Another thing that could or should be done, is to figure out a rule for
what should be in scala and what should be in scala.annotation, and move
them around with deprecations.
To me the obvious rule would be:
This results in:
compileTimeOnly: scala, it's changes the program's meaning
elidable: scala, it changes the code fundamentally
implicitAmbiguous: scala, it's part of the program's API
implicitNotFound: scala, it's part of the program's API
showAsInfix: scala, it's part of the program's API
strictfp: scala, it changes the programs behavior
switch: annotation, it's a micro-optimization
tailrec: scala, it can prevent a program from crashing
unspecialized: annotation, it's a micro-optimization
unused: annotation, it's just a workaround for a compiler warning
varargs: annotation, it's just for interop
deprecated: scala, it's part of the API
deprecatedInheritance: scala, it's part of the API
deprecatedName: scala, it's part of the API
deprecatedOverriding: scala, it's part of the API
inline: annotation, it's just a hint to the optimizer
native: scala, it changes the program's meaning
noinline: annotation, it only affects the optimizer
specialized: annotation, it's an implementation detail
throws: scala, it's part of the API
transient: not sure, it only affects java serialization IIUC, which is
often avoided in scala and not fundamental to the program itself, but it
does change behavior and is part of how Java works
unchecked: annotation, it's just a workaround for a compiler warning
volatile: scala, it changes the programs behavior, although in a subtle
way
On Mon, Mar 2, 2020 at 12:02 PM Naftoli Gugenheim naftoligug@gmail.com
wrote:
Another option (also not necessary to go into 3.0) is that we make a new
package scala.annot, deprecating scala.annotation (exports can help). Then
it's just@annot.tailrec. I don't consider that very noisy.On Mon, Mar 2, 2020 at 12:00 PM Naftoli Gugenheim naftoligug@gmail.com
wrote:I don't see the point of adding another language rule, but if you're
going to, here's a simpler one, that addresses @sjrd's point about
libraries:An annotation
@arefers toaif it is available in the current scope,
otherwise it is expanded to@annotation.aand that is tried as well.This works for scala.annotation because scala._ is imported
so @annotation.tailrec is valid. It also could be used by libraries, e.g.
if I do import lib._ and there is a lib.annotation package then @a could
resolve to @lib.annotation.a.Of course, in that case scala.annotation would presumably be shadowed, so
you'd have to be careful about your imports, but that isn't really anything
new.That said, I think Dotty already adds way too many language rules for one
version bump, so I would be against adding anything for this in 3.0.On Mon, Mar 2, 2020 at 11:49 AM odersky notifications@github.com wrote:
Note also that no annotations are currently defined in Predef. So
adding some would create another irregularity.—
You are receiving this because you are subscribed to this thread.
Reply to this email directly, view it on GitHub
https://github.com/lampepfl/dotty/issues/8419?email_source=notifications&email_token=AAAYAUCLLCDKTGUVIESMVRTRFPPSLA5CNFSM4K7RVG72YY3PNVWWK3TUL52HS4DFVREXG43VMVBW63LNMVXHJKTDN5WW2ZLOORPWSZGOENQBRUQ#issuecomment-593500370,
or unsubscribe
https://github.com/notifications/unsubscribe-auth/AAAYAUEWWBYUG7O7BXF4U2DRFPPSLANCNFSM4K7RVG7Q
.
I would be against putting all annotations in scala. There are some very common names that would be injected into everyone's scope that way.
Hmmmm.... but they're only common names in term namespace, not type namespace. And annotations have initial-lowercase names, whereas types practically always have an initial capital. So:
scala 2.13.1> import annotation.tailrec
import annotation.tailrec
scala 2.13.1> tailrec
^
error: not found: value tailrec
scala 2.13.1> 3: tailrec
^
error: type mismatch;
found : Int(3)
required: scala.annotation.tailrec
Therefore, actual collisions seem highly unlikely. (I'm not saying that swings any decisions, I just wanted to point it out in case it's not obvious.)
Is it really necessary to make this change now that we have export?
I mean, the users can export all their own commonalities into their namespace once.
EDIT: rethinking this, ignore what I wrote. It would be problematic for a library to export such a namespace into itself
I agree that this can wait post 3.0. But as long as a fundamental change is on the table, it seems premature to start moving annotations around to other packages or adding aliases. We lived with the situation for a long time, we can live with it a bit longer.
Most helpful comment
This seems like a very ad hoc rule in the compiler to remove some arguably boilerplate-y imports of the standard library. What about other libraries defining annotations in their subpackages
xyz.annotation._? If we're not addressing custom annotations in libraries, I don't see the point of addressing the few annotations in the stdlib. And if we're arguing that the ones in the stdlib are so commonly used that they deserve less boilerplate, then I really don't see why we can't put them inscala.