Loading presentation...

Present Remotely

Send the link below via email or IM


Present to your audience

Start remote presentation

  • Invited audience members will follow you as you navigate and present
  • People invited to a presentation do not need a Prezi account
  • This link expires 10 minutes after you close the presentation
  • A maximum of 30 users can follow your presentation
  • Learn more about this feature in our knowledge base article

Do you really want to delete this prezi?

Neither you, nor the coeditors you shared it with will be able to recover it again.


7 Languages in 7 Months: #4 Scala

No description

Owein Reese

on 28 February 2013

Comments (0)

Please log in to add your comment.

Report abuse

Transcript of 7 Languages in 7 Months: #4 Scala

7 Languages in 7 Months Scala About Me Why Use It? Basic Constructs At a Glance Scala is Key Benefits @OweinReese

Engineer at Novus Partners Object Oriented
Statically Typed
Garbage Collected Interoperable with any Java library
Promotes immutable design
Type level programming
Higher-Order functions
Advanced Flow Control
Just as fast as Java in speed and performance Objects, Traits and Functions Objects Classes
Case Classes
Companions Case Classes Companion Classes class Foo(example: Thing){ //A Constructor
private val hidden = 1 //A variable
def bar(one: Thing, two: Thing) ={ //A Multi-line Method
val very = one + two
val complicated = one - two

example('s') are (very, complicated) //Look, no "return"
def baz(one: Thing) = one + example //Without brackets
} Objects object Foo{
val one = "The loneliest number"
def two = "Death and Taxes"
} Things to know:
No different from a class
No constructor
Are singletons
Careful with referencing other objects case class Foo(one: Thing, two: Thing){
def method = one + two
} Things to know:
Default implementation of hashCode, equals and serialization
Companion object has pre-built "apply" and "unapply" functions
All constructor params are public class Foo(one: Int, two: Int)

object Foo{
def apply(one: Int, two: Int) = new Foo(one, two)
} Things to know:
Share the same name
Do not explicitly share code
Often times, work hand in hand Functions Higher Order
Control-Like Functions Are First Class Composable Partial Application Forming Closures def threeTimes(arg: Int, f: Int => Int): Int
def evalution(one: Thing): Thing => Thing f(x) = x +1
g(x) = 2*x

h(x) = f(g(x)) = 2*x + 1 val more = threeTimes(3, timesTwo andThen plusOne) def plusValue(value: Int)(arg: Int) = arg + value

val more = threeTimes(2, plusValue(3)) def foo(one: Int, two: Int) ={
val modTwo = one % 2
def operate(value: Int) = value*modTwo

} Things to Know:
They can be passed as arguments
They can be returned as values
They can be treated like an object because they are! Things to Know:
You don't have to pass in all arguments at once
When you don't, you get another function Things to Know:
Inner functions have access to anything defined within the outer function
Inner functions have access to all class methods and variables Basic Control Conditional logic, comprehensions, and pattern matching Conditional Control If Statements
While loops
Recursion If Statement val positive = if(arg > 0) arg else -arg
if(positive < 42){
println("It's not the answer we seek")
} While Loops Recursion Things to Know:
If-else statements return a value
If statements return Unit (world's most useless type)
Brackets are not optional for multi-line statements var dirty = 0
while(dirty < 10){
side(effects are (dirty))
dirty += 1
} Things to Know:
Operate by side-effect
Often times more performant than a "map" or "flatMap"
Speed comparable to tail recursion def poorSum(arg: Int) =
if(arg > 0) arg + sum(arg - 1) else 0

@tailrec def sum(arg: Int, acc: Int = 0): Int =
if(arg > 0) sum(arg - 1, arg + acc) else acc Things to Know:
Recursion is fast
Non-tail recursive functions can still blow the stack
The "tailrec" annotation checks at compile time that you've written a tail recursive function For Comprehensions foreach
Monadic flow control For As a Foreach For As a Map For as a Filter For-Comprehensions for(item <- items){

items foreach println Things to Know:
Both statements do the same thing
Both statements compile to the same code! val more = for(item <- items) yield item + 1

val plusOne = items map (_ + 1) Things to Know:
The "yield" key word signifies the for-comprehension will return values
"yield" is not the same in Scala as it is in Python
Both statements compile to the same code val less = for(item <- items if predicate(item)) yield item

val same = items filter predicate Things to Know:
The if statement acts as a control guard, only those things which pass are acted upon in the yield statement
Both statements above do the same thing Monadic Flow Control val matching = for{
item <- items if predicate(item)
thing <- things
} yield process(item, thing) Things to Know:
You can iterate over multiple collections
Iteration is a combinatorial of all collections
Each successive portion has access to all retrieved prior values, hence calling both "item" and "thing" at the end def three(arg: Int) = List.fill(arg)(3)
def none(arg: Int) = List.fill(arg)(0)
def nine(arg: Int) = List.fill(arg)(9)

val guessHowMany = for{
item <- items
more <- three(item)
evenMore <- none(more)
omg <- nine(evenMore)
} yield omg Mixins Traits trait Foo{
def bar(one: Thing): Thing
def baz(one: Thing, two: Thing): Thing
def whoa(one: Thing) = baz(bar(one), one)
} Things to know:
No constructor
Not all methods need be defined
Powerful but easily abused, stay tuned Traits Traits
Stackable Control-Like Structures def keyOpLog(key: String)(op: => Thing) ={
val statement = op
log info statement
statement find(key)
def parse(that: What) = keyOpLog(key){
that validate(regex) extract()
} Things To Know:
Works like a "block" from Ruby
Resembles your standard controls: if, else, while, etc. Stackable Traits trait Summable{
def sum(one: Thing, two: Thing) = one sum (two.value)
class Foobar(inner: Thing) extends Foo with Summable{
def bar(one: Thing) = sum(one, inner)
def baz(one: Thing, two: Thing) = sum(one, two)
} Things to Know:
Multiple traits can be "mixed in" to a single class
Mixin order matters
Avoids problems associated with multiple inheritance
Used properly, promotes DRY trait First{
def foo(arg: Int): Int
def bar(arg: Int): Int
} trait Second extends First{
abstract override def bar(arg: Int) =
super bar (arg*3)
} class Base extends First{
def foo(arg: Int) = arg
def bar(arg: Int) = arg
class Stacked extends Base with Second Things to Know:
Works like a "decorator" pattern
Uses an inheritance model For As a FlatMap for{
num <- List(1, 2, 3)
more <- List.fill(num)(3)
} yield more

List(1, 2, 3) flatMap(num => List.fill(num)(3)) Things to Know:
Both produce List(1, 1, 1, 2, 2, 2, 3, 3, 3)
Without flatMap, you'd only be able to make a List of Lists More Than Collections val anotherFuture = for{
valueA <- futureA
valueB <- futureB
valueC <- futureC
} yield valueA + valueB + valueC Things To Know:
As long as an object implements a conforming map and flatMap, for-comprehensions work
This example shows how easy non-blocking code really is to write Pattern Matching basic
extraction With Types and Values Guards Extractors something match{
case x: Int => x % 2 == 0
case "a string" => true
case _ => false
} Things to Know:
You are not limited to a single type
Replaces several Gang of Four patterns
For types with a discrete set of subtypes, creates a compilation warning if not all handled thing match{
case x: Int if x < 0 => true
case x: Int => false
case _ => false
} Things to Know:
Adds control for predicate conditions
Corresponding "if-else" statements much more verbose case class Foo(one: Int)
case class Bar(one: Int, two: String)

item match{
case Foo(x) => x
case Bar(x, "wowsers") => x
case Bar(5, _) => 0
case Bar(x, y) if y.isEmpty => x
} Things to Know:
can match on type, value, predicate condition
case classes make use of the free "unapply"
anything with a defined "unapply" is fair game Other features Types and Implicits Types Declaring
Structural Type Parameters Covariance (Scary big word) Contravariance Structural class Foo[A](x: A){
def map[B](f: A => B) = new Foo(f(x))
} Things to Know:
Placeholder for an actual type
Foo[Int] is a different type from Foo[Double]
No real restriction on number of type parameters class Animal
class Dog extends Animal
class Counter[+A]{
def howMany(things: List[A]) = things.size
val counter = new Counter[Animal]
counter.howMany(someListOfDogs) Things to Know:
Dog "is a" Animal, so why isn't a List of dogs also a List of animals?
This allows the obvious and natural to happen trait Listener[-A]{
def listen(x: A)
class Record extends Listener[Event]{
def listen(x: Event){ println(x) }

def registerMouseListener(listener: Listener[MouseEvent]) Things to Know:
Works in opposite direction, any super type is acceptable
Why shouldn't an EventListener (a more general type) not be able to substitute for a MouseEventListener? type Duck = { def quack: Unit }
class DuckCall[Duck](x: Duck){
def goHunting = {
} Things to Know:
If it walks like a duck, talks like a duck...
Statically typed and compile time checked form of duck typing
Requires runtime inspection of code (reflection) so quite slow Implicits hidden parameters
pimp my library
type classes Hiding Method Parameters Implicitly Convert Pimp my Library Type Class In Action object AsyncCreator{
implicit val myThreadPool = new ThreadPool

def async[A](f: => A) = new PostPone(f)

class PostPone[A](action: => A)(implicit pool: ThreadPool){
val eventually = pool run (action)
} Things to Know:
Pass a value to a call site without explicitly declaring it
There is a defined order or precedence in searching for an implicit value
easy way to get yourself into trouble object AddOne{
implicit def convert(x: String) = x.toInt

def acceptOnlyInts(x: Int) = x + 1
val thisWorks = acceptOnlyInts("3")
} Things to Know:
Convert one type to another without having to add boilerplate code, an Adapter pattern or anything else
Avoid stateful changes (especially bidirectional stateful changes)
"turned off" by default in Scala 2.10 object PimpWithFrank{
implicit def s2frank(x: String) = new{
def frank = "frank" + x

"mystring".frank Things to Know:
you can add any method you want to any object
makes writing a DSL for a library easier
debugger may have problems stepping into these methods List(1, 2, 3).sum //compiles
List('a', 'b', 'c').sum //throws a compiler error

def sum(implicit num: Numeric[A]) Things to Know:
sum requires that there be a "Numeric" trait typed to the parameter "A." There exists a Numeric[Int] but no Numeric[Char]
Compile error is only thrown when attempting to use an undefined type class
Allows for "turning on" and "turning off" behavior based on types class Meter(m: Int)
object Meter{
implicit object MeterOrdering extends Ordering[Meters]{
def compare(first: Meter, second: Meter) = first.m compare second.m

val measures = List(new Meter(3), new Meter(6), new Meter(1))
val sorted = measures.sort //a new, sorted list Things to Know:
implicits are checked first at the class level, then companion object, then up the package list
Full transcript