title: Why are classes inside Scala package objects dispreferred?
body: <p>Starting with 2.10, <code>-Xlint</code> complains about classes defined inside of package objects. But why? Defining a class inside a package object should be exactly equivalent to defining the classes inside of a separate package with the same name, except a lot more convenient.</p>
  
  <p>In my opinion, one of the serious design flaws in Scala is the inability to put anything other than a class-like entity (e.g. variable declarations, function definitions) at top level of a file. Instead, you're forced to put them into a separate ''package object'' (often in <code>package.scala</code>), separate from the rest of the code that they belong with and violating a basic programming rule which is that conceptually related code should be physically related as well. I don't see any reason why Scala can't conceptually allow anything at top level that it allows at lower levels, and anything non-class-like automatically gets placed into the package object, so that users never have to worry about it.</p>
  
  <p>For example, in my case I have a <code>util</code> package, and under it I have a number of subpackages (<code>util.io</code>, <code>util.text</code>, <code>util.time</code>, <code>util.os</code>, <code>util.math</code>, <code>util.distances</code>, etc.) that group heterogeneous collections of functions, classes and sometimes variables that are semantically related. I currently store all the various functions, classes, etc. in a <code>package object</code> sitting in a file called <code>io.scala</code> or <code>text.scala</code> or whatever, in the <code>util</code> directory. This works great and it's very convenient because of the way functions and classes can be mixed, e.g. I can do something like:</p>
  
  <pre><code>package object math {
    // Coordinates on a sphere
  
    case class SphereCoord(lat: Double, long: Double) { ... }
  
    // great-circle distance between two points
    def spheredist(a: SphereCoord, b: SphereCoord) = ...
  
    // Area of rectangle running along latitude/longitude lines
    def rectArea(topleft: SphereCoord, botright: SphereCoord) = ...
  
    // ...
    // ...
  
    // Exact-decimal functions
    class DecimalInexactError extends Exception
  
    // Format floating point value in decimal, error if can't do exactly
    formatDecimalExactly(val num: Double) = ...
  
    // ...
    // ...
  }
  </code></pre>
  
  <p>Without this, I would have to split the code up inconveniently according to fun vs. class rather than by semantics. The alternative, I suppose, is to put them in a normal object -- kind of defeating the purpose of having package objects in the first place.</p>