Scala for the doubters
-
Upload
nekuromento -
Category
Software
-
view
40 -
download
2
Transcript of Scala for the doubters
Scala for the doubtersMax Klyga
@Neku42
–James Gosling
“If I were to pick a language to use today other than Java,
it would be Scala.”
Scala
–James Iry, “A Brief, Incomplete, and Mostly Wrong History of Programming Languages”
“A drunken Martin Odersky sees a Reese's Peanut Butter Cup ad featuring
somebody's peanut butter getting on somebody else's chocolate and has an idea. He creates Scala, a language that
unifies constructs from both object oriented and functional languages. This
pisses off both groups and each promptly declares jihad.”
Scala
OOP FP
Lightweight syntax
object Main extends Application {
val phonebook = Map(
"Alice" -> "212-34-56",
"Bob" -> "265-43-21"
)
phonebook += ("Carl" -> "298-76-54")
println(phonebook("Alice"))
for (i <- 1 to 10) {
println(i)
}
}
Scala
Lightweight syntax
public class Person
{
private String firstName;
private String lastName;
String getFirstName() { return firstName; }
void setFirstName(String firstName) { this.firstName = firstName; }
String getLastName() { return lastName; }
void setLastName(String lastName) { this.lastName = lastName; }
int hashCode() { .... }
boolean equals(Object o) { .... }
}
Java
Lightweight syntax
case class Person(var firstName:String, var lastName:String)
Scala
Lightweight syntax
boolean hasUpperCase = false;
for (int i = 0; i < name.length(); ++i) {
if (Character.isUpperCase(name.charAt(i))) {
hasUpperCase = true;
break;
}
}
Java
Lightweight syntax
val hasUpperCase = name.exists(_.isUpperCase)
Scala
Lightweight syntax
Predicate<Character> isUpperCase = new Predicate<Character>() {
public Character apply(Character ch) {
return Character.isUpperCase(ch);
}
};
boolean hasUpperCase = Iterables.any(Lists.charactersOf(name), isUpperCase);
Java + Guava
Lightweight syntax
Predicate<Character> isUpperCase = (ch) -> Character.isUpperCase(ch);
boolean hasUpperCase = Iterables.any(Lists.charactersOf(name), isUpperCase);
Java 8 + Guava
Lightweight syntax
boolean hasUpperCase = name.chars().anyMatch((ch) -> Character.isUpperCase(ch));
Java 8
Lightweight syntax
boolean hasUpperCase = name.chars().anyMatch((ch) -> Character.isUpperCase(ch));
Java 8
Scala
val hasUpperCase = name.exists(_.isUpperCase)
LambdasJava 8
•Can only access final variables•Cannot mutate variables in outer scope
Scala
•Can access any variables•Can mutate any accessible variables
TraitsJava 8
•Can define default methods in interfaces(Java 9 allows private methods)
•“Diamond” inheritance is forbidden
Scala
•No restrictions on method implementation•Method invocation chain determined by inheritance order
Composable
Everything is an expression
Composable
var x:Int
if (…) {
x = 10
} else {
x = 0
}
Composable
val x = if (…) {
10
} else {
0
}
Composable
var x = List[Int]()
for (i <- 1 to 10) {
x = i :: x
}
Composable
var x = for (i <- 1 to 10) {
yield i
}
Composable
Everything is an expression
if for while try match
Composable
Things nest
Composableimport com.dull.lib
class Eggs {
import org.cool.lib
def bacon {
import org.other.cool.lib
…
}
}
Composableclass Eggs {
def bacon {
def inner(…) {
def innerer {
…
}
…
}
…
}
}
Pattern matchingsealed abstract class ChatProtocol
case class Message(userId:Int, text:String) extends ChatProtocol
case class Join(userId:Int, name:String) extends ChatProtocol
case class Leave(userId:Int) extends ChatProtocol
command match {
case Message(id, text) => println(s"${users(id)}: ${text}")
case Join(id, name) => {
users += (id, name)
println(s"${name} joined")
}
case Leave(id) => {
println(s"${users(id)} left")
users -= id
}
}
REPLJava 9 will finally get it too
So much more• Everything is an object
• Limited type inference
• Operator overloading (Everything is a method)
• Algebraic data types
• Partial functions
• Tuples
• Value classes
–Alan Perlis
“Syntactic sugar causes cancer of the semi-colons.”
Implicits
• Conversions
• Extension methods via Rich Interface Pattern
• Remove boilerplate code
Implicits
• Conversions
• Extension methods via Rich Interface Pattern
• Remove boilerplate code
Generic code
• Partial application
• Variance annotations
• Implicits
• Macros
With great power comes great responsibility
Sleep of reason produces monsters
Operator overloading abuse
val intermediateHandler = (:/(host, port) / target <<? params >:> identity)
https://github.com/dispatch/reboot
def root = jsonObj | jsonArray
def jsonObj = "{" ~> repsep(objEntry, ",") <~ "}" ^^ { case vals:List[_] => JSONObject(Map(vals:_*)) }
def jsonArray = "[" ~> repsep(value, ",") <~ "]" ^^ { case vals:List[_] => JSONArray(vals) }
def objEntry = stringVal ~ (":" ~> value) ^^ { case x ~ y => (x, y) }
https://github.com/scala/scala-parser-combinators
Unicode operators in ScalaZ: ≠ ∋ ⇏ ★ ∅
Learning Scala will make you a better Java programmer
Learning Scala will make you a better Java programmer
• Data transformation pipeline instead of CRUD
• “Sane” error handling, data validation
http://fsharpforfunandprofit.com/rop/
• Computation and data composition
For comprehensions (Monads …)
–Paul Graham
“you could get smarter programmers to work on a Python project than you could to
work on a Java project.”
The Python Paradox
The Scala Paradox
Why use Scala?
• eDSL
• Parsers
• Distributed computing infrastructure
eDSLval orders = List[Order](
// use the default pricing strategy
new Order to buy(200 sharesOf "GOOGLE")
maxUnitPrice 300
using defaultPricing,
// use a custom pricing strategy
new Order to sell(200 bondsOf "Sun")
maxUnitPrice 300
using {
(qty, unit) => qty * unit - 500
}
)
http://debasishg.blogspot.com/2008/05/designing-internal-dsls-in-scala.html
eDSLclass HelloWorldSpec extends Specification { def is = s2"""
This is a specification for the 'Hello world' string
The 'Hello world' string should
contain 11 characters $e1
start with 'Hello' $e2
end with 'world' $e3
"""
def e1 = "Hello world" must haveSize(11)
def e2 = "Hello world" must startWith("Hello")
def e3 = "Hello world" must endWith("world")
}
https://etorreborre.github.io/specs2/
eDSLobject SquareRoot extends Baysick {
def main(args:Array[String]) = {
10 PRINT "Enter a number"
20 INPUT 'n
30 PRINT "Square root of " % "'n is " % SQRT('n)
40 END
RUN
}
}
https://github.com/fogus/baysick
Java ❤️ Scala
Java ❤️ Scala
• Scala Maven plugin - http://davidb.github.io/scala-maven-plugin/
Learn more• Twitter Scala school
http://twitter.github.io/scala_school/
• Scala for the Impatient
http://www.horstmann.com/scala/
• Programming in Scala
http://www.artima.com/shop/programming_in_scala_2ed
• Functional Programming in Scala
http://manning.com/bjarnason/
Questions
Max Klyga@Neku42