Prezi

Share this prezi

Who can edit:

Present Online

Send the link below via email or IM to invite your audience

Copy

Start the presentation

Start presenting

  • Invited audience will follow you as you navigate and present
  • This link expires 10 minutes after you close the presentation
  • A maximum of 30 users can view together your prezi
  • Learn more about this feature in the manual

Download prezi for:

Present offline on a PC or Mac.

  • Embedded YouTube videos need an active Internet connection to play.
  • Portable prezis are not editable.

Edit and present offline with Prezi Desktop

Do you really want to delete this prezi?

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

DeleteCancel

Make your likes visible on Facebook?

Connect your Facebook account to Prezi and let your likes appear on your timeline.
You can change this under Settings & Account at any time.

7 Languages in 7 Months: #4 Scala

No description
by Owein Reese on 28 February 2013

Comments (0)

Please log in to add your comment.

Report abuse

Prezi Transcript

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 Functional 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 Objects 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 Composition Currying Closures 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 operate(two) } 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 map flatMap filter Monadic flow control For As a Foreach For As a Map For as a Filter For-Comprehensions for(item <- items){ println(item) } 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 Mixins 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 guards 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 Covariance Contravariance 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 = { x.quack x.quack } } 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 conversions 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
See the full transcript