Package object for one-liner Scala classes - scala

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() ... }

Related

Why case class and object with different names appear in same scala file? [duplicate]

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.

Scala: Difference between file.class and file$.class from scalac

When I use scalac to compile file.scala, I end up with 2 outputs, file.class and file$.class. What is the difference between these files and which is the appropriate one to then run? I get distinctly different error messages between executing "scala file" vs "scala file$".
Scala objects get compiled to classes ending in "$" because you're allowed to have an "ordinary" class with the same name. But the object's methods are also exposed as static methods on the "ordinary" class, so that they can be called under the names you would expect. This is an artifact of trying to represent the scala semantics in a way that make sense to Java / the JVM, and I would encourage you to regard it as an implementation detail rather than something important.
(#MattPutnam's answer is correct that anonymous classes, including closures, are compiled to class files with $es in their name, but that's not what's causing your file$.class in this particular instance)
Use scala file. If you're interested in the implementation details you might also want to try java -cp /path/to/scala-library.jar file.
file$.class is some inner anonymous class. In Java they're very explicit, but they can be easy to miss in Scala. If you use any method that takes a function, there's an implicit anonymous class there. Post the code and I'll point it out.

Scala style: More than one class in a file?

Unlike Java, Scala supports putting multiple classes in one file. Since Scala's classes are often quite short (think case classes), this often seems to make sense.
What is considered the proper style and idiom to do this, on production code? Under what circumstances should short or associated classes be put in the same file? How should that file be named?
This is all covered in Scala style guide
Summary :
As a rule of thumb, you should have one logical compilation unit (i.e
trait, class, object) per file.
Exception made of companion objects
where you can have them as well as their original trait/class in the
same file
Another exception is sealed trait with its subclasses
Last exception is if it makes way more sense maintenance wise (i.e your logical compilation units forms a inseparable, cohesive group)
Multi-unit file should have a lowercase first letter.

Traits vs. Packages in Scala

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.

Is the word "Helper" in a class name a code smell?

We seems to be abstracting a lot of logic way from web pages and creating "helper" classes. Sadly, these classes are all sounding the same, e.g
ADHelper, (Active Directory)
AuthenicationHelper,
SharePointHelper
Do other people have a large number of classes with this naming convention?
I would say that it qualifies as a code smell, but remember that a code smell doesn't necessarily spell trouble. It is something you should look into and then decide if it is okay.
Having said that I personally find that a name like that adds very little value and because it is so generic the type may easily become a bucket of non-related utility methods. I.e. a helper class may turn into a Large Class, which is one of the common code smells.
If possible I suggest finding a type name that more closely describes what the methods do. Of course this may prompt additional helper classes, but as long as their names are helpful I don't mind the numbers.
Some time ago I came across a class called XmlHelper during a code review. It had a number of methods that obviously all had to do with Xml. However, it wasn't clear from the type name what the methods had in common (aside from being Xml-related). It turned out that some of the methods were formatting Xml and others were parsing Xml. So IMO the class should have been split in two or more parts with more specific names.
As always, it depends on the context.
When you work with your own API I would definitely consider it a code smell, because FooHelper indicates that it operates on Foo, but the behavior would most likely belong directly on the Foo class.
However, when you work with existing APIs (such as types in the BCL), you can't change the implementation, so extension methods become one of the ways to address shortcomings in the original API. You could choose to names such classes FooHelper just as well as FooExtension. It's equally smelly (or not).
Depends on the actual content of the classes.
If a huge amount of actual business logic/business rules are in the helper classes, then I would say yes.
If the classes are really just helpers that can be used in other enterprise applications (re-use in the absolute sense of the word -- not copy then customize), then I would say the helpers aren't a code smell.
It is an interesting point, if a word becomes 'boilerplate' in names then its probably a bit whiffy - if not quite a real smell. Perhaps using a 'Helper' folder and then allowing it to appear in the namespace keeps its use without overusing the word?
Application.Helper.SharePoint
Application.Helper.Authentication
and so on
In many cases, I use classes ending with Helper for static classes containing extension methods. Doesn't seem smelly to me. You can't put them into a non-static class, and the class itself does not matter, so Helper is fine, I think. Users of such a class won't see the class name anyway.
The .NET Framework does this as well (for example in the LogicalTreeHelper class from WPF, which just has a few static (non-extension) methods).
Ask yourself if the code would be better if the code in your helper class would be refactored to "real" classes, i.e. objects that fit into your class hierarchy. Code has to be somewhere, and if you can't make out a class/object where it really belongs to, like simple helper functions (hence "Helper"), you should be fine.
I wouldn't say that it is a code smell. In ASP.NET MVC it is quite common.