1. Scala, Akka, and Play: an Introduction
on Heroku
Havoc Pennington
Typesafe
2. Overview
Modernizing development on the Java Virtual Machine
– Scala: practical, superior alternative to Java with incremental
migration path
– Akka: proven Actor model gives horizontal scale for both Java and
Scala, without the pain points of explicit threads
– Play: popular Rails-style convention-over-configuration lightweight
web framework for both Java and Scala
– All supported on Heroku, a cloud platform with the same developer-
friendly point of view
Developer-friendly, horizontally scalable,
with a pragmatic path to adoption
2
4. Where it comes from
Scala has established itself as one of the main alternative
languages on the JVM.
Created by Martin Odersky, who also designed generics in Java 5
and implemented the javac compiler. He works with a team at
EPFL (École polytechnique fédérale de Lausanne) in addition to
the team at Typesafe.
Prehistory:
1996 – 1997: Pizza
1998 – 2000: GJ, Java generics, javac
( “make Java better” )
Timeline:
2003 – 2006: The Scala “Experiment”
4
2006 – 2009: An industrial strength programming language
5. Quick Scala Facts
• Vibrant open source community
• Wide commercial adoption
• Catching fire last couple years, but has been maturing many years
• Supports both object-oriented and functional styles
• Great interoperability with Java
• Static type safety
• Type inference makes it concise like a dynamic language
• “Scala” implies a “scalable language”
– Horizontal scale across cores
– Developer scale: manage complex projects
7. Select Commercial Users
Migrated core messaging Scala drives its social graph
service from Ruby to sustain service: 380-400 M
3 orders of magnitude growth transactions/day
EU’s largest energy firm
Entire web site and all
migrated a 300K lines contract
services written in Scala
modeling platform from Java to
Scala
Approved for general
production use
7
8. Community Traction
Open source ecosystem with
• Tens of thousands of downloads, scala-
lang.org visitors
• 20 books
• 40+ active user groups
8
9. GitHub and StackOverflow
9
From http://www.dataists.com/2010/12/ranking-the-popularity-of-programming-langauges/
10. Practical Migration and Interoperability
import java.net.URL;
Java: Import java.io.InputStream;
• Scala differs from Java only on
the source code level URL u = new URL(“http://foo.com”);
InputStream s = u.openStream();
• Once you have a .jar or .war, it
s.close();
just looks like Java
• Scala code can seamlessly
import and use any Java class
• Projects can have a mix of
Java and Scala files Scala: import java.net.URL
• Deploy Scala to any cloud or val u = new URL(“http://foo.com”)
val s = u.openStream()
container that supports Java s.close()
10
11. Less Code
When going from Java to Scala, expect at least a factor of 2
reduction in LOC.
Guy Steele: “Switching from Java to Scala reduced
size of Fortress typechecker by a factor of 4”.
But does it matter?
Doesn’t Eclipse write these extra lines for me?
This does matter. Eye-tracking experiments* show that for program
comprehension, average time spent per word of source code is
constant.
So, roughly, half the code means half the time necessary to
understand it.
*G. Dubochet. Computer Code as a Medium for Human Communication: Are Programming Languages Improving?
In 21st Annual Psychology of Programming Interest Group Conference, pages 174-187, Limerick, Ireland, 2009.
11
12. A class ...
public class Person {
public final String name;
public final int age;
Person(String name, int age) {
... in Java: this.name = name;
this.age = age;
}
}
class Person(val name: String,
... in Scala: val age: Int)
12
13. ... and its usage
import java.util.ArrayList;
...
Person[] people;
Person[] minors;
Person[] adults;
{ ArrayList<Person> minorsList = new ArrayList<Person>();
ArrayList<Person> adultsList = new ArrayList<Person>();
... in Java: for (int i = 0; i < people.length; i++)
(people[i].age < 18 ? minorsList : adultsList)
.add(people[i]);
minors = minorsList.toArray(people);
adults = adultsList.toArray(people);
}
... in Scala: val people: Array[Person]
val (minors, adults) = people partition (_.age < 18)
13
14. Both Object-Oriented and Functional
• Scala is not “religious” on programming paradigm: it tries to let you
do what's practical for the situation
• In some cases, Scala is “more object oriented” than Java; for
example
– primitive types are full-fledged objects
– static methods are replaced by methods on singleton objects
14
15. Detour: What is Functional
Programming?
• Emphasizes transformation (take a value, return a new value) over
mutable state (take a value, change the value in-place)
• Think ƒ(x)
• Also includes some cultural traditions, such as transforming lists
with map and reduce
• Advantages include:
– Inherently parallelizable and thread-safe
– Enables many optimizations, such as lazy evaluation
– Can make code more flexible and generic, for example by supporting
composition
15
16. Imperative Style (Java)
public static void addOneToAll(ArrayList<Integer> items) {
for (int i = 0; i < items.size(); ++i) {
items.set(i, items.get(i) + 1);
}
}
Mutates (modifies) the list in-place
16
17. Functional Style (Java)
public static List<Integer> addOneToAll(List<Integer> items) {
ArrayList<Integer> result = new ArrayList<Integer>();
for (int i : items) {
result.add(i + 1);
}
return result;
}
Returns a new list, leaving original untouched
17
18. Functional Enables Composition
public static List<Integer> addTwoToAll(List<Integer> items) {
return addOneToAll(addOneToAll(items));
}
(Composition is great for HTTP request handlers, by the way.)
18
19. Imperative Style (Scala)
def addOneToAll(items : mutable.IndexedSeq[Int]) = {
var i = 0
while (i < items.length) {
items.update(i, items(i) + 1)
i += 1
}
}
Mutates (modifies) the list in-place
19
20. Functional Style (Scala)
def addOneToAll(items : Seq[Int]) = items map { _ + 1 }
Anonymous function applied to
each item in the list
Returns a new list, leaving original untouched
20
21. Functional is not...
• A syntax. You can use functional style in both Java and Scala.
• A bunch of jargon (Monads, Functors, etc.); the Scala standard
library and the Programming in Scala book for example take care to
avoid this sort of academic language.
• A silver bullet.
21
22. Best fit for the problem domain
• Something like a simulation or a UI toolkit might map most naturally
to object-oriented style
• Something like a file format transformation or HTTP request might
map most naturally to functional style
• There is no need to be religious
• You can also use Scala as “Java with fewer characters to type,” and
ignore the functional style
22
23. End of detour
Next: how Scala uses functional style to support horizontal scale...
23
24. Horizontal Scale
The world of mainstream software is changing:
– Moore’s law now achieved
by increasing # of cores
not clock cycles
– Huge volume workloads
that require horizontal
scaling
Data from Kunle Olukotun, Lance Hammond, Herb
Sutter, Burton Smith, Chris Batten, and Krste
Asanovic 24
25. Concurrency is too hard
Almost every program that uses
threads is full of bugs.
25
26. The Root of The Problem
• Non-determinism caused by var x = 0
concurrent threads accessing async { x = x + 1 }
shared mutable state. async { x = x * 2 }
• It helps to encapsulate state in actors
or transactions, but the fundamental // can give 0, 1, 2
problem stays the same.
• So,
non-determinism = parallel processing + mutable state
• To get deterministic processing, avoid the mutable state!
• Avoiding mutable state means programming functionally.
26
27. Remember this code from before...
import java.util.ArrayList;
...
Person[] people;
Person[] minors;
Person[] adults;
{ ArrayList<Person> minorsList = new ArrayList<Person>();
ArrayList<Person> adultsList = new ArrayList<Person>();
... in Java: for (int i = 0; i < people.length; i++)
(people[i].age < 18 ? minorsList : adultsList)
.add(people[i]);
minors = minorsList.toArray(people);
adults = adultsList.toArray(people);
}
... in Scala: val people: Array[Person]
val (minors, adults) = people partition (_.age < 18)
27
28. Let's make it parallel...
... in Java:
?
... in Scala: val people: Array[Person]
val (minors, adults) = people.par partition (_.age < 18)
28
29. Recommended: Read the Book
• Very clearly-written, by Scala's
creator and designer
• Highly recommended to start
here
30. Scala in Summary
• Beautiful interoperability with Java: mix Scala and Java as desired,
no huge rewrites
• Conciseness means dramatic improvement in maintainability and
productivity
• Functional style seamlessly supports parallel computation, for
example parallel collections have exactly the same API as serial
• Vibrant community, hockey-stick growth curve, and available
commercial support
32. What is Akka?
• An implementation of the “Actor model”
– The actor model is an alternative to explicit threads, originally used in
the highly reliable Erlang environment
• An API for both Java and Scala
– Many people use Akka but not Scala, even though Akka is written in
Scala.
33. What else is Akka?
“Akka is the platform for next generation
event-driven, scalable, and fault-tolerant
architectures on the JVM”
A toolkit with many tools, but let's focus on Actors...
34. An Actor
... in Java:
public class HelloWorldActor extends UntypedActor {
public void onReceive(Object msg) {
getContext().replySafe(((String) msg) + “ World”);
}
}
... in Scala:
class HelloWorldActor extends Actor {
def receive = {
case msg : String => self reply (msg + “ World”)
}
}
34
35. Actors for Concurrent Programming
• Developer writes an object, called an Actor, which handles
messages.
• Each actor instance runs in only one thread at a time, so no
synchronization is required for actor state.
• Akka dispatcher schedules actors on threads – or even on multiple
machines – as needed. Can have millions of actors, an actor does
not “use up” a thread.
• Mutable state is safely single-threaded.
• Easier for programmers to create reliable concurrent processing.
• Many sources of contention, races, locking and dead-locks are
removed.
• No need to use locks or java.util.concurrent – at all. Even though
you're using mutable state, it's encapsulated in actors.
35
36. Separation of Concerns
• “Business logic” does not concern itself with the concurrency
mechanism or scheduling. Just implement what you'd like to happen
in response to each message.
• Note the similarity to Scala collections
– In “items foreach { _ + 1 }” rather than a while loop, the Scala
library “drives” the application of “{ _ + 1 }” to “items” and can make
that transparently parallel
– In the same way, Akka “drives” the dispatch of messages to actors,
allowing it to Do The Right Thing
– Developer says “what” but avoids hardcoding “how”
36
37. Other Goodies
• Actor model
• Event-driven dispatcher can run millions of actors
• Remoting
• Supervisors (fault-tolerance)
• Software Transactional Memory (STM)
• Futures, Pools, and other handy utilities
Akka offers a comprehensive toolkit for clustering, concurrency, and
fault-tolerance.
40. Akka in Summary
• Akka is an implementation of the Actor model for both Java and
Scala.
• Actors encapsulate mutable state with the guarantee of one
message at a time.
• Actor instances don't need to do any locking or think about threads,
eliminating a whole class of bugs and mental overhead.
• The magic comes from the dispatcher, which (by default) combines
an event-driven loop with a thread pool for scalability.
• A single JVM can host millions of actors – far more actors than
threads.
• Akka comes with a complete toolkit for distributed, fault-tolerant
computing, built on actors as a base.
• Highly modular: the core actor jar has ZERO dependencies.
40
42. Both Scala and Java
• Like Akka, Play has both Java and Scala APIs
• Originally a Java framework, but increasing emphasis on Scala
• You could use the Java version of Play and just happen to write
some files in Scala, but there are also dedicated Scala-tuned APIs
in Play's Scala module
43. It's a Framework
• Framework, not a library; many decisions are made in advance, you
can often change them but there are defaults
• For example:
– Model-View-Controller approach
– Selenium is set up for testing
– There's a database API built-in with good default mappings to REST
– memcached support built-in
– Predefined “prod” and “dev” modes
– default template system
• Lets you get started quickly, instead of having to make a dozen
decisions first. Can change decisions “as needed.”
• Always start with a complete “hello world” project, and iterate it from
there.
44. Scripting-style Web Development
• The Play Framework feels like a Python or Ruby framework, rather
than a traditional Java framework
• No compile and restart; server compiles and recompiles on the fly,
so just edit, reload, edit, reload. Compilation and other errors appear
right in the browser.
• Like developing with a “scripting language” … but you have static
type safety!
• With Scala, your code can be as concise as it would be in a
“scripting language”
45. Stateless
• Play is “share-nothing” so no need for communication between
nodes
• State can be kept in your SQL or NoSQL store, in memcached, or
browser cookies
47. Play in Summary
• Both Scala and Java friendly
• Emphasis on rapid development and good defaults, rather than
absolute flexibility
• Similar in feel to Python and Ruby frameworks, for example shares
the MVC model
• Try out the Java or Scala tutorials on the Play website
49. Heroku Supports Scala and Play
• With Heroku, the unit of deployment is a git repository: that is, you
deploy the source code, not a .war file or similar
• This means Heroku must know how to build from source
• With Heroku's “Java support” you could already deploy a Scala
application using Maven
• Most Scala developers use Simple Build Tool, however
• Play Framework has built-in build facilities so it can build on browser
reload
Heroku now supports Play Framework applications,
plus (experimentally) SBT apps might work...
51. Takeaways
These technologies offer a genuine opportunity for huge
productivity gains over traditional Java.
They are practical to adopt incrementally without huge
rewrites.
Typesafe offers commercial support and training for Scala
and Akka.
On Twitter: @Typesafe
51
Learn more at typesafe.com