diff --git a/_style/files.md b/_style/files.md index 54ddf4e2db..f52df47689 100644 --- a/_style/files.md +++ b/_style/files.md @@ -11,33 +11,32 @@ previous-page: method-invocation next-page: scaladoc --- -As a rule, files should contain a *single* logical compilation unit. By -"logical" I mean a class, trait or object. One exception to this -guideline is for classes or traits which have companion objects. -Companion objects should be grouped with their corresponding class or -trait in the same file. These files should be named according to the -class, trait or object they contain: +The unit of work for the compiler is a "compilation unit", +which is usually just an ordinary file. +The Scala language places few restrictions on how code is organized across files. +The definition of a class, or equivalently a trait or object, can't be split over multiple files, +so it must be contained within a single file. +A class and its companion object must be defined together in the same file. +A sealed class can be extended only in the same file, so all its subclasses must be defined there. - package com.novell.coolness +Similarly, there are no restrictions on the name of a source file or where it is located in the file system, +although certain conventions are broadly honored in practice. +Generally, the file is named after the class it contains, +or if it has more than one class, the parent class. + +For example, a file, `Inbox.scala`, is expected to contain `Inbox` and its companion: + + package org.coolness class Inbox { ... } // companion object object Inbox { ... } -These compilation units should be placed within a file named -`Inbox.scala` within the `com/novell/coolness` directory. In short, the -Java file naming and positioning conventions should be preferred, -despite the fact that Scala allows for greater flexibility in this -regard. - -## Multi-Unit Files +The file may be located in a directory, `org/coolness`, following Java tooling conventions, +but this is at the discretion of the developer and for their convenience. -Despite what was said above, there are some important situations which -warrant the inclusion of multiple compilation units within a single -file. One common example is that of a sealed trait and several -sub-classes (often emulating the ADT language feature available in -functional languages): +It is natural to put the following `Option` ADT in a file, `Option.scala`: sealed trait Option[+A] @@ -45,26 +44,12 @@ functional languages): case object None extends Option[Nothing] -Because of the nature of sealed superclasses (and traits), all subtypes -*must* be included in the same file. Thus, such a situation definitely -qualifies as an instance where the preference for single-unit files -should be ignored. - -Another case is when multiple classes logically form a single, cohesive -group, sharing concepts to the point where maintenance is greatly served -by containing them within a single file. These situations are harder to -predict than the aforementioned sealed supertype exception. Generally -speaking, if it is *easier* to perform long-term maintenance and -development on several units in a single file rather than spread across -multiple, then such an organizational strategy should be preferred for -these classes. However, keep in mind that when multiple units are -contained within a single file, it is often more difficult to find -specific units when it comes time to make changes. - -**All multi-unit files should be given camelCase names with a lower-case -first letter.** This is a very important convention. It differentiates -multi- from single-unit files, greatly easing the process of finding -declarations. These filenames may be based upon a significant type which -they contain (e.g. `option.scala` for the example above), or may be -descriptive of the logical property shared by all units within (e.g. -`ast.scala`). +The related elements, `Some` and `None`, are easily discoverable, even in the absence of tooling. + +When unrelated classes are grouped together, perhaps because they implement a feature or a model a domain, +the source file receives a descriptive `camelCase` name. +Some prefer this naming scheme for top-level terms. For example, `object project` would be found in `project.scala`. +Similarly, a package object defined as `package object model` is located in `package.scala` in the `model` source directory. + +Files created just for quick testing can have arbitrary names, such as `demo-bug.scala`. +