Wille Faler is an experienced software developer, architect and agile coach with experience across a number of different industries as an independent consultant. Wille specializes in backend, integration, and Java technologies, but has more recently found a passion for Scala and text mining/analysis. Wille is a DZone MVB and is not an employee of DZone and has posted 39 posts at DZone. You can read more from them at their website. View Full User Profile

Why Scala Doesn’t Have Java Interfaces (And Doesn’t Need Them)

02.17.2011
| 9594 views |
  • submit to reddit

One thing that puzzled me a little when I started out in Scala was the lack of interfaces and the choice of “traits” instead, which seemed to be a hybrid between interfaces and abstract classes from Java. How are you supposed to achieve clean polymorphism without interfaces I wondered?

Well, turns out what has a single solution in Java actually has a multitude of solutions in Scala, the obvious one is to use traits as straight interface replacements, and that certainly works.

However, there are two even more elegant solutions available in Scala that doesn’t force you to implement/extend a specific trait:

Function Passing
Given Scala’s functional aspects, one obvious alternative to traits is function passing. Say you want to do something with an InputStream, and you want to force the client of a function to have an “interface” that takes an InputStream as an argument and returns just about anything (or nothing). Well, that’s easy-peasy with Scala: 
  def getAbsoluteResource(path: String)(op: InputStream => Any) = {..}

def someInputStreamFunction(io: InputStream): Unit = {..}

// call the function:
getAbsoluteResource("/myPath.properties")(someInputStreamFunction)
In the actual call, we may replace the “someInputStreamFunction” with just about any other function, from any other object that conforms to the same contract. Why should we be forced extend specific traits and have specific names for our functions if that just works?

Also, this style of programming allows for some interesting things such as “around blocks”, which are in fact functions that take functions/function closures as an argument. This certainly makes lifecycle management a lot easier than the customary verbose Java-style of defining lifecycle methods on interfaces.
An example of this sort of “around” pattern with function passing is the below example of JPA transaction management with the recursivity-jpa library:
transaction{
..your code within the transaction/persistence context goes here..
}
Structural Types/”Static Duck Typing”
How many times have you created interfaces like “Identifiable” with a “getId” method in Java merely to deal with entities that need persisting in a more generic way? I have, a lot. Well, Scala has a powerful little feature called “Structural Types” that can get rid of all of this - it is basically a means of enforcing a contract on a type without forcing it to extend anything else. You do this as follows:
def someFunction(identifiable: {def id: Long}){
..do stuff..
}
Here we have basically instructed the compiler to say that the function “someFunction” can take any argument that is of type “AnyRef”, but the AnyRef argument MUST have a function on it called “id” that returns a Long. Incidentally, for case classes, “def” will work fine with val’s and var’s defined in the case class constructor. Pretty neat, huh? Of course, you can further use structural types with casts in “asInstanceOf” or “isInstanceOf”, or combine it with Generics. In other words, you can enforce an old-school “Java interface” without having to explicitly implement an interface. The absolute prime example where this is useful is the case I already mentioned: in persistence code where entities need to be identifiable, but you don’t want to force a trait/interface down the throats of the entities.

So there you have it, a small primer of why Scala doesn’t need Java interfaces: Scala simply has more elegant ways of dealing with the same problem, without any of the weight that comes with Java interfaces.

This may be pretty basic stuff for the seasoned Scala developer, but I thought I’d put it down in writing so newbies have an easily accessible explanation for an issue that is quite a common question that I come across with people that are new to Scala.

References
Published at DZone with permission of Wille Faler, author and DZone MVB. (source)

(Note: Opinions expressed in this article and its replies are the opinions of their respective authors and not those of DZone, Inc.)

Tags:

Comments

Cedric Beust replied on Thu, 2011/02/17 - 1:10pm

These two examples are very poor and limited substitutes to interfaces. 1) Passing methods will only work in the simplest cases, where the interface you would pass only has one method (a "SAM"). 2) Structural typing is dangerous and should be avoided, here are a few reasons why: http://beust.com/weblog/2008/02/11/structural-typing-vs-duck-typing/ The bottom line is that traits are the right replacement for interfaces in Scala. And yes, whenever you are tempted to use structural typing, you should most likely take the time to create a trait capturing the interface you are trying to pass around, which will most likely come in handy down the road.

Wille Faler replied on Thu, 2011/02/17 - 1:34pm

Cedric:
I certainly agree that traits should be preferred most of the time, however I feel there are a number of cases where function passing or structural types are preferable:

Lifecycle management:
All the "before", "after", "onSomeEvent" and other types of lifecycle methods that are littered across a lot of Java frameworks are a blight and a mess forced by what Java is. In these cases, the "around"-pattern style that function-passing allows, and being able to chain nested functions and function calls is a very elegant and flexible solution for what is a very messy and inflexible thing in Java (In Java, once you have defined your life-cycle methods/events, you are stuck with them in the public API, and re-ordering or changing them will have unexpected consequences for API clients).

Persistence:
If you want to write DRY code for persistence, you will often have to be able to generically identify objects that are persistable. But do you want every domain object that is persistable depend on an interface like "Identifiable" or "KeyedEntity"? I certainly don't. In this case I think a structural type as in the example is preferable over adding interfaces/traits to each and every class that is persistence enabled.

Mario Fusco replied on Thu, 2011/02/17 - 5:41pm in response to: Cedric Beust

Sorry, but I don't agree with that post. Structural typing IS duck typing done right and you can easily make it DRY by assigning a type alias to its declaration. Not rocket science.

Cedric Beust replied on Thu, 2011/02/17 - 6:05pm

Mario: in short, you're disagreeing with me by paraphrasing what I said :-)

Another problem with structural typing in Scala is that it doesn't work with instanceof, which is one more reason why you should never use it and always take the time to create a type for it (be it class, trait or whatever makes sense).

Mario Fusco replied on Fri, 2011/02/18 - 5:07am in response to: Cedric Beust

Cedric I don't see how I am paraphrasing what you said. I was saying that if you want to use structural typing and stay DRY you could use a type alias like that:

    type Named = {def getName(): String}

Sorry if I missed that, but I don't see in which point you wrote something similar.

Wille Faler replied on Fri, 2011/02/18 - 5:28am

Cedric: Thanks for pointing out that isInstanceOf and asInstanceOf don't work with structural types. Kind of assumed they would - though casting works it will throw a "NoSuchMethodException", I'm not sure that's the desirable behavior in that instance..

Cedric Beust replied on Fri, 2011/02/18 - 1:19pm

Mario, here is what I wrote above, which seems to be exactly what you're saying as well: "whenever you are tempted to use structural typing, you should most likely take the time to create a trait"

Eric Giese replied on Mon, 2011/02/21 - 3:55am

Concerning traits vs. structural typing: There is no definite answer to that question in my opionion. I guess it depends on wether you are writing code for "open" or "closed" usage scenarios.

If you are writing a public API and want to define "handler" interfaces with multiple methods, or are writing methods which operate on well-defined datastructures, than structural typing is superior. Thats because you do not enforce an interface on the caller which he perhaps cannot provide without writing glue code.
The best example for this is the "id" type given, in example when you are operating on DAOs with have nothing in common except this id. Structural types are easier to provide by external callers, because they do not force interface contracts into POJOs.

However, in nearly all other cases where you have absolute control over the sourcecode, traits are clearly the better solution, because they are not purely virtual and easier to extend.

County Line Nissan replied on Mon, 2011/08/01 - 11:00am

This may be pretty basic stuff for the seasoned Scala developer, but I thought I’d put it down in writing so newbies have an easily accessible explanation for an issue that is quite a common question that I come across with people that are new to Scala. -County Line Nissan

Comment viewing options

Select your preferred way to display the comments and click "Save settings" to activate your changes.