Upload
kalanidhi
View
220
Download
0
Embed Size (px)
Citation preview
8/13/2019 Scala Springone 111031111747 Phpapp01
1/56
Scala for Java Developers
Ramnivas Laddad
@ramnivas
2011 SpringOne 2GX. All rights reserved. Do not distribute without permission.
http://localhost/var/www/apps/conversion/tmp/scratch_5/twitter.comhttp://localhost/var/www/apps/conversion/tmp/scratch_5/twitter.com8/13/2019 Scala Springone 111031111747 Phpapp01
2/56
What is Scala
2
a general purposeprogramming language designed toexpress common programming patterns in a concise,elegant, and type-safeway. It smoothly integrates featuresof object-orientedand functionallanguages, enabling Javaand other programmers to be more productive.
http://www.scala-lang.org
http://www.scala-lang.org/http://www.scala-lang.org/http://www.scala-lang.org/http://www.scala-lang.org/8/13/2019 Scala Springone 111031111747 Phpapp01
3/56
Object-oriented
Everything is an object No primitives
Classes
Same as Java, but concise
Traits Interfaces done right
Singletons
Language-level concept
3
8/13/2019 Scala Springone 111031111747 Phpapp01
4/56
Statically typed
Rich type system (by Javas standard) Higher-kinded types
Implicit conversions
Type evidence
Expressive type system Inferred types
4
8/13/2019 Scala Springone 111031111747 Phpapp01
5/56
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 Scala doesnt force it
5
8/13/2019 Scala Springone 111031111747 Phpapp01
6/56
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
6
8/13/2019 Scala Springone 111031111747 Phpapp01
7/56
Hello World: Scripting Style
$ scala hello-script.scalaHello World
println("Hello World")
No compilation
8/13/2019 Scala Springone 111031111747 Phpapp01
8/56
Hello World: Porting of Java Code
$ scalac hello-java.scala$ scala example.MainHello World
// hello-java.scalapackageexample
objectMain {
defmain(args: Array[String]) {println("Hello World")}
}
static
Inferredsemicolons
8/13/2019 Scala Springone 111031111747 Phpapp01
9/56
Hello World: Using the App trait
$ scalac hello-app.scala$ scala example.MainHello World
// hello-app.scalapackageexample
objectMain extendsApp {println("Hello World")}
8/13/2019 Scala Springone 111031111747 Phpapp01
10/56
Simple Class
classPerson
valp = newPersonType
Inferred
Defaultaccess: public
No curlybraces needed
(but allowed)
8/13/2019 Scala Springone 111031111747 Phpapp01
11/56
Simple Class
classPerson
valp: Person = newPersonExplicit typespecification
8/13/2019 Scala Springone 111031111747 Phpapp01
12/56
Class with constructor
classPerson(firstName: String,
lastName: String)
valp = newPerson("Ramnivas", "Laddad")
println(p.firstName) // Error
Primaryconstructor
Fieldsaccessible in
class body
8/13/2019 Scala Springone 111031111747 Phpapp01
13/56
Class with getters
classPerson(valfirstName: String,
vallastName: String)
valp = newPerson("Ramnivas", "Laddad")println(p.firstName)
Value(Java final)
8/13/2019 Scala Springone 111031111747 Phpapp01
14/56
Class with gettersand setters
classPerson(varfirstName: String,
varlastName: String)
valp = newPerson("Ramnivas", "Laddad")println(p.firstName)p.firstName = "Ramnivas2
Variable (Javanon-final)
8/13/2019 Scala Springone 111031111747 Phpapp01
15/56
Extending a class
classStudent(firstName: String,
lastName: String,
valgrade: Int)
extendsPerson(firstName, lastName)
vals = newStudent("Ramnivas", "Laddad", 1)println(s.firstName)println(s.grade)
8/13/2019 Scala Springone 111031111747 Phpapp01
16/56
Defining methods
classPerson(valfirstName: String,vallastName: String) {
defname = firstName + " "+ lastName
overridedeftoString = name}
valp = newPerson("Ramnivas", "Laddad")
println(p.name) // Ramnivas Laddadprintln(p) // Ramnivas Laddad
Not optional
8/13/2019 Scala Springone 111031111747 Phpapp01
17/56
Uniform access principle
classPerson(valfirstName: String,vallastName: String) {
valname = firstName + " "+ lastName
overridedeftoString = name}
valp = newPerson("Ramnivas", "Laddad")
println(p.name) // Ramnivas Laddadprintln(p) // Ramnivas Laddad
8/13/2019 Scala Springone 111031111747 Phpapp01
18/56
Names in Scala
Class, method, field names can contain non alpha-numeric characters
::
:::
~>
f@#:
Valuable if used judiciously
DSLs
18
8/13/2019 Scala Springone 111031111747 Phpapp01
19/56
More about methods and fields
Declaring abstract methods and fields
Just dont provide definition
deflearn(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
19
8/13/2019 Scala Springone 111031111747 Phpapp01
20/56
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 itssubpackages
20
8/13/2019 Scala Springone 111031111747 Phpapp01
21/56
Traits: Interfaces done right
21
traitPartyGoer {
valage: IntvalyearsUntilLegalDrinking =
if(age >= 18) 0 else18-age
}
classStudent(firstName: String, lastName: String,
valage: Int, valgrade: Int)
extendsPerson(firstName, lastName)
withPartyGoer
vals = newStudent("a", "b", 17, 12)
s.yearsUntilLegalDrinking // 1
8/13/2019 Scala Springone 111031111747 Phpapp01
22/56
Collections
valpeople = List("John", "Jacob",
"Mike")
valfirstPerson = people(0)
println(firstPerson) // John
8/13/2019 Scala Springone 111031111747 Phpapp01
23/56
8/13/2019 Scala Springone 111031111747 Phpapp01
24/56
Working with collections: for comprehension
24
for(person
8/13/2019 Scala Springone 111031111747 Phpapp01
25/56
Working with collections: for comprehension
25
for(person
8/13/2019 Scala Springone 111031111747 Phpapp01
26/56
Working with collections: filter
valstudent1 = newStudent("first1", "last1", 1)
valstudent2 = newStudent("first2", "last2", 1)
valstudent3 = newStudent("first3", "last3", 2)
valstudent4 = newStudent("first4", "last4", 6)
valstudents = List(student1, student2,student3, student4)
valfirstGraders = students.filter(_.grade == 1)println(firstGraders)// List(first1 last1, first2 last2)
8/13/2019 Scala Springone 111031111747 Phpapp01
27/56
Working with collections: filter
valstudent1 = newStudent("first1", "last1", 1)
valstudent2 = newStudent("first2", "last2", 1)
valstudent3 = newStudent("first3", "last3", 2)
valstudent4 = newStudent("first4", "last4", 6)
valstudents = List(student1, student2,student3, student4)
valinFirstGrade: Student => Boolean
= s => s.grade == 1
valfirstGraders = students.filter(inFirstGrade)
// List(first1 last1, first2 last2)
8/13/2019 Scala Springone 111031111747 Phpapp01
28/56
Working with collections: using _
valstudent1 = newStudent("first1", "last1", 1)
valstudent2 = newStudent("first2", "last2", 1)
valstudent3 = newStudent("first3", "last3", 2)
valstudent4 = newStudent("first4", "last4", 6)
valstudents = List(student1, student2,student3, student4)
valfirstGraders
= students.filter(_.grade == 1)println(firstGraders)// List(first1 last1, first2 last2)
8/13/2019 Scala Springone 111031111747 Phpapp01
29/56
Working with collections: passing method as function
valstudent1 = newStudent("first1", "last1", 1)
valstudent2 = newStudent("first2", "last2", 1)
valstudent3 = newStudent("first3", "last3", 2)
valstudent4 = newStudent("first4", "last4", 6)
valstudents = List(student1, student2,student3, student4)
definFirstGrade(s: Student) : Boolean
= s.grade == 1valfirstGraders = students.filter(inFirstGrade)
// List(first1 last1, first2 last2)
8/13/2019 Scala Springone 111031111747 Phpapp01
30/56
Working with collections: partition
valstudent1 = newStudent("first1", "last1", 1)
valstudent2 = newStudent("first2", "last2", 1)
valstudent3 = newStudent("first3", "last3", 2)
valstudent4 = newStudent("first4", "last4", 6)
valstudents = 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
8/13/2019 Scala Springone 111031111747 Phpapp01
31/56
Working with collections: transforming
valstudent1 = newStudent("first1", "last1", 1)
valstudent2 = newStudent("first2", "last2", 1)
valstudent3 = newStudent("first3", "last3", 2)
valstudent4 = newStudent("first4", "last4", 6)
valstudents = List(student1, student2,student3, student4)
valrollCall = students.map(_.firstName)
println(rollCall)// List(first1, first2, first3, first4)
8/13/2019 Scala Springone 111031111747 Phpapp01
32/56
Map
// student1, student2, student3, student4
valstudentSchools = Map(student1 -> "Miller",student2 -> "Lawson",student3 -> "Lawson",
student4 -> "Miller")
println(studentSchools(student1)) // Miller
8/13/2019 Scala Springone 111031111747 Phpapp01
33/56
More collections
Set
IndexedSeq
Vector (good one!)
Range
1 to 100 1 until 100
2 until 100 by 2
Mutable versions
Parallel versions
33
8/13/2019 Scala Springone 111031111747 Phpapp01
34/56
Putting it together: Quicksort
defquicksort[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))
8/13/2019 Scala Springone 111031111747 Phpapp01
35/56
Putting it together: Quicksort
defquicksort[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)))
8/13/2019 Scala Springone 111031111747 Phpapp01
36/56
Pattern matching: Basics
vala:Any = "foo"
a match{
casestr: String => println("A string: "+ str)casei: Int => println("An int: "+ i)
case_ => println("Something else")
}
8/13/2019 Scala Springone 111031111747 Phpapp01
37/56
Pattern matching: with collections
vall = List("a", "b", "c")
l match{
caseNil => println("Empty!")casehead :: Nil =>
println("Only one item "+ head)
casehead :: tail =>
println("Item "+ head +" followed by "+ tail)
}
8/13/2019 Scala Springone 111031111747 Phpapp01
38/56
Quicksort with pattern matching
defquicksort[T](input: Traversable[T])(implicitordering: Ordering[T]) : Traversable[T] =
input match{
casehead :: 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)))
8/13/2019 Scala Springone 111031111747 Phpapp01
39/56
Destutter using Pattern matching
39
defdestutter[A](lst: List[A]): List[A] = lst match{caseh1 :: h2 :: tail if(h1 == h2)
=> destutter(h2 :: tail)
caseh1 :: 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()
8/13/2019 Scala Springone 111031111747 Phpapp01
40/56
Case classes
Useful in pattern matching
case
Offer many useful common methods
equals()
hashCode()
toString
copy()
40
8/13/2019 Scala Springone 111031111747 Phpapp01
41/56
Case classes
41
caseclassHuman(name: String)caseclassSuperHero(name: String, power: String)
valcharacters = List(Human("Programmer"),
SuperHero("Customer", "money"),
SuperHero("QA", "testing"))
8/13/2019 Scala Springone 111031111747 Phpapp01
42/56
Case classes and pattern matching
42
valactions = for(character
name + " needs to be saved"
caseSuperHero(name, power) =>name + " will save using "+ power
}
actions.foreach(println)
8/13/2019 Scala Springone 111031111747 Phpapp01
43/56
Pattern matching and extracting just enough
43
valactions = for(character
name + " needs to be saved"
caseSuperHero(_, power) =>
"Could be saved using "+ power
}
actions.foreach(println)
// Programmer needs to be saved// Could be saved using money// Could be saved using testing
8/13/2019 Scala Springone 111031111747 Phpapp01
44/56
Regular expressions
44
valtext = "Ramnivas Laddad"
valName = """(\w+)\s+(\w+)""".r
valperson = text match{
caseName(first, last) =>
Some(newPerson(first, last))
case_ =>
None
}
println(person) // Some(Ramnivas Laddad)
8/13/2019 Scala Springone 111031111747 Phpapp01
45/56
Options
45
valtexts =
List("Ramnivas Laddad", "foo", "Scott Andrews")
valpeopleOptions = texts.map {
_ match{caseName(first, last) =>
Some(newPerson(first, last))case_ => None
}}
println(peopleOptions)// List(Some(Ramnivas Laddad),
None,Some(Scott Andrews))
8/13/2019 Scala Springone 111031111747 Phpapp01
46/56
Options: flattening
46
valtexts =
List("Ramnivas Laddad", "foo", "Scott Andrews")
valpeopleOptions = texts.map {
_ match{
caseName(first, last) =>Some(newPerson(first, last))
case_ => None
}}
println(peopleOptions.flatten)// List(Ramnivas Laddad, Scott Andrews)
8/13/2019 Scala Springone 111031111747 Phpapp01
47/56
Options: flatMap
47
valtexts =
List("Ramnivas Laddad", "foo", "Scott Andrews")
valpeople = texts.flatMap {
_ match{
caseName(first, last) =>Some(newPerson(first, last))
case_ => None
}}
println(people)// List(Ramnivas Laddad, Scott Andrews)
8/13/2019 Scala Springone 111031111747 Phpapp01
48/56
Higher order functions
defprocess() : Unit = {retry(5){
...}
}
defretry[T](maxRetry: Int)(thunk: => T) = {
defretry(thunk: => T, attempt: Int): T = {try{thunk
} catch{caseex if(attempt < maxRetry) =>retry(thunk, attempt + 1)
}}retry(thunk, 0)
}
Thunk
8/13/2019 Scala Springone 111031111747 Phpapp01
49/56
Caching using Scala
defgetQuoteGraph(stock: Stock,
days: Int) : Array[Byte] = {
cached("chart", stock.ticker + ":" + days) {
... Expensive calculation
}
}
8/13/2019 Scala Springone 111031111747 Phpapp01
50/56
Caching higher-order function
abstractclassCaching(valcacheManager: CacheManager) {
defcached[T](region: String, key: Any)(thunk: => T): T = {
valcache = ...
if(cache.containsKey(key)) {
cache.get(key).asInstanceOf[T]
} else{
valthunkVal: T = thunk
cache.put(key, thunkVal)
thunkVal
}
}
}
8/13/2019 Scala Springone 111031111747 Phpapp01
51/56
Transaction management
deffindOrder(orderId: Long) : Order = {
transactional(readOnly=true) {
//...
}
}
defupdateOrder(order: Order) {
transactional() {
//...}
}
51
8/13/2019 Scala Springone 111031111747 Phpapp01
52/56
Transaction management function
deftransactional[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
8/13/2019 Scala Springone 111031111747 Phpapp01
53/56
Transaction management implementation
abstractclassTransactionManagement(valtxManager: PlatformTransactionManager) {
deftransactional[T](...)(thunk: => T) : T= {
valtxAttribute = newTransactionAttributeWithRollbackRules(...)
valstatus = txManager.getTransaction(txAttribute)
try{
valret = thunk
txManager.commit(status)ret
} catch{
caseex => {
if(txAttribute.rollbackOn(ex)) {
txManager.rollback(status)
} else{
txManager.commit(status)}
throwex
}
}
}
}
8/13/2019 Scala Springone 111031111747 Phpapp01
54/56
There is more a lot more
Methods/functions
Default parameters
Named parameters
Curried parameters
Partial 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
54
8/13/2019 Scala Springone 111031111747 Phpapp01
55/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
Learn Haskell first!
Might help to break from the Java way of thinking
55
Be ready to be humbled
8/13/2019 Scala Springone 111031111747 Phpapp01
56/56
Scala for Java Developers
Ramnivas Laddad
@ramnivas
http://localhost/var/www/apps/conversion/tmp/scratch_5/twitter.comhttp://localhost/var/www/apps/conversion/tmp/scratch_5/twitter.com