Scala for Java Developers
Ramnivas Laddad
@ramnivas
@ramnivas
•  Author of books and articles
–  AspectJ in Action (1st and 2nd edition)
•  Spring framework, Cloud Foundry
•  Main interests
–  Cloud computing
–  Aspect-oriented programming
–  Scala and functional programming
•  Speaker at many professional conferences
–  JavaOne, JavaPolis, SpringOne, Software Development, No Fluff Just Stuff,
EclipseCon, O’Reilly OSCON etc.
•  Active involvement in AspectJ, Spring, and Cloud Foundry since
their early form
What is Scala
3
“a general purpose programming language designed to
express common programming patterns in a concise,
elegant, and type-safe way. It smoothly integrates features
of object-oriented and functional languages, enabling Java
and other programmers to be more productive.”
http://www.scala-lang.org
Object-oriented
•  Everything is an object
–  No “primitives”
•  Classes
–  Same as Java, but concise
•  Traits
–  Interfaces done right
•  Singletons
–  Language-level concept
4
Statically typed
•  Rich type system (by Java’s standard)
–  Higher-kinded types
–  Implicit conversions
–  Type evidence
•  Expressive type system
•  Inferred types
5
Functional Programming
•  Functions as values
–  May be
•  Saved
•  Passed to other functions (higher-order functions)
 No need to write ugly anonymous classes
–  Advanced pattern matching
–  Expressions return a value
•  if/else, try/catch, match, …
•  Promotes immutability
–  But doesn’t force it
6
Java Interoperability
•  Compiles to Java byte code
–  Jars, wars, …
–  No special operational change
•  Scala calling Java, Java calling Scala code is fine
•  Whole Java eco-system at your service
•  You can write apps using Scala and Spring, today
7
Hello World: Scripting Style
$ scala hello-script.scala	
Hello World
	
println("Hello World")	
No compilation
Hello World: Porting of Java Code
$ scalac hello-java.scala	
$ scala example.Main	
Hello World
// hello-java.scala	
package example	
	
object Main {	
def main(args: Array[String]) {	
	println("Hello World") 	
}	
}
‘static’
Inferred
semicolons
Hello World: Using the App trait
$ scalac hello-app.scala	
$ scala example.Main	
Hello World
// hello-app.scala	
package example	
	
object Main extends App {	
println("Hello World") 	
}
Simple Class
class Person	
val p = new Person	
Type
Inferred
Default
access: public
No curly
braces needed
(but allowed)
Simple Class
class Person	
val p: Person = new Person	
Explicit type
specification
Class with constructor
class Person(firstName: String, 	
lastName: String)	
val p = new Person("Ramnivas", "Laddad")	
println(p.firstName) // Error
Primary
constructor
Fields –
accessible in
class body
Class with “getters”
class Person(val firstName: String, 	
val lastName: String)	
val p = new Person("Ramnivas", "Laddad")	
println(p.firstName)
Value
(Java ‘final’)
Class with “getters” and “setters”
class Person(var firstName: String, 	
var lastName: String)	
val p = new Person("Ramnivas", "Laddad")	
println(p.firstName)	
p.firstName = "Ramnivas2”
Variable (Java
non-final)
Extending a class
class Student(firstName: String, 	
lastName: String, 	
val grade: Int)	
extends Person(firstName, lastName)	
val s = new Student("Ramnivas", "Laddad", 1)	
println(s.firstName)	
println(s.grade)
Defining methods
class Person(val firstName: String, 	
val lastName: String) {	
def name = firstName + " " + lastName	
	
override def toString = name 	
}	
val p = new Person("Ramnivas", "Laddad")	
println(p.name) // Ramnivas Laddad	
println(p) // Ramnivas Laddad
Not optional
Uniform access principle
class Person(val firstName: String, 	
val lastName: String) {	
val name = firstName + " " + lastName	
	
override def toString = name 	
}	
val p = new Person("Ramnivas", "Laddad")	
println(p.name) // Ramnivas Laddad	
println(p) // Ramnivas Laddad
Names in Scala
•  Class, method, field names can contain non alpha-
numeric characters
–  ::
–  :::
–  ~>
–  f@#:
•  Valuable if used judiciously
–  DSLs
19
More about methods and fields
•  Declaring abstract methods and fields
–  Just don’t provide definition
def learn(subject: String)	
val knowledge
•  Classes with abstract method must be declared abstract
–  Just as in Java
•  Methods can be defined inside methods
•  Methods may be marked @tailrec to check for tail-
recursiveness
20
Finer access control levels
•  Default access level: public
•  Protected: protected
–  Same as Java
•  Private:
–  private 	
–  private[this] Access only from this instance 	
–  private[package-name] Access from package and its
subpackages
	
21
Traits: Interfaces done right
22
trait PartyGoer {	
val age: Int	
val yearsUntilLegalDrinking = 	
if (age >= 21) 0 else 21-age	
}	
class Student(firstName: String, lastName: String, 	
val age: Int, val grade: Int) 	
extends Person(firstName, lastName) 	
with PartyGoer
val s = new Student("a", "b", 17, 12)	
s.yearsUntilLegalDrinking // 4
Collections
val people = List("John", "Jacob", 	
"Mike")	
val firstPerson = people(0)	
println(firstPerson) // John
Collections
val people = Array("John", "Jacob", 	
"Mike")	
val firstPerson = people(0)	
println(firstPerson) // John
Working with collections: for comprehension
25
for (person <- people) {	
println(person)	
}
Working with collections: for comprehension
26
for (person <- people if person startsWith "J") {	
println("""Lucky one to start name in "J" """ + person)	
}	
	
// You are lucky one to start name in "J" John	
// You are lucky one to start name in "J" Jacob
Working with collections: for comprehension
27
for (person <- people if person startsWith "J") {	
println(s"""Lucky one to start name in "J" $person""")	
}	
	
// You are lucky one to start name in "J" John	
// You are lucky one to start name in "J" Jacob
Working with collections: filter
val student1 = new Student("first1", "last1", 1)	
val student2 = new Student("first2", "last2", 1)	
val student3 = new Student("first3", "last3", 2)	
val student4 = new Student("first4", "last4", 6)	
val students = List(student1, student2, 	
student3, student4)	
val firstGraders = students.filter(	
s => s.grade == 1)	
println(firstGraders) 	
// List(first1 last1, first2 last2)
Working with collections: filter
val student1 = new Student("first1", "last1", 1)	
val student2 = new Student("first2", "last2", 1)	
val student3 = new Student("first3", "last3", 2)	
val student4 = new Student("first4", "last4", 6)	
val students = List(student1, student2, 	
student3, student4)	
val inFirstGrade: Student => Boolean 	
= s => s.grade == 1	
	
val firstGraders = students.filter(inFirstGrade)	
// List(first1 last1, first2 last2)
Working with collections: using _
val student1 = new Student("first1", "last1", 1)	
val student2 = new Student("first2", "last2", 1)	
val student3 = new Student("first3", "last3", 2)	
val student4 = new Student("first4", "last4", 6)	
val students = List(student1, student2, 	
student3, student4)	
val firstGraders 	
= students.filter(_.grade == 1)	
println(firstGraders) 	
// List(first1 last1, first2 last2)
Working with collections: passing method as function
val student1 = new Student("first1", "last1", 1)	
val student2 = new Student("first2", "last2", 1)	
val student3 = new Student("first3", "last3", 2)	
val student4 = new Student("first4", "last4", 6)	
val students = List(student1, student2, 	
student3, student4)	
def inFirstGrade(s: Student) : Boolean 	
= s.grade == 1 	
val firstGraders = students.filter(inFirstGrade)	
// List(first1 last1, first2 last2)
Working with collections: partition
val student1 = new Student("first1", "last1", 1)	
val student2 = new Student("first2", "last2", 1)	
val student3 = new Student("first3", "last3", 2)	
val student4 = new Student("first4", "last4", 6)	
val students = List(student1, student2, 	
student3, student4)	
val (elementarySchoolers, middleSchoolers) 	
= students.partition(_.grade < 6)	
println(elementarySchoolers)	
println(middleSchoolers)	
//List(first1 last1, first2 last2, first3 last3)	
//List(first4 last4)	
Tuple
Working with collections: transforming
val student1 = new Student("first1", "last1", 1)	
val student2 = new Student("first2", "last2", 1)	
val student3 = new Student("first3", "last3", 2)	
val student4 = new Student("first4", "last4", 6)	
val students = List(student1, student2, 	
student3, student4)	
val rollCall = students.map(_.firstName)	
println(rollCall)	
// List(first1, first2, first3, first4)
Map
// student1, student2, student3, student4	
val studentSchools = Map(student1 -> "Miller", 	
student2 -> "Lawson",	
student3 -> "Lawson", 	
student4 -> "Miller")	
println(studentSchools(student1)) // Miller
More collections
•  Set
•  IndexedSeq
•  Vector (good one!)
•  Range
–  1 to 100
–  1 until 100
–  2 until 100 by 2
•  …
•  Mutable versions
•  Parallel versions
35
Putting it together: Quicksort
def quicksort[T](input: Traversable[T])	
(ordering: Ordering[T]) : Traversable[T] = 	
if (input.isEmpty) {	
input	
} else {	
val (low, high) 	
= input.tail.partition(ordering.lt(_, input.head))	
quicksort(low)(ordering) ++ List(input.head) 	
++ quicksort(high)(ordering)	
}	
println(quicksort(List(1, 3, 4, 5, 1))(Ordering.Int))
Putting it together: Quicksort
def quicksort[T](input: Traversable[T])	
(implicit ordering: Ordering[T]) 	
: Traversable[T] =	
if (input.isEmpty) {	
input	
} else {	
val (low, high) 	
= input.tail.partition(ordering.lt(_, input.head))	
quicksort(low) ++ List(input.head) ++ quicksort(high)	
}	
println(quicksort(List(1, 3, 4, 5, 1)))
Pattern matching: Basics
val a:Any = "foo"	
	
a match {	
case str: String => println("A string: " + str)	
case i: Int => println("An int: " + i)	
case _ => println("Something else")	
}
Pattern matching: with collections
val l = List("a", "b", "c")	
	
l match {	
case Nil => println("Empty!")	
case head :: Nil => 	
println("Only one item " + head)	
case head :: tail => 	
println("Item " + head + 	
" followed by " + tail)	
}
Quicksort with pattern matching
def quicksort[T](input: Traversable[T])	
(implicit ordering: Ordering[T]) : Traversable[T] =
input match {	
case head :: tail => 	
val (low, high) = tail.partition(ordering.lt(_, head))	
quicksort(low) ++ List(head) ++ quicksort(high)	
case _ => input	
}	
println(quicksort(List(1, 3, 4, 5, 1)))
Destutter using Pattern matching
41
def destutter[A](lst: List[A]): List[A] = lst match {	
case h1 :: h2 :: tail if (h1 == h2) 	
=> destutter(h2 :: tail)	
case h1 :: h2 :: tail 	
=> h1 :: destutter(h2 :: tail)	
case _ 	
=> lst	
}	
// destutter(List(1,1,1,1,1,1)) => List(1)	
// destutter(List(1,1,4,3,3,2)) => List(1,4,3,2)	
// destutter(List())=> List()
Case classes
•  Useful in pattern matching
–  “case”
•  Offer many useful common methods
–  equals()
–  hashCode()
–  toString
–  copy()
42
Case classes
43
case class Human(name: String)	
case class SuperHero(name: String, power: String)	
val characters = List(Human("Programmer"), 	
SuperHero("Customer", "money"), 	
SuperHero("QA", "testing"))
Case classes and pattern matching
44
val actions = for (character <- characters) 	
yield character match {	
case Human(name) => 	
name + " needs to be saved"	
case SuperHero(name, power) => 	
name + " will save using " + power	
}	
	
actions.foreach(println)
Pattern matching and extracting just enough
45
val actions = for (character <- characters) 	
yield character match {	
case Human(name) => 	
name + " needs to be saved"	
case SuperHero(_, power) => 	
"Could be saved using " + power	
}	
	
actions.foreach(println)	
	
// Programmer needs to be saved	
// Could be saved using money	
// Could be saved using testing
Regular expressions
46
val text = "Ramnivas Laddad" 	
	
val Name = """(w+)s+(w+)""".r	
	
val person = text match {	
case Name(first, last) => 	
Some(new Person(first, last))	
case _ => 	
None	
}	
	
println(person) // Some(Ramnivas Laddad)
Options
47
val texts = 	
List("Ramnivas Laddad", "foo", "Martin Odersky")	
	
val peopleOptions = texts.map {	
_ match {	
case Name(first, last) => 	
Some(new Person(first, last))	
case _ => None	
}	
}	
	
println(peopleOptions)	
// List(Some(Ramnivas Laddad), 	
None, 	
Some(Martin Odersky))
Options: flattening
48
val texts = 	
List("Ramnivas Laddad", "foo", "Martin Odersky")	
	
val peopleOptions = texts.map {	
_ match {	
case Name(first, last) => 	
Some(new Person(first, last))	
case _ => None	
}	
}	
	
println(peopleOptions.flatten)	
// List(Ramnivas Laddad, Martin Odersky)
Options: flatMap
49
val texts = 	
List("Ramnivas Laddad", "foo", "Martin Odersky")	
	
val people = texts.flatMap {	
_ match {	
case Name(first, last) => 	
Some(new Person(first, last))	
case _ => None	
}	
}	
	
println(people)	
// List(Ramnivas Laddad, Martin Odersky)
Higher order functions
def process() : Unit = {	
retry(5) {	
...	
}	
}
def retry[T](maxRetry: Int)(thunk: => T) = {	
def loop(thunk: => T, attempt: Int): T = {	
try {	
thunk	
} catch {	
case ex if (attempt < maxRetry) =>	
loop(thunk, attempt + 1)	
}	
}	
loop(thunk, 0)	
}
Thunk
Caching using Scala
def getQuoteGraph(stock: Stock, 	
days: Int) : Array[Byte] = {	
cached("chart", stock.ticker + ":" + days) {	
!
... Expensive calculation !
!
}	
}
Caching higher-order function
abstract class Caching(val cacheManager: CacheManager) {	
def cached[T](region: String, key: Any)	
(thunk: => T): T = {	
val cache = ...	
	
if (cache.containsKey(key)) {	
cache.get(key).asInstanceOf[T]	
} else {	
val thunkVal: T = thunk	
cache.put(key, thunkVal)	
thunkVal	
}	
}	
}
Transaction management
def findOrder(orderId: Long) : Order = {	
transactional(readOnly=true) {	
//...	
}	
}	
	
def updateOrder(order: Order) {	
transactional() {	
//...	
}	
}
53
Transaction management function
def transactional[T](propgation: Propagation = Propagation.REQUIRED,	
isolation: Isolation = Isolation.DEFAULT,	
readOnly: Boolean = false,	
timeout: Int =TransactionDefinition.TIMEOUT_DEFAULT,	
rollbackFor: List[Throwable] = List(),	
noRollbackFor: List[Throwable] = List())	
(thunk: => T) : T
Transaction management implementation
abstract class TransactionManagement(val txManager: PlatformTransactionManager) {	
	
def transactional[T](...)(thunk: => T) : T = {	
val txAttribute = new TransactionAttributeWithRollbackRules(...)	
	
val status = txManager.getTransaction(txAttribute)	
	
try {	
val ret = thunk	
txManager.commit(status)	
ret	
} catch {	
case ex => {	
if (txAttribute.rollbackOn(ex)) {	
txManager.rollback(status)	
} else {	
txManager.commit(status)	
}	
throw ex	
}	
}	
}	
}
There is more… a lot more
•  Methods/functions
–  Default parameters
–  Named parameters
–  Curried parameters
–  Partial, partially-applied
functions
•  Type system
–  Higher-kinded types
–  Bounded types
–  Implicit type conversion
–  Type parameter
evidence
–  Type aliasing
•  Lazy values
•  Partial imports
•  Actors
•  Extractors
•  Scala ecosystem
•  Combinator/parser
•  Continuations
•  Compiler plugin
•  …
56
Learning Scala
•  Read a Scala book
–  Get the whole picture
•  May feel complex at first
–  Java-style Scala may serve best during initial exploration
–  Over time you will appreciate its simplicity
–  Will affect your non-Scala programming deeply
57
Be ready to be humbled
Be ready to have fun!
Scala for Java Developers
Ramnivas Laddad
@ramnivas

More Related Content

PDF
Functional Object-Oriented Imperative Scala / 関数型オブジェクト指向命令型 Scala by Sébasti...
PDF
Exploring type level programming in Scala
PDF
Be Smart, Constrain Your Types to Free Your Brain!
PDF
ZIO Prelude - ZIO World 2021
ODP
1.2 scala basics
PDF
Scala In The Wild
PDF
Scala - en bedre og mere effektiv Java?
PPTX
All about scala
Functional Object-Oriented Imperative Scala / 関数型オブジェクト指向命令型 Scala by Sébasti...
Exploring type level programming in Scala
Be Smart, Constrain Your Types to Free Your Brain!
ZIO Prelude - ZIO World 2021
1.2 scala basics
Scala In The Wild
Scala - en bedre og mere effektiv Java?
All about scala

What's hot (19)

PDF
Workshop Scala
PDF
scala
PDF
Starting with Scala : Frontier Developer's Meetup December 2010
PDF
Scala. Inception.
PPTX
Programming picaresque
PDF
PPTX
Scala on Android
PDF
Scala vs Java 8 in a Java 8 World
PDF
Stepping Up : A Brief Intro to Scala
PDF
From Java to Scala - advantages and possible risks
PPT
Scala uma poderosa linguagem para a jvm
PPT
Scala introduction
PPT
Scala - brief intro
PDF
An Introduction to Scala for Java Developers
PDF
Scaladroids: Developing Android Apps with Scala
PDF
Native XML processing in C++ (BoostCon'11)
PDF
Solid and Sustainable Development in Scala
PDF
Scala-对Java的修正和超越
PDF
Scala Quick Introduction
Workshop Scala
scala
Starting with Scala : Frontier Developer's Meetup December 2010
Scala. Inception.
Programming picaresque
Scala on Android
Scala vs Java 8 in a Java 8 World
Stepping Up : A Brief Intro to Scala
From Java to Scala - advantages and possible risks
Scala uma poderosa linguagem para a jvm
Scala introduction
Scala - brief intro
An Introduction to Scala for Java Developers
Scaladroids: Developing Android Apps with Scala
Native XML processing in C++ (BoostCon'11)
Solid and Sustainable Development in Scala
Scala-对Java的修正和超越
Scala Quick Introduction
Ad

Viewers also liked (18)

PDF
Functional Scala II (in practice)
PDF
Functional Scala I
PPTX
Scala 2.10.0 (english version)
PDF
Scala Workshop
KEY
Scala For Java Programmers
PDF
Sqoop on Spark for Data Ingestion-(Veena Basavaraj and Vinoth Chandar, Uber)
PDF
Scala dreaded underscore
PPT
Scala Talk at FOSDEM 2009
PPTX
The Evolution of Scala
PPT
Scala Days San Francisco
PPTX
A Brief Intro to Scala
PDF
Scala Days NYC 2016
PDF
Introduction to Scala for Java Developers
PDF
Lambda Architecture with Spark, Spark Streaming, Kafka, Cassandra, Akka and S...
PDF
Lambda Architecture with Spark Streaming, Kafka, Cassandra, Akka, Scala
PDF
Scala, Akka, and Play: An Introduction on Heroku
PDF
Introduction to Functional Programming with Scala
Functional Scala II (in practice)
Functional Scala I
Scala 2.10.0 (english version)
Scala Workshop
Scala For Java Programmers
Sqoop on Spark for Data Ingestion-(Veena Basavaraj and Vinoth Chandar, Uber)
Scala dreaded underscore
Scala Talk at FOSDEM 2009
The Evolution of Scala
Scala Days San Francisco
A Brief Intro to Scala
Scala Days NYC 2016
Introduction to Scala for Java Developers
Lambda Architecture with Spark, Spark Streaming, Kafka, Cassandra, Akka and S...
Lambda Architecture with Spark Streaming, Kafka, Cassandra, Akka, Scala
Scala, Akka, and Play: An Introduction on Heroku
Introduction to Functional Programming with Scala
Ad

Similar to Scala for Java Developers (Silicon Valley Code Camp 13) (20)

PPT
Scala for Java Developers
ODP
1.1 motivation
PDF
Scala - en bedre Java?
PDF
Introduction to Scala
PPTX
Softshake 2013: 10 reasons why java developers are jealous of Scala developers
ODP
Introduction to Scala
PDF
A bit about Scala
PPTX
Intro to scala
ODP
1.2 scala basics
PDF
CGIS_IP_T6_AccessCtrl_ClassScope_Packages_API.pdf
PDF
BCS SPA 2010 - An Introduction to Scala for Java Developers
ODP
PPTX
Taxonomy of Scala
ODP
2.1 recap from-day_one
PDF
Introduction to Scala
ODP
1.1 motivation
ODP
1.1 motivation
PDF
Scala for Java Programmers
PPTX
FFW Gabrovo PMG - PHP OOP Part 3
PPTX
Scala: Devnology - Learn A Language Scala
Scala for Java Developers
1.1 motivation
Scala - en bedre Java?
Introduction to Scala
Softshake 2013: 10 reasons why java developers are jealous of Scala developers
Introduction to Scala
A bit about Scala
Intro to scala
1.2 scala basics
CGIS_IP_T6_AccessCtrl_ClassScope_Packages_API.pdf
BCS SPA 2010 - An Introduction to Scala for Java Developers
Taxonomy of Scala
2.1 recap from-day_one
Introduction to Scala
1.1 motivation
1.1 motivation
Scala for Java Programmers
FFW Gabrovo PMG - PHP OOP Part 3
Scala: Devnology - Learn A Language Scala

Recently uploaded (20)

PDF
Improvisation in detection of pomegranate leaf disease using transfer learni...
PDF
MENA-ECEONOMIC-CONTEXT-VC MENA-ECEONOMIC
PPT
Galois Field Theory of Risk: A Perspective, Protocol, and Mathematical Backgr...
PDF
Comparative analysis of machine learning models for fake news detection in so...
PDF
IT-ITes Industry bjjbnkmkhkhknbmhkhmjhjkhj
PDF
Rapid Prototyping: A lecture on prototyping techniques for interface design
PDF
Dell Pro Micro: Speed customer interactions, patient processing, and learning...
PDF
Produktkatalog für HOBO Datenlogger, Wetterstationen, Sensoren, Software und ...
PDF
Transform-Quality-Engineering-with-AI-A-60-Day-Blueprint-for-Digital-Success.pdf
PDF
Planning-an-Audit-A-How-To-Guide-Checklist-WP.pdf
PDF
Statistics on Ai - sourced from AIPRM.pdf
PPTX
Module 1 Introduction to Web Programming .pptx
PPTX
SGT Report The Beast Plan and Cyberphysical Systems of Control
PDF
The-2025-Engineering-Revolution-AI-Quality-and-DevOps-Convergence.pdf
DOCX
Basics of Cloud Computing - Cloud Ecosystem
PDF
Transform-Your-Streaming-Platform-with-AI-Driven-Quality-Engineering.pdf
PDF
LMS bot: enhanced learning management systems for improved student learning e...
PDF
Convolutional neural network based encoder-decoder for efficient real-time ob...
PPTX
Custom Battery Pack Design Considerations for Performance and Safety
PDF
Auditboard EB SOX Playbook 2023 edition.
Improvisation in detection of pomegranate leaf disease using transfer learni...
MENA-ECEONOMIC-CONTEXT-VC MENA-ECEONOMIC
Galois Field Theory of Risk: A Perspective, Protocol, and Mathematical Backgr...
Comparative analysis of machine learning models for fake news detection in so...
IT-ITes Industry bjjbnkmkhkhknbmhkhmjhjkhj
Rapid Prototyping: A lecture on prototyping techniques for interface design
Dell Pro Micro: Speed customer interactions, patient processing, and learning...
Produktkatalog für HOBO Datenlogger, Wetterstationen, Sensoren, Software und ...
Transform-Quality-Engineering-with-AI-A-60-Day-Blueprint-for-Digital-Success.pdf
Planning-an-Audit-A-How-To-Guide-Checklist-WP.pdf
Statistics on Ai - sourced from AIPRM.pdf
Module 1 Introduction to Web Programming .pptx
SGT Report The Beast Plan and Cyberphysical Systems of Control
The-2025-Engineering-Revolution-AI-Quality-and-DevOps-Convergence.pdf
Basics of Cloud Computing - Cloud Ecosystem
Transform-Your-Streaming-Platform-with-AI-Driven-Quality-Engineering.pdf
LMS bot: enhanced learning management systems for improved student learning e...
Convolutional neural network based encoder-decoder for efficient real-time ob...
Custom Battery Pack Design Considerations for Performance and Safety
Auditboard EB SOX Playbook 2023 edition.

Scala for Java Developers (Silicon Valley Code Camp 13)

  • 1. Scala for Java Developers Ramnivas Laddad @ramnivas
  • 2. @ramnivas •  Author of books and articles –  AspectJ in Action (1st and 2nd edition) •  Spring framework, Cloud Foundry •  Main interests –  Cloud computing –  Aspect-oriented programming –  Scala and functional programming •  Speaker at many professional conferences –  JavaOne, JavaPolis, SpringOne, Software Development, No Fluff Just Stuff, EclipseCon, O’Reilly OSCON etc. •  Active involvement in AspectJ, Spring, and Cloud Foundry since their early form
  • 3. What is Scala 3 “a general purpose programming language designed to express common programming patterns in a concise, elegant, and type-safe way. It smoothly integrates features of object-oriented and functional languages, enabling Java and other programmers to be more productive.” http://www.scala-lang.org
  • 4. Object-oriented •  Everything is an object –  No “primitives” •  Classes –  Same as Java, but concise •  Traits –  Interfaces done right •  Singletons –  Language-level concept 4
  • 5. Statically typed •  Rich type system (by Java’s standard) –  Higher-kinded types –  Implicit conversions –  Type evidence •  Expressive type system •  Inferred types 5
  • 6. Functional Programming •  Functions as values –  May be •  Saved •  Passed to other functions (higher-order functions)  No need to write ugly anonymous classes –  Advanced pattern matching –  Expressions return a value •  if/else, try/catch, match, … •  Promotes immutability –  But doesn’t force it 6
  • 7. Java Interoperability •  Compiles to Java byte code –  Jars, wars, … –  No special operational change •  Scala calling Java, Java calling Scala code is fine •  Whole Java eco-system at your service •  You can write apps using Scala and Spring, today 7
  • 8. Hello World: Scripting Style $ scala hello-script.scala Hello World println("Hello World") No compilation
  • 9. Hello World: Porting of Java Code $ scalac hello-java.scala $ scala example.Main Hello World // hello-java.scala package example object Main { def main(args: Array[String]) { println("Hello World") } } ‘static’ Inferred semicolons
  • 10. Hello World: Using the App trait $ scalac hello-app.scala $ scala example.Main Hello World // hello-app.scala package example object Main extends App { println("Hello World") }
  • 11. Simple Class class Person val p = new Person Type Inferred Default access: public No curly braces needed (but allowed)
  • 12. Simple Class class Person val p: Person = new Person Explicit type specification
  • 13. Class with constructor class Person(firstName: String, lastName: String) val p = new Person("Ramnivas", "Laddad") println(p.firstName) // Error Primary constructor Fields – accessible in class body
  • 14. Class with “getters” class Person(val firstName: String, val lastName: String) val p = new Person("Ramnivas", "Laddad") println(p.firstName) Value (Java ‘final’)
  • 15. Class with “getters” and “setters” class Person(var firstName: String, var lastName: String) val p = new Person("Ramnivas", "Laddad") println(p.firstName) p.firstName = "Ramnivas2” Variable (Java non-final)
  • 16. Extending a class class Student(firstName: String, lastName: String, val grade: Int) extends Person(firstName, lastName) val s = new Student("Ramnivas", "Laddad", 1) println(s.firstName) println(s.grade)
  • 17. Defining methods class Person(val firstName: String, val lastName: String) { def name = firstName + " " + lastName override def toString = name } val p = new Person("Ramnivas", "Laddad") println(p.name) // Ramnivas Laddad println(p) // Ramnivas Laddad Not optional
  • 18. Uniform access principle class Person(val firstName: String, val lastName: String) { val name = firstName + " " + lastName override def toString = name } val p = new Person("Ramnivas", "Laddad") println(p.name) // Ramnivas Laddad println(p) // Ramnivas Laddad
  • 19. Names in Scala •  Class, method, field names can contain non alpha- numeric characters –  :: –  ::: –  ~> –  f@#: •  Valuable if used judiciously –  DSLs 19
  • 20. More about methods and fields •  Declaring abstract methods and fields –  Just don’t provide definition def learn(subject: String) val knowledge •  Classes with abstract method must be declared abstract –  Just as in Java •  Methods can be defined inside methods •  Methods may be marked @tailrec to check for tail- recursiveness 20
  • 21. Finer access control levels •  Default access level: public •  Protected: protected –  Same as Java •  Private: –  private –  private[this] Access only from this instance –  private[package-name] Access from package and its subpackages 21
  • 22. Traits: Interfaces done right 22 trait PartyGoer { val age: Int val yearsUntilLegalDrinking = if (age >= 21) 0 else 21-age } class Student(firstName: String, lastName: String, val age: Int, val grade: Int) extends Person(firstName, lastName) with PartyGoer val s = new Student("a", "b", 17, 12) s.yearsUntilLegalDrinking // 4
  • 23. Collections val people = List("John", "Jacob", "Mike") val firstPerson = people(0) println(firstPerson) // John
  • 24. Collections val people = Array("John", "Jacob", "Mike") val firstPerson = people(0) println(firstPerson) // John
  • 25. Working with collections: for comprehension 25 for (person <- people) { println(person) }
  • 26. Working with collections: for comprehension 26 for (person <- people if person startsWith "J") { println("""Lucky one to start name in "J" """ + person) } // You are lucky one to start name in "J" John // You are lucky one to start name in "J" Jacob
  • 27. Working with collections: for comprehension 27 for (person <- people if person startsWith "J") { println(s"""Lucky one to start name in "J" $person""") } // You are lucky one to start name in "J" John // You are lucky one to start name in "J" Jacob
  • 28. Working with collections: filter val student1 = new Student("first1", "last1", 1) val student2 = new Student("first2", "last2", 1) val student3 = new Student("first3", "last3", 2) val student4 = new Student("first4", "last4", 6) val students = List(student1, student2, student3, student4) val firstGraders = students.filter( s => s.grade == 1) println(firstGraders) // List(first1 last1, first2 last2)
  • 29. Working with collections: filter val student1 = new Student("first1", "last1", 1) val student2 = new Student("first2", "last2", 1) val student3 = new Student("first3", "last3", 2) val student4 = new Student("first4", "last4", 6) val students = List(student1, student2, student3, student4) val inFirstGrade: Student => Boolean = s => s.grade == 1 val firstGraders = students.filter(inFirstGrade) // List(first1 last1, first2 last2)
  • 30. Working with collections: using _ val student1 = new Student("first1", "last1", 1) val student2 = new Student("first2", "last2", 1) val student3 = new Student("first3", "last3", 2) val student4 = new Student("first4", "last4", 6) val students = List(student1, student2, student3, student4) val firstGraders = students.filter(_.grade == 1) println(firstGraders) // List(first1 last1, first2 last2)
  • 31. Working with collections: passing method as function val student1 = new Student("first1", "last1", 1) val student2 = new Student("first2", "last2", 1) val student3 = new Student("first3", "last3", 2) val student4 = new Student("first4", "last4", 6) val students = List(student1, student2, student3, student4) def inFirstGrade(s: Student) : Boolean = s.grade == 1 val firstGraders = students.filter(inFirstGrade) // List(first1 last1, first2 last2)
  • 32. Working with collections: partition val student1 = new Student("first1", "last1", 1) val student2 = new Student("first2", "last2", 1) val student3 = new Student("first3", "last3", 2) val student4 = new Student("first4", "last4", 6) val students = List(student1, student2, student3, student4) val (elementarySchoolers, middleSchoolers) = students.partition(_.grade < 6) println(elementarySchoolers) println(middleSchoolers) //List(first1 last1, first2 last2, first3 last3) //List(first4 last4) Tuple
  • 33. Working with collections: transforming val student1 = new Student("first1", "last1", 1) val student2 = new Student("first2", "last2", 1) val student3 = new Student("first3", "last3", 2) val student4 = new Student("first4", "last4", 6) val students = List(student1, student2, student3, student4) val rollCall = students.map(_.firstName) println(rollCall) // List(first1, first2, first3, first4)
  • 34. Map // student1, student2, student3, student4 val studentSchools = Map(student1 -> "Miller", student2 -> "Lawson", student3 -> "Lawson", student4 -> "Miller") println(studentSchools(student1)) // Miller
  • 35. More collections •  Set •  IndexedSeq •  Vector (good one!) •  Range –  1 to 100 –  1 until 100 –  2 until 100 by 2 •  … •  Mutable versions •  Parallel versions 35
  • 36. Putting it together: Quicksort def quicksort[T](input: Traversable[T]) (ordering: Ordering[T]) : Traversable[T] = if (input.isEmpty) { input } else { val (low, high) = input.tail.partition(ordering.lt(_, input.head)) quicksort(low)(ordering) ++ List(input.head) ++ quicksort(high)(ordering) } println(quicksort(List(1, 3, 4, 5, 1))(Ordering.Int))
  • 37. Putting it together: Quicksort def quicksort[T](input: Traversable[T]) (implicit ordering: Ordering[T]) : Traversable[T] = if (input.isEmpty) { input } else { val (low, high) = input.tail.partition(ordering.lt(_, input.head)) quicksort(low) ++ List(input.head) ++ quicksort(high) } println(quicksort(List(1, 3, 4, 5, 1)))
  • 38. Pattern matching: Basics val a:Any = "foo" a match { case str: String => println("A string: " + str) case i: Int => println("An int: " + i) case _ => println("Something else") }
  • 39. Pattern matching: with collections val l = List("a", "b", "c") l match { case Nil => println("Empty!") case head :: Nil => println("Only one item " + head) case head :: tail => println("Item " + head + " followed by " + tail) }
  • 40. Quicksort with pattern matching def quicksort[T](input: Traversable[T]) (implicit ordering: Ordering[T]) : Traversable[T] = input match { case head :: tail => val (low, high) = tail.partition(ordering.lt(_, head)) quicksort(low) ++ List(head) ++ quicksort(high) case _ => input } println(quicksort(List(1, 3, 4, 5, 1)))
  • 41. Destutter using Pattern matching 41 def destutter[A](lst: List[A]): List[A] = lst match { case h1 :: h2 :: tail if (h1 == h2) => destutter(h2 :: tail) case h1 :: h2 :: tail => h1 :: destutter(h2 :: tail) case _ => lst } // destutter(List(1,1,1,1,1,1)) => List(1) // destutter(List(1,1,4,3,3,2)) => List(1,4,3,2) // destutter(List())=> List()
  • 42. Case classes •  Useful in pattern matching –  “case” •  Offer many useful common methods –  equals() –  hashCode() –  toString –  copy() 42
  • 43. Case classes 43 case class Human(name: String) case class SuperHero(name: String, power: String) val characters = List(Human("Programmer"), SuperHero("Customer", "money"), SuperHero("QA", "testing"))
  • 44. Case classes and pattern matching 44 val actions = for (character <- characters) yield character match { case Human(name) => name + " needs to be saved" case SuperHero(name, power) => name + " will save using " + power } actions.foreach(println)
  • 45. Pattern matching and extracting just enough 45 val actions = for (character <- characters) yield character match { case Human(name) => name + " needs to be saved" case SuperHero(_, power) => "Could be saved using " + power } actions.foreach(println) // Programmer needs to be saved // Could be saved using money // Could be saved using testing
  • 46. Regular expressions 46 val text = "Ramnivas Laddad" val Name = """(w+)s+(w+)""".r val person = text match { case Name(first, last) => Some(new Person(first, last)) case _ => None } println(person) // Some(Ramnivas Laddad)
  • 47. Options 47 val texts = List("Ramnivas Laddad", "foo", "Martin Odersky") val peopleOptions = texts.map { _ match { case Name(first, last) => Some(new Person(first, last)) case _ => None } } println(peopleOptions) // List(Some(Ramnivas Laddad), None, Some(Martin Odersky))
  • 48. Options: flattening 48 val texts = List("Ramnivas Laddad", "foo", "Martin Odersky") val peopleOptions = texts.map { _ match { case Name(first, last) => Some(new Person(first, last)) case _ => None } } println(peopleOptions.flatten) // List(Ramnivas Laddad, Martin Odersky)
  • 49. Options: flatMap 49 val texts = List("Ramnivas Laddad", "foo", "Martin Odersky") val people = texts.flatMap { _ match { case Name(first, last) => Some(new Person(first, last)) case _ => None } } println(people) // List(Ramnivas Laddad, Martin Odersky)
  • 50. Higher order functions def process() : Unit = { retry(5) { ... } } def retry[T](maxRetry: Int)(thunk: => T) = { def loop(thunk: => T, attempt: Int): T = { try { thunk } catch { case ex if (attempt < maxRetry) => loop(thunk, attempt + 1) } } loop(thunk, 0) } Thunk
  • 51. Caching using Scala def getQuoteGraph(stock: Stock, days: Int) : Array[Byte] = { cached("chart", stock.ticker + ":" + days) { ! ... Expensive calculation ! ! } }
  • 52. Caching higher-order function abstract class Caching(val cacheManager: CacheManager) { def cached[T](region: String, key: Any) (thunk: => T): T = { val cache = ... if (cache.containsKey(key)) { cache.get(key).asInstanceOf[T] } else { val thunkVal: T = thunk cache.put(key, thunkVal) thunkVal } } }
  • 53. Transaction management def findOrder(orderId: Long) : Order = { transactional(readOnly=true) { //... } } def updateOrder(order: Order) { transactional() { //... } } 53
  • 54. Transaction management function def transactional[T](propgation: Propagation = Propagation.REQUIRED, isolation: Isolation = Isolation.DEFAULT, readOnly: Boolean = false, timeout: Int =TransactionDefinition.TIMEOUT_DEFAULT, rollbackFor: List[Throwable] = List(), noRollbackFor: List[Throwable] = List()) (thunk: => T) : T
  • 55. Transaction management implementation abstract class TransactionManagement(val txManager: PlatformTransactionManager) { def transactional[T](...)(thunk: => T) : T = { val txAttribute = new TransactionAttributeWithRollbackRules(...) val status = txManager.getTransaction(txAttribute) try { val ret = thunk txManager.commit(status) ret } catch { case ex => { if (txAttribute.rollbackOn(ex)) { txManager.rollback(status) } else { txManager.commit(status) } throw ex } } } }
  • 56. There is more… a lot more •  Methods/functions –  Default parameters –  Named parameters –  Curried parameters –  Partial, partially-applied functions •  Type system –  Higher-kinded types –  Bounded types –  Implicit type conversion –  Type parameter evidence –  Type aliasing •  Lazy values •  Partial imports •  Actors •  Extractors •  Scala ecosystem •  Combinator/parser •  Continuations •  Compiler plugin •  … 56
  • 57. Learning Scala •  Read a Scala book –  Get the whole picture •  May feel complex at first –  Java-style Scala may serve best during initial exploration –  Over time you will appreciate its simplicity –  Will affect your non-Scala programming deeply 57 Be ready to be humbled Be ready to have fun!
  • 58. Scala for Java Developers Ramnivas Laddad @ramnivas