Just a little question here.
I found on Play Framework 2 sources:
private[data] object FormUtils {
...
}
Just wonder what the [data] means? Is it just some fancy syntax to say the object / class belongs to a subfolder?
It means that this class can only be used from package play.api.data and its subpackages. It's close to package-private visibility level in Java, but with two differences:
It's visible from subpackages (there are no subpackages in Java, but in Scala, e.g. play.api.data.foo is considered a part of play.api.data).
You can write, e.g. private[api], and it would be visible from all subpackages of play.api.
This article explains Scala access modifiers in more detail.
Related
I've recently started programming in Scala, coming from Python and Java I was wondering what the correct way or the accepted way is when defining objects/classes in Scala. Scala supports, just like python, to add several class or object definitions in a single file.
So purely from an accepted structure perspective, does every object need to be defined in its own file or are you allowed to choose this yourself?
There is a chapter in the official Scala Style Guide on this. It's pretty clear in itself, but I'll just leave some quotes here.
The core idea is:
As a rule, files should contain a single logical compilation unit. By “logical” I mean a class, trait or object.
There is, of course, an exception for companion objects:
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.
There is also the fact that sealed only works within the same file.
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. Because of the nature of sealed superclasses (and traits), all subtypes must be included in the same file.
Most of the time, case classes are just simple data containers and can be grouped together.
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.
Finally, there is a naming convention for exempted multi-unit Scala files:
All multi-unit files should be given camelCase names with a lower-case first letter.
So: put your Scala classes and objects in separate files, unless they fall into one of the three mentioned exceptions.
In Scala, it is perfectly valid to have multiple classes within a single file AS LONG AS they are tightly related.
But not all languages encourage this convention, and I think it is worth considering the reason.
I personally dislike it when people put multiple classes into a single file because it makes it harder to find a class definition. This is magnified in code reviews where I want to be able to review code as quickly as possible without digging around.
Cons
Code reviews require me to do more searching to find a class
I don't like having to grep to find a file
A consistent naming convention allows me to use my text editor or IDE tools to quickly open a file by the class name
Pros
As Jesper pointed out, certain scenarios require it
Support classes/traits are kept hidden to minimize file structure "noise"
Sometimes you have to put several traits, classes or objects in one source file, particularly when you are using sealed traits. A sealed trait can only be extended inside the same source file.
For example, the Predef object says it extends LowPriorityImplicits, but there is no documentation for LowPriorityImplicits.
https://www.scala-lang.org/api/current/scala/Predef$.html
More curious than anything else.
There is a part of the Scala language that is privately packaged because things otherwise can go wrong if they were to be used immaturely and compromise the soundness of the language, among other reasons. The docs for those private definitions don't get generated and published. You can see the implementation of LowPriorityImplicits here
This is more of a design and readability/maintainability question rather than a technical one.
Sometimes in Scala, you get these one liner classes (often case classes), which are typically used to hold data. They're very synonymous with Java beans, but with constructor parameters actually being val members, no need for setter methods due to immutability, and no need for toString due to the nice feature of case classes, you end up with just one line consisting of constructor parameters.
I find it wasteful to put these one-liners in a separate Scala file, and I hate to put them with other more meaty Scala classes because it starts to become confusing (even in IntelliJ IDEA it starts to pollute the project source tree).
I started a new habit of putting these single liners in the Package Object package.scala file of that package. Is there any disadvantage to this from a maintainability point of view? I am just putting them there for lack of a better place. Is there any better approach?
I don't think there is a disadvantage in that, but also I don't see an immediate advantage or reason to do so.
You may have a look at this question. Basically, if you use the -Xlint compiler flag, you will be told that you should not put classes into a package object.
If you want to have several classes together because of their one-line nature, you can put them still together in one file, it doesn't have to be a package object. E.g.
// utils.scala
package foo
case class FooUtil()
case class BarUtil()
Instead of package object foo { case class FooUtil() ... }
After watching Martin's keynote on Reflection and Compilers I can't seem to get this crazy question out of my head. Martin talks among other things about the "(Wedding) Cake Pattern", where traits play the central part. I'm wondering, why in the world do we need packages when we already have traits? Is there anything a package can do, what a trait (at least theoretically) cannot?
I'm not talking about the current implementation, I'm just trying to imagine what programming would be like if we replace packages with traits. In my head it would be like this:
one keyword less (package is unneeded)
no need for package objects
To summarize all my questions:
Is it theoretically possible to remove packages from the language and use traits instead.
What other benefits would we gain from this change? (I was thinking about first class packages and first class imports, but mixin composition is a compile time thing, although the super calls are dynamically bound)
Is Java/JVM compatibility the only thing, which would stand in the way?
Update
Daniel Spiewak talks in this keynote about the Dependency Injection being just the top of the iceberg of all the stuff you can do with the Cake Pattern.
Martin Odersky has said that Scala could get by with just traits, objects, methods and paths (I hope I didn't forget something).
Both classes and packages are just there because Scala is intended to be a hosted language, i.e. a language which runs on (this is actually not the interesting bit) and interoperates with (this is the important point) a host platform. Some of the host platforms that Scala is intended to interoperate with are the Java platform and the CLI, both which have a concept of classes and packages (namespaces in the case of the CLI) that is significantly distinct enough that it cannot be easily expressed as traits or objects. This is unlike interfaces, which can be trivially mapped to and from purely abstract traits.
The above statement was made in a discussion about potentially removing generics from Scala, because everything generics can do can also be achieved by abstract types.
In scala the object and package serve almost the same purpose and objects are also called modules. Objects deserve to be thought of as modules because they can contain any definition including other objects of course and, significantly, types.
A trait can be thought of as an abstract module. It can contain any definition and any member can be abstract including, again significantly, type members. I am reciting all this just to highlight the symmetry. Perhaps OT but to me traits seem to be as big an innovation in scala as the merging of object and functional ideas.
To finally give an answer:
I think packages could be removed in favour of objects (not traits).
The benefit would be a simplification - package objects would not need to be explicitly defined.
I think packages are distinct from objects for Java/JVM compatibility.
Some more commentary: in the video Martin talks of traits (abstract modules) more than concrete modules because the latter only appear at the last moment to assemble and reify some combination of abstract modules.
It is good to use abstract modules even when not "mixing a cake". e.g. when sketching out some code you might define a module to contain definitions. But as soon as you come to a type or value you are not ready to fill in, don't supply a dummy such as null. Instead switch the object to a trait and leave the member abstract.
Scala 2.10 brings reflection other than that provided the JVM (or I guess CLR).
What in particular do we have to look forward to, and how will it improve on the platform?
For example, will there be a class that reflects the language's convertibility between fields and accessor methods, so that I can iterate over the properties of an object?
update 2012-07-04:
Daniel SOBRAL (also on SO) details in his blog post "JSON serialization with reflection in Scala! Part 1 - So you want to do reflection?" some of the features coming with reflection:
To recapitulate, Scala 2.10 will come with a Scala reflection library.
That library is used by the compiler itself, but divided into layers through the cake pattern, so different users see different levels of detail, keeping jar sizes adequate to each one's use, and hopefully hiding unwanted detail.
The reflection library also integrates with the upcoming macro facilities, enabling enterprising coders to manipulate code at compile time.
update 2012-06-14. (from Eugene Burmako):
In Scala 2.10.0-M4, we have released the new reflection API that will most likely make it into 2.10.0-final without significant changes.
More details about the API can be found:
SO answer Get companion object instance with new Scala reflection API
Scala Reflection SIP, June 2012 by Martin Odersky (SIP, actually "Scala Improvement Process")
summary and migration route from M3
Extracts:
Universes and mirrors are now separate entities:
universes host reflection artifacts (trees, symbols, types, etc),
mirrors abstract loading of those artifacts (e.g. JavaMirror loads stuff
using a classloader and annotation unpickler, while GlobalMirror uses internal compiler classreader to achieve the same goal).
Public reflection API is split into scala.reflect.base and scala.reflect.api.
The former represents a minimalistic snapshot that is exactly enough to
build reified trees and types.
To build, but not to analyze - everything smart (for example, getting a type signature) is implemented in scala.reflect.api.
Both reflection domains have their own universe: scala.reflect.basis and
scala.reflect.runtime.universe.
The former is super lightweight and doesn't involve any classloaders,
while the latter represents a stripped down compiler.
Initial answer, Sept. 2011:
You can see evolutions of the reflect package in the Scala GitHub repo, with this two very recent commits:
Changes to Liftcode to use new reflection semantics, where a compiler uses type checking.
Started work on compiler toolbox that can compile reflect trees at runtime.
(Liftcode being, according to this thread, aims at simplifying "writing code that writes code")
The class scala/reflect/internal/Importers.scala (created yesterday!) is a good example of using those latest reflection feature.
Two links which should be of interest:
The scala-internals mailing list discussion on the reflection api.
The nightly build api doc for 2.10-SNAPSHOT.
Personally I am hoping to use this for doing runtime discovery of extensions (i.e. a type that extends a known trait), and generating UI forms and a few other things from those.
With current 2.10M4 you already can iterate over members of a class:
reflect.runtime.universe.typeOf[MyClass].members.filter(!_.isMethod)
The above code lists Symbol objects representing members of a class MyClass which are not methods. There are tons of ways you can fine-tune this.