Dropped: Package Objects says package objects will be dropped. But there’s three areas which the replacement (top level definitions) does not suffice:
-
Top-level definitions does not allow statements like
println(1)
. Or it does, but you need to wrap them inval _ = println(1)
. This seems like a pretty silly restriction with a pretty silly workaround.- Given we already allow top-level wrapper objects to have non-lazy initialization logic with
val
s, we should just allow top level statements. Apart from improving consistency and removing a weird restriction/workaround, this would also make vanilla.scala
files to be usable for scripts without custom wrapping like Ammonite and Scala-CLI do. Other typed/compiled languages like C# allow top level statements without issue, in scripting languages like Python/Ruby/Javascript this is the default, and of course Ammonite/Scala-CLI demonstrate there’s a broad use case even in Scala (and.kts
in Kotlin or.fsi
in Fsharp)
- Given we already allow top-level wrapper objects to have non-lazy initialization logic with
-
Top-level wrapper objects cannot inherit from traits or classes. This is pretty common in my experience, e.g. having
package object foo extends Thing
have the default instance of something andpackage foo; object Bar extends Thing
andpackage foo; object Qux extends Thing
have other available instances, all of which implement the same interface and inherit the same implementations.- One limitation of doing this is that you can’t do
val x = foo
whenfoo
is a package object, as it complainspackage foo is not a value
, and you have to sayval x = foo.package
. This seems like a restriction that should be liftable right, to makeval x = foo
automatically expand toval x = foo.package
? That would help smooth out one of the warts of package objects today
- One limitation of doing this is that you can’t do
-
package object
s serve as a natural place to put package-level Scaladoc and other documentation, similar tomodule-info.java
files or python__init__.py
files. Without that, there’s nowhere to put “package scaladoc”.readme.md
files work fine when browsing the repo but are not slurped up by scaladoc.
All of these seem fixable, but thinking further, what is a package object
other than object package; export package.*
? I understand having top-level definitions is great, but given that package objects seem to have a pretty trivial desugaring in terms of other existing language features, it seems like the cost of keeping them around indefinitely for backwards compat isn’t too much. And other languages have module-info.java
or __init__.py
files that serve similar purposes, which indicates to me that the idea of a “primary file for a folder full of files” does have value as a general abstraction