Academic Integrity: tutoring, explanations, and feedback — we don’t complete graded work or submit on a student’s behalf.

I\'ve been promoting Scala at work as something we should try out for things lik

ID: 639535 • Letter: I

Question

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)

Explanation / Answer

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.

Hire Me For All Your Tutoring Needs
Integrity-first tutoring: clear explanations, guidance, and feedback.
Drop an Email at
drjack9650@gmail.com
Chat Now And Get Quote