Take the 2-minute tour ×
Programmers Stack Exchange is a question and answer site for professional programmers interested in conceptual questions about software development. It's 100% free, no registration required.

I've been promoting Scala at work as something we should try out for things like testing with Specs http://code.google.com/p/specs/ and rapid prototyping of web services with tools like Scalatra https://github.com/scalatra/scalatra and Lift http://liftweb.net.

A technical manager is interested in hearing more about Scala, and has no experience with the language. I've pointed out how Scala prototypes could be written quickly and deployed into our existing Java infrastructure as well as use our existing Java libraries. He is largely interested in the specific benefits of using Scala over Java and will be interested in concrete examples.

I'd like to hear any thoughts or experiences people have introducing Scala to technical management. Thoughts on good code, clear, concise examples that demonstrate a big win over the Java equivalent, would be greatly appreciated.

Some examples areas for discussion I have been thinking about are:

REPL
A big win over Java, and I use it every day to test the Java code I am writing.

Basic Collection Iteration
One of the first areas I think Java programmers can see immediate benefit.

Type Inference
We use a lot of Python at work - I think less type boilerplate in a strongly typed language will be appealing.

Java Integration
Given our Java investment, this will be a biggie.

Concurrency
A brief run through of Akka actors and the new parallel collections. I'd love to see any small, focused examples anyone has here.

Specs
I've been finding BDD with Specs excellent for testing Java applications.

Web development
I've found Scalatra ideal for rapid development of REST services.

Please share any other areas you think might be of interest as well as any focused code examples in these or other areas you think demonstrate advantages of Scala over the Java equivalent.

EDIT: To be perfectly clear I am primarily interested in concise concrete code examples appropriate to this situation. Not at all interested in another "Java vs Scala" thread. I hope that was clear. Something like:

Java:

Foo theFoo = null;
for(Foo aFoo: allTheFoos) {
  if (aFoo.getId().equals(theIdIWant)) {
    theFoo = aFoo;
    break;
  }
}

Scala:

val thefoo = allTheFoos.find(aFoo.id == theIdIWant)
share|improve this question

migrated from stackoverflow.com Jan 23 '11 at 16:12

This question came from our site for professional and enthusiast programmers.

3  
i think this is suited more in programmers.stackexchange.com than in here , here we want code :D –  Saif al Harthi Jan 22 '11 at 16:53
    
I considered it, but I'm really very much hoping to compile a set of good code examples. This is not a PowerPoint pitch. I need to show concrete code examples. –  Janx Jan 22 '11 at 16:58
    
What's a technical manager? If you're pitching to just one person, it matters a lot who they are and how they think. –  huynhjl Jan 22 '11 at 19:11
1  
Excellent point about audience - In this case the tech lead on my project and a top level engineer in the company. A person who still writes a lot of code (mostly C++) but also does a lot of architecture and design and has considerable influence on company technical direction. –  Janx Jan 22 '11 at 20:06
add comment

3 Answers

up vote 19 down vote accepted

REPL - I was using scala at work for a long time before I really started to use the REPL regularly. It can be useful for checking little things (like: how will a very large BigDecimal format itself using toString?) But I've started using it much, much more since I started using scalaz and functional-programming, because it allows for quick playing around with types (it's very useful for checking what is being inferred).

Collections - with the collection framework and the io.Source utility, it's incredibly easy to write scripting-style stuff to slice and dice data which you might want to do every day. For example, I get an ad-hoc query to find out the distinct values in column 7 on the 2nd line of each file in a directory with >50k files in it:

def toEntry(f : java.io.File) : Option[String] =
  Source.fromFile(f).getLines.drop(1).headOption map (l => l.split(",")(6).trim)

((new java.io.File("/some/dir").listFiles) flatMap toEntry) toSet

The great thing is that I can do this in the REPL, playing around. For someone whose bash skills are not so great, it can be a real boon.

Obviously the collections are just awesome when doing serious programming. Java methods to do things like aggregate trades which used to be tens of lines of messy code are now a few lines of clear, maintainable scala.

Java Integration - scala interoperates with Java. End of story. You get to leverage everything you like or need.

Concurrency - this is the biggest win. I just cannot explain how much easier the actor model is to code against than what I used to do in Java with executors and locks/synchronization. Each actor is conceptually a thread processing a queue and yet this scales happily to tens of thousands of actors (I believe that Viktor Klang has benchmarked Akka with over a million actors running in a single VM. That's a lot of dining philosophers!).

To give an example, I have just finished re-writing a system we have to process market data and our trading positions to distribute real-time P&L to our traders. The original Java server was single-threaded (i.e. all market data was pushed onto a single queue for processing). There were a number of things that this system simply could not reasonably accomplish because of its single-threaded nature. That is, in order (for example) to recover a single missed trade, I would have to effectively pause the whole system, rather than just that trader's book. I wrote the replacement system in under 3 days (admittedly leveraging off other work I have done). Development in scala is just so much quicker than Java.

Type Inference - well, obviously this saves a lot of writing. My argument (when I was a Java developer) was that my IDE was able to help me generating all of this boilerplate (extract method, introduce parameter etc). But that completely misses the point! When I look at Java now, all I see is a bunch of for, while, if loops and types. What the code is actually doing is completely hidden:

Map<Region, Map<TradeID, Trade>> m = service.getTradesByRegion();
BigDecimal totalUSD = BigDecimal.ZERO
for (Map.Entry<Region, Map<TradeID, Trade>> e : m.entrySet() {
    if (!shouldInclude(e.getKey())) {
        continue;
    }
    Map<TradeID, Trade> ts = e.getValue(); 
    for (Map.Entry<TradeID, Trade> p : ts.entrySet()) {
        if (shouldInclude(p.getKey().getBroker())) {
            totalUSD = totalUSD.add(p.getValue().getUSDValue().getAmount().abs())
        }
    }
}

Good grief!

val totalUSD 
  = (service.tradesByRegion filterKeys shouldInclude).values.flatten collect { 
      case (id, trade) if  shouldInclude(id.broker) => trade.usdValue.amount
     } ∑

This last one is a real example and makes usage of the scalaz library and the integration with it to my own units library:

implicit def MoneyZero(implicit val ccy : Currency) = new Zero[Money] {
  def zero = Money.zero(ccy)
}
implicit def MoneySemigroup = new Semigroup[Money] {
  def append(m1 : Money, m2 : Money) = m1 + m2
}

Or you could be doubly-clever and do:

implicit def MoneySemigroup(implicit val ccy : Currency, env: MarketEnvironment) = 
  new Semigroup[Money] {
    def append(m1 : Money, m2 : Money) = m1.into(ccy) + m2.into(ccy)
  }

EDIT - I am just updating this again with another real example of scala's terseness and clarity (and thus maintainability and speed of development).

In a new project, I need to take a list of FX trades:

trait Trade {
  def pair : CcyPair
  def primaryQty : BigDecimal
  def secondaryQty : BigDecimal
  final def posns = primaryQty → secondaryQty
}

And I need to group them by currency pair, and then for each list, sum to a total amount of the primary and total amount of the secondary. Here is the code:

fxs.groupBy(_.pair) mapValues (ts => ts.map(_.posns). ∑ )

That. Is. It. This gives me a Map[CcyPair, (BigDecimal, BigDecimal)]. It works because there are Scalaz semigroups in scope for the Tuple2[A, B] where there are also semigroups for A and B. Here is the corresponding code in Java:

Map<CcyPair, Collection<Trade>> grouped = XCollections.group(fxs, new Transformer<Trade, CcyPair>() {
    public CcyPair transfer(Trade trade) {
        return trade.getCcyPair();
    }
}
Map<CcyPair, BigDecimal> primaryTotals = new HashMap<CcyPair, BigDecimal>();
Map<CcyPair, BigDecimal> secondaryTotals = new HashMap<CcyPair, BigDecimal>();
for (Map.Entry< CcyPair, Collection<Trade>> e : grouped) {
    BigDecimal d1 = BigDecimal.ZERO
    BigDecimal d2 = BigDecimal.ZERO
    for (Trade trade : e.getValue()) {
        d1 = d1.add(trade.getPrimaryQty());
        d2 = d1.add(trade.getSecondaryQty());
    }
    primaryTotals.put(e.getKey(), d1);
    secondaryTotals.put(e.getKey(), d2);
}

And I don't even really end up with what I want. Show those two code snippets to your TM and ask him to find the bug.

share|improve this answer
    
BlibbyBobbles for the win! –  Kevin Wright Jan 22 '11 at 18:15
    
Every time I've tried io.Source I have regretted it. Use cases like what you show are oh-so-tempting, but it's Source is oh-so-buggy so it's not worth it. Just my opinion. –  Erik Engbrecht Jan 22 '11 at 18:54
    
Well, the use-case was for ad-hoc scripting, so I think that should be fine. On the other hand, I'm, using Source in a production system written in mid-2009 with no issues. Admittedly, I had to cast to BufferedSource and call close back in 2.7 in order for it to behave! –  oxbow_lakes Jan 22 '11 at 19:16
    
Well, last time I tried it I was maybe two notches above ad-hoc scripting, and it exploded. I think it was a character encoding issue or something like that (I was on Windows). Or maybe it was line endings (again, good ole Windows). I don't know. All I had to go on was a stack trace that didn't point at an obvious answer and I was on company time so I couldn't spend time debugging it. Java's IO libraries just worked, even if were ugly in their imperativeness. –  Erik Engbrecht Jan 22 '11 at 19:41
5  
I'm not much of a fan of that last example, because without meaningful method names, the Scala code is as obscure as the Java code. You may understand what it is doing better, but you still don't get the business logic. –  Daniel C. Sobral Jan 22 '11 at 23:10
show 3 more comments

Funny. I was just considering asking a similar question, as I am working on a presentation for tuesday where I have one hour to "sell" Scala to the Java developers. I'll post some of my examples. Maybe you can find a use for them, and I get to test them out. Let me know if they are good or bad :)

Key points:

  • Less code
  • Fewer errors
  • More readable code

Iteration

Similar to your example I guess..

Java:

public boolean hasAtLeastOneLetterWithReplyExpected() {
  for (PersistedLetter letter : getChosenLetters()) {
    if (letter.isReplyExpected()) {
      return true;
    }
  }
  return false;
}

Scala:

def hasAtLeastOneLetterWithReplyExpected = {
  getChosenLetters.exists(_.isReplyExpected)
}

Anonymous classes

Avoid the cases where we need anonymous classes to simulate functions.

Java (from Spring ref doc.):

public Object someServiceMethod() {
  return transactionTemplate.execute(new TransactionCallback() {
    // the code in this method executes in a transactional context
    public Object doInTransaction(TransactionStatus status) {
      updateOperation1();
      return resultOfUpdateOperation2();
    }
  });
}

Scala (constructed/theoretic example):

def someServiceMethod = {
  transactionTemplate.executeInTransaction(status => {
    updateOperation1
    resultOfUpdateOperation2
  }
}

Null checking/optional values

NullPointerException is an eternal pain in Java. I see them every single day.. Using Scala Option all values that can be empty must be explicitly defined as such, so that defaults can be given by the user.

Typically seen in Java:

private CaseStatus status = null;
// ++ Code that might set the status

public String getCaseStatus() {
  if (status != null) {
    return status.getTextDescription();
  } else {
    return "";
  }
}

Solved with Scala Option type:

private var status: Option[CaseStatus] = None
// ++ Code that might set the status

def getCaseStatus =
  status.map(_.getTextDescription).getOrElse("")

Object construction

Lets say I have a Customer class that has two fields. I want to be able to construct instances with any number of the fields set. Usually our domain objects will have many more fields, but using two here to make it readable.

Java:

public class Customer {
  private String firstName;
  private String lastName;

  public Customer(String firstName, String lastName) {
    this.firstName = firstName;
    this.lastName = lastName;
  }

  public Customer(String lastName) { ... }

  public Customer(String firstName) { ... } // !! error dup constructor

  public Customer() { ... } // alternative empty constructor

  public void setFirstName(String firstName) { ... } // with setter
}

Or using Java builders:

public class CustomerBuilder {
  private Customer customer = new Customer();

  public CustomerBuilder lastName(String lastName) {
    customer.setLastName(lastName);
    return this;
  }

  public CustomerBuilder firstName( ... ) { ... }

  public Customer build() { return customer; }
}

Customer customer = new CustomerBuilder()
  .lastName("Waaler")
  .firstName("Eivind")
  .build();

In Scala we have named and default parameters. No need for multiple constructors/setter methods/builders:

// Named + default parameters
class Customer(
  val firstName: String = "",
  val lastName: String = ""
)

// Example usage
val customer = new Customer()

val customer = new Customer("Eivind", "Waaler")

val customer = new Customer(lastName = "Waaler")

val customer = new Customer(firstName = "Eivind")

val customer = new Customer(lastName = "Waaler",
                            firstName = "Eivind")

Comments? Would love to see more concrete examples from others..

share|improve this answer
    
Thanks for sharing your examples and congratulations that you work with Java developers open-minded enough to hear about Scala. I'll be sure to post the examples I come up with by the end of the weekend. –  Janx Jan 22 '11 at 20:14
    
@Janx That would be great! For my part it's important to have examples that are easy to understand from a Java perspective, so I'm trying to stay away from the most complicated Scala features for this presentation.. –  eivindw Jan 22 '11 at 21:59
add comment

I'd advise you to take some of your own code and rewrite in Scala, showing the manager a side-by-side comparison.

Concentrate on removing boilerplate and other features of Scala that help you improve the readability of your code and emphasize the underlying logic.

You probably want to avoid such advanced features as higher-kinded types and type classes, unless you can keep a clean separation between an API and consumption of that API - with the consumer being significantly cleaner that its Java equivalent.

Specific features that will help you here:

  • case classes
  • pattern matching (as in this example)
  • type inference
  • the breadth of methods available on collections
  • pimp-my-library (only if it's obviously relevant)

UPDATE

As oxbow_lakes rightly points out, the speed of development on Scala is a major factor here.

Management types are generally immune to technical whizz-bangery, but very receptive to anything that they perceive as risk.

You're already at a disadvantage here as your manager will be considering the difficulties of recruiting Scala programmers, the availability of books/consultancy/support, whether the language is going to succeed or die out when the next big thing comes along, etc.

So... you need to alleviate any such concerns, and also point out how Scala helps with risks that you already have from using Java:

Java doesn't support concurrency so easily, and computers are getting twice as parallel every 18 months

  • Java's closures are still a long way off
  • immutability by default and side-effect-free functions are a big win
  • Akka...

Time to market

  • This isn't just about getting a product to your customers, it's sometimes about producing a demo fast enough to secure buy-in toi a project from others in the company
  • Show off the REPL for fast prototyping

Maintainability

  • Type inference really helps here, as do DSLs
  • Scala's syntax is just plain more readable, unless you go out of your way to show off
  • REPL again, explore an existing codebase by launching the console from sbt or Maven

Errors

  • The richer type system helps the compiler catch a lot more that might otherwise make it into production
  • Just consider contravariance in Java Arrays vs covariance in Scala collections

UPDATE 2

Take some captures from JavaZone trailer, use Scala Johansson in any presentation you give - has to be a sure winner!

share|improve this answer
    
I would add "DSLs" and "XML support" to the list. –  Landei Jan 22 '11 at 17:40
1  
I would be careful with DSLs. Some people have very negative reactions to them. I also wouldn't bring up XML. On one hand I've written some Scala XML code that was simple and elegant that I think would have been an ugly mess in Java. On the other Scala's XML library can be a wellspring of WTF moments, so I'd be conservative and not bring it up. –  Erik Engbrecht Jan 22 '11 at 19:50
1  
XML is fair enough if you already use a lot of it and have no choice. DSLs, on the other hand, tend to be an expensive proposition containing advanced code that may scare off a newcomer. By all means show an existing DSL, such as specs or scalatest, but I wouldn't introduce someone to Scala by showing them the code behind a DSL. –  Kevin Wright Jan 22 '11 at 19:55
    
Great reply and good ideas. I definitely plan to steer clear of anything advanced like higher-kinded types, as I think that would work against me. My coworkers would definitely not see the appeal of Scala's more advanced functionality and would probably ding it with the "too complex" brand. I'm not sure about XML - I've definitely found it useful for quick one-offs. I'll give it some thought. In any event, some great thoughts here. Thanks! –  Janx Jan 22 '11 at 20:11
    
+1 for Scala Johansson :) –  raychenon Jun 23 at 14:18
add comment

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.