SlideShare una empresa de Scribd logo
1 de 81
Simple Scala DSLs

      May 21, 2010




          1
A Definition




              2
A Definition

A DSL is a custom way to represent logic designed to
solve a specific problem.




                           2
A Definition

A DSL is a custom way to represent logic designed to
solve a specific problem.



I’m going to try and give you tools to stretch Scala’s
syntax to match the way you think about the logic of your
specific problem.




                            2
Key Scala features

• Syntactic sugar

• Implicit methods

• Options

• Higher order functions



                           3
Syntactic Sugar

You can omit . and () for any method which takes a single
parameter.

map get “key” == map.get(“key”)




                            4
Syntactic Sugar

Methods whose names end in : bind to the right.

“key” other: obj == obj.other:(“value”)

val newList = item :: oldList
val newList = oldList.::(item)




                           5
Syntactic Sugar

the apply() method

a(b) == a.apply(b)

map(“key”)     ==    map.apply(“key”)




                          6
Syntactic Sugar

the update() method

a(b) = c == a.update(b, c)
a(b, c) = d == a.update(b, c, d)

map(“key”) = “value” ==
   map.update(“key”, “value”)




                      7
Syntactic Sugar

setters and getters
object X { var y = 0 }
object X {
   private var _z: Int = 0
   def y = _z
   def y_=(i: Int) = _z = i
}
X.y => 0
X.y = 1 => Unit
X.y => 1
                      8
Syntactic Sugar

tuples

(a, b) == Tuple2[A,B](a, b)
(a, b, c) == Tuple3[A,B,C](a, b, c)

val (a, b) = sometuple   // extracts




                     9
Syntactic Sugar
unapply() - used to extract values in pattern matching
object Square {
  def unapply(p: Pair[Int, Int]) = p match {
    case (x, y) if x == y => Some(x)
    case _ => None
  }
}
(2, 2) match {
  case Square(side) => side*side
  case _ => -1
}                        10
Syntactic Sugar
varargs - sugar for a variable length array

def join(arr: String*) = arr.mkString(“,”)
join(“a”) => “a”
join(“a”, “b”) => “a,b”

def join(arr: Array[String]) =
arr.mkString(“,”)
join(Array(“a”, “b”)) => “a,b”


                             11
Syntactic Sugar
unapplySeq() - an extractor that supports vararg matching

object Join {
  def apply(l: String*) = l.mkString(“,”)
  def unapplySeq(s: String) =
    Some(s.split(“,”))
}
Join(“1”, “2”, “3”) match {
  case Join(“1”, _*) => println(“starts w/1”)
  case _ => println(“doesn’t start w/1”)
}
                           12
Syntactic Sugar




                  13
Syntactic Sugar
Case Classes are regular classes which export their
constructor parameters and which provide a recursive
decomposition mechanism via pattern matching.




                           13
Syntactic Sugar
Case Classes are regular classes which export their
constructor parameters and which provide a recursive
decomposition mechanism via pattern matching.

case class Square(side: Int)




                           13
Syntactic Sugar
Case Classes are regular classes which export their
constructor parameters and which provide a recursive
decomposition mechanism via pattern matching.

case class Square(side: Int)
val s = Square(2) // apply() is defined




                           13
Syntactic Sugar
Case Classes are regular classes which export their
constructor parameters and which provide a recursive
decomposition mechanism via pattern matching.

case class Square(side: Int)
val s = Square(2) // apply() is defined
s.side => 2        // member is exported




                           13
Syntactic Sugar
Case Classes are regular classes which export their
constructor parameters and which provide a recursive
decomposition mechanism via pattern matching.

case class Square(side: Int)
val s = Square(2) // apply() is defined
s.side => 2        // member is exported
val Square(x) = s // unapply() is defined




                           13
Syntactic Sugar
Case Classes are regular classes which export their
constructor parameters and which provide a recursive
decomposition mechanism via pattern matching.

case class Square(side: Int)
val s = Square(2) // apply() is defined
s.side => 2        // member is exported
val Square(x) = s // unapply() is defined
s.toString ==> “Square(2)”



                           13
Syntactic Sugar
Case Classes are regular classes which export their
constructor parameters and which provide a recursive
decomposition mechanism via pattern matching.

case class Square(side: Int)
val s = Square(2) // apply() is defined
s.side => 2        // member is exported
val Square(x) = s // unapply() is defined
s.toString ==> “Square(2)”
s.hashCode ==> 630363263

                           13
Syntactic Sugar
Case Classes are regular classes which export their
constructor parameters and which provide a recursive
decomposition mechanism via pattern matching.

case class Square(side: Int)
val s = Square(2) // apply() is defined
s.side => 2        // member is exported
val Square(x) = s // unapply() is defined
s.toString ==> “Square(2)”
s.hashCode ==> 630363263
s == Square(2) ==> true
                           13
Syntactic Sugar




                  14
Syntactic Sugar
Many classes can be used in for comprehensions because
they implement some combination of:

map[B](f: (A) => B): Option[B]
flatMap[B](f: (A) => Option[B]): Option[B]
filter(p: (A) => Boolean): Option[A]
foreach(f: (A) => Unit): Unit




                          14
Syntactic Sugar
Many classes can be used in for comprehensions because
they implement some combination of:

map[B](f: (A) => B): Option[B]
flatMap[B](f: (A) => Option[B]): Option[B]
filter(p: (A) => Boolean): Option[A]
foreach(f: (A) => Unit): Unit

for { i <- List(1,2,3)
      val x = i * 3
      if x % 2 == 0 } yield x          ==> List(6)

List(1,2,3).map(_ * 3).filter(_ % 2 == 0)
  ==> List(6)             14
Implicit Methods
Implicit methods are a compromise between the
closed approach to extension of Java and the open
approach to extension in Ruby.

Implicit Methods are:




                           15
Implicit Methods
Implicit methods are a compromise between the
closed approach to extension of Java and the open
approach to extension in Ruby.

Implicit Methods are:

• lexically scoped / non-global




                            15
Implicit Methods
Implicit methods are a compromise between the
closed approach to extension of Java and the open
approach to extension in Ruby.

Implicit Methods are:

• lexically scoped / non-global
• statically typed



                            15
Implicit Methods
Implicit methods are inserted by the compiler under
the following rules:




                            16
Implicit Methods
Implicit methods are inserted by the compiler under
the following rules:

   • they are in scope




                            16
Implicit Methods
Implicit methods are inserted by the compiler under
the following rules:

   • they are in scope
   • the selection is unambiguous




                            16
Implicit Methods
Implicit methods are inserted by the compiler under
the following rules:

   • they are in scope
   • the selection is unambiguous
   • it is not already in an implicit i.e. no nesting




                              16
Implicit Methods
Implicit methods are inserted by the compiler under
the following rules:

   • they are in scope
   • the selection is unambiguous
   • it is not already in an implicit i.e. no nesting
   • the code does not compile as written


                              16
Implicit Methods: Usage

Extending Abstractions: Java

class IntWrapper(int i) {
  int timesTen() {
    return i * 10;
  }
}

int i = 2;
new IntWrapper(i).timesTen();



                          17
Implicit Methods: Usage

Extending Abstractions: Java

Java’s abstractions are totally sealed and we must use
explicit wrapping each time we wish to extend them.

Pros: safe

Cons: repetitive boilerplate at each call site




                             18
Implicit Methods: Usage

Extending Abstractions: Ruby

class Int
  def timesTen
    self * 10
  end
end

i = 2
i.timesTen



                          19
Implicit Methods: Usage

Extending Abstractions: Ruby

Ruby’s abstractions are totally open. We can modify
the behavior of existing classes and objects in pretty
much any way we want.

Pros: declarative, powerful and flexible

Cons: easily abused and can be extremely difficult to
debug



                            20
Implicit Methods: Usage

Extending Abstractions: Scala

class IntWrapper(i: Int) {
  def timesTen = i * 10
}

implicit def wrapint(i: Int) =
  new IntWrapper(i)

val i = 2
i.timesTen


                           21
Implicit Methods: Usage

Extending Abstractions: Scala

Scala’s approach is both powerful and safe. While it is
certainly possible to abuse, it naturally encourages a
safer approach through lexical scoping.

Pros: more powerful than java, safer than ruby

Cons: can result in unexpected behavior if not tightly
scoped



                            22
Implicit Methods: Usage

Normalizing parameters

def remainder[T <: Double](num: T): Double =
num - num.floor




                         23
Implicit Methods: Usage

Normalizing parameters

def remainder[T <: Double](num: T): Double =
num - num.floor

remainder(.4)       ==> 0




                         23
Implicit Methods: Usage

Normalizing parameters

def remainder[T <: Double](num: T): Double =
num - num.floor

remainder(.4)       ==> 0

remainder(1.2)      ==> 1.2




                         23
Implicit Methods: Usage

Normalizing parameters

def remainder[T <: Double](num: T): Double =
num - num.floor

remainder(.4)       ==> 0

remainder(1.2)      ==> 1.2

remainder(120d) ==> 0



                         23
Implicit Methods: Usage

Normalizing parameters




                         24
Implicit Methods: Usage

Normalizing parameters

remainder(120) ==> error: inferred
type arguments [Int] do not conform to
method remainder's type parameter
bounds [T <: Double]




                         24
Implicit Methods: Usage

Normalizing parameters

remainder(120) ==> error: inferred
type arguments [Int] do not conform to
method remainder's type parameter
bounds [T <: Double]

implicit def i2d(i: Int): Double =
i.toDouble




                         24
Implicit Methods: Usage

Normalizing parameters

remainder(120) ==> error: inferred
type arguments [Int] do not conform to
method remainder's type parameter
bounds [T <: Double]

implicit def i2d(i: Int): Double =
i.toDouble

remainder(120)      ==> 0

                         24
Options

Options are scala’s answer to null.

Options are a very simple, 3-part class hierarchy:




                            25
Options

Options are scala’s answer to null.

Options are a very simple, 3-part class hierarchy:


• sealed abstract class Option[+A] extends
Product




                            25
Options

Options are scala’s answer to null.

Options are a very simple, 3-part class hierarchy:


• sealed abstract class Option[+A] extends
Product

• case final class Some[+A](val x : A)
extends Option[A]



                            25
Options

Options are scala’s answer to null.

Options are a very simple, 3-part class hierarchy:


• sealed abstract class Option[+A] extends
Product

• case final class Some[+A](val x : A)
extends Option[A]

• case object None extends Option[Nothing]
                            25
Options: Common Methods

def get: A

Some(1).get
 ==> 1

None.get
 ==> java.util.NoSuchElementException!




                   26
Options: Common Methods

def getOrElse[B >: A](default: => B): B

Some(1).getOrElse(2)
 ==> 1

None.getOrElse(2)
 ==> 2




                    27
Options: Common Methods

def map[B](f: (A) => B): Option[B]

Some(1).map(_.toString)
 ==> Some(“1”)

None.map(_.toString)
 ==> None




                   28
Options: Usage

Replacing Null Checks

A (contrived) Java example:

int result = -1;
int x = calcX();
if (x != null) {
  int y = calcY();
  if (y != null) {
    result = x * y;
  }
}
                              29
Options: Usage

Replacing Null Checks

def calcX: Option[Int]
def calcY: Option[Int]

for {
  val x <- Some(3)
  val y <- Some(2)
} yield x * y

 ==> Some(6)


                        30
Options: Usage

Replacing Null Checks

for {
  val x <- None
  val y <- Some(2)
} yield x * y

 ==> None




                        31
Options: Usage

Replacing Null Checks

(for {
  val x <- None
  val y <- Some(2)
} yield x * y).getOrElse(-1)

 ==> -1




                        32
Options: Usage

Replacing Null Checks

(for {
  val x <- Some(3)
  val y <- Some(2)
} yield x * y).getOrElse(-1)

 ==> 6




                        33
Options: Usage

Safely Transforming Values

val x: Option[Int] = calcOptionalX()

def xform(i: Int): Int




                             34
Options: Usage

Safely Transforming Values

val x: Option[Int] = calcOptionalX()

def xform(i: Int): Int


(x map xform) getOrElse -1




                             34
Options: Usage

Safely Transforming Values

val x: Option[Int] = calcOptionalX()

def xform(i: Int): Int


(x map xform) getOrElse -1

(for (i <- x) yield xform(i)).getOrElse(-1)


                             34
Implicits + Options




                      35
Implicits + Options

val m = Map(“1” -> 1,“map” -> Map(“2” -> 2))




                      35
Implicits + Options

val m = Map(“1” -> 1,“map” -> Map(“2” -> 2))


We’d like to be able to access the map like this:

m/”key1”/”key2”/”key3”




                            35
Implicits + Options

val m = Map(“1” -> 1,“map” -> Map(“2” -> 2))


We’d like to be able to access the map like this:

m/”key1”/”key2”/”key3”


But, we’d like to not have to constantly check nulls or
Options.



                            35
Implicits + Options

class MapWrapper(map: Map[String, Any]) {
  def /(s: String): Option[Any] = map.get(s)
}

implicit def a2mw(a: Any) = new
MapWrapper(a.asInstanceOf[Map[String, Any]])




                      36
Implicits + Options

class MapWrapper(map: Map[String, Any]) {
  def /(s: String): Option[Any] = map.get(s)
}

implicit def a2mw(a: Any) = new
MapWrapper(a.asInstanceOf[Map[String, Any]])

m/”a” ==> None




                      36
Implicits + Options

class MapWrapper(map: Map[String, Any]) {
  def /(s: String): Option[Any] = map.get(s)
}

implicit def a2mw(a: Any) = new
MapWrapper(a.asInstanceOf[Map[String, Any]])

m/”a” ==> None

m/”1” ==> Some(1)


                      36
Implicits + Options

class MapWrapper(map: Map[String, Any]) {
  def /(s: String): Option[Any] = map.get(s)
}

implicit def a2mw(a: Any) = new
MapWrapper(a.asInstanceOf[Map[String, Any]])

m/”a” ==> None

m/”1” ==> Some(1)

m/”map”/”2” ==> ClassCastException!
                      36
Implicits + Options

class OptionMapWrapper(
    o: Option[MapWrapper]) {
  def /(s: String) = o match {
    case Some(mw) => mw/s
    case _ => None
  }
}
implicit def o2omw(o: Option[Any]) = new
OptionMapWrapper(o map a2mw)




                      37
Implicits + Options

class OptionMapWrapper(
    o: Option[MapWrapper]) {
  def /(s: String) = o match {
    case Some(mw) => mw/s
    case _ => None
  }
}
implicit def o2omw(o: Option[Any]) = new
OptionMapWrapper(o map a2mw)

m/”map”/”2”   ==> Some(2)


                      37
Implicits + Options

class OptionMapWrapper(
    o: Option[MapWrapper]) {
  def /(s: String) = o match {
    case Some(mw) => mw/s
    case _ => None
  }
}
implicit def o2omw(o: Option[Any]) = new
OptionMapWrapper(o map a2mw)

m/”map”/”2”   ==> Some(2)

m/”map”/”next”/”blah”      ==> None
                      37
Higher Order Functions
Higher order functions are functions that:

• take functions as parameters
AND / OR

• result in a function




                             38
Higher Order Functions




                    39
Higher Order Functions
Let’s say we’d like to write a little system for easily running
statements asynchronously via either threads or actors.




                              39
Higher Order Functions
Let’s say we’d like to write a little system for easily running
statements asynchronously via either threads or actors.


What we’d like to get to:

run (println(“hello”)) using threads

run (println(“hello”)) using actors




                              39
Higher Order Functions
trait RunCtx {
  def run(f: => Unit): Unit
}

class Runner(f: => Unit) {
  def using(ctx: RunCtx) = ctx run f
}

def run(f: => Unit) = new Runner(f)




                     40
Higher Order Functions
object actors extends RunCtx {
  def run(f: => Unit) =
    scala.actors.Actor.actor(f)
}

object threads extends RunCtx {
  def run(f: => Unit) = {
    object t extends Thread {
      override def run = f
    }
    t.start
  }
}
                     41
Thank You!


email: lincoln@hotpotato.com
twitter: 11nc
hotpotato: lincoln


Questions?



                          42

Más contenido relacionado

La actualidad más candente

Introduction to matlab lecture 2 of 4
Introduction to matlab lecture 2 of 4Introduction to matlab lecture 2 of 4
Introduction to matlab lecture 2 of 4Randa Elanwar
 
16. Arrays Lists Stacks Queues
16. Arrays Lists Stacks Queues16. Arrays Lists Stacks Queues
16. Arrays Lists Stacks QueuesIntro C# Book
 
Monoids - Part 2 - with examples using Scalaz and Cats
Monoids - Part 2 - with examples using Scalaz and CatsMonoids - Part 2 - with examples using Scalaz and Cats
Monoids - Part 2 - with examples using Scalaz and CatsPhilip Schwarz
 
Scala categorytheory
Scala categorytheoryScala categorytheory
Scala categorytheoryKnoldus Inc.
 
First-Class Patterns
First-Class PatternsFirst-Class Patterns
First-Class PatternsJohn De Goes
 
Introduction to MatLab programming
Introduction to MatLab programmingIntroduction to MatLab programming
Introduction to MatLab programmingDamian T. Gordon
 
Matlab solved problems
Matlab solved problemsMatlab solved problems
Matlab solved problemsMake Mannan
 
N-Queens Combinatorial Problem - Polyglot FP for fun and profit - Haskell and...
N-Queens Combinatorial Problem - Polyglot FP for fun and profit - Haskell and...N-Queens Combinatorial Problem - Polyglot FP for fun and profit - Haskell and...
N-Queens Combinatorial Problem - Polyglot FP for fun and profit - Haskell and...Philip Schwarz
 
Introduction to matlab lecture 3 of 4
Introduction to matlab lecture 3 of 4Introduction to matlab lecture 3 of 4
Introduction to matlab lecture 3 of 4Randa Elanwar
 
O caml2014 leroy-slides
O caml2014 leroy-slidesO caml2014 leroy-slides
O caml2014 leroy-slidesOCaml
 
One Monad to Rule Them All
One Monad to Rule Them AllOne Monad to Rule Them All
One Monad to Rule Them AllJohn De Goes
 
Scala Collections : Java 8 on Steroids
Scala Collections : Java 8 on SteroidsScala Collections : Java 8 on Steroids
Scala Collections : Java 8 on SteroidsFrançois Garillot
 
Introduction to Monads in Scala (2)
Introduction to Monads in Scala (2)Introduction to Monads in Scala (2)
Introduction to Monads in Scala (2)stasimus
 
Matlab Functions
Matlab FunctionsMatlab Functions
Matlab FunctionsUmer Azeem
 
19. Java data structures algorithms and complexity
19. Java data structures algorithms and complexity19. Java data structures algorithms and complexity
19. Java data structures algorithms and complexityIntro C# Book
 

La actualidad más candente (20)

Chapter 5
Chapter 5Chapter 5
Chapter 5
 
Introduction to matlab lecture 2 of 4
Introduction to matlab lecture 2 of 4Introduction to matlab lecture 2 of 4
Introduction to matlab lecture 2 of 4
 
16. Arrays Lists Stacks Queues
16. Arrays Lists Stacks Queues16. Arrays Lists Stacks Queues
16. Arrays Lists Stacks Queues
 
Monoids - Part 2 - with examples using Scalaz and Cats
Monoids - Part 2 - with examples using Scalaz and CatsMonoids - Part 2 - with examples using Scalaz and Cats
Monoids - Part 2 - with examples using Scalaz and Cats
 
Scala categorytheory
Scala categorytheoryScala categorytheory
Scala categorytheory
 
First-Class Patterns
First-Class PatternsFirst-Class Patterns
First-Class Patterns
 
Ch3
Ch3Ch3
Ch3
 
Introduction to MatLab programming
Introduction to MatLab programmingIntroduction to MatLab programming
Introduction to MatLab programming
 
Cats in Scala
Cats in ScalaCats in Scala
Cats in Scala
 
Matlab solved problems
Matlab solved problemsMatlab solved problems
Matlab solved problems
 
N-Queens Combinatorial Problem - Polyglot FP for fun and profit - Haskell and...
N-Queens Combinatorial Problem - Polyglot FP for fun and profit - Haskell and...N-Queens Combinatorial Problem - Polyglot FP for fun and profit - Haskell and...
N-Queens Combinatorial Problem - Polyglot FP for fun and profit - Haskell and...
 
Introduction to matlab lecture 3 of 4
Introduction to matlab lecture 3 of 4Introduction to matlab lecture 3 of 4
Introduction to matlab lecture 3 of 4
 
O caml2014 leroy-slides
O caml2014 leroy-slidesO caml2014 leroy-slides
O caml2014 leroy-slides
 
One Monad to Rule Them All
One Monad to Rule Them AllOne Monad to Rule Them All
One Monad to Rule Them All
 
Scala Collections : Java 8 on Steroids
Scala Collections : Java 8 on SteroidsScala Collections : Java 8 on Steroids
Scala Collections : Java 8 on Steroids
 
Introduction to Monads in Scala (2)
Introduction to Monads in Scala (2)Introduction to Monads in Scala (2)
Introduction to Monads in Scala (2)
 
Matlab Functions
Matlab FunctionsMatlab Functions
Matlab Functions
 
Scala Bootcamp 1
Scala Bootcamp 1Scala Bootcamp 1
Scala Bootcamp 1
 
Getting Started With Scala
Getting Started With ScalaGetting Started With Scala
Getting Started With Scala
 
19. Java data structures algorithms and complexity
19. Java data structures algorithms and complexity19. Java data structures algorithms and complexity
19. Java data structures algorithms and complexity
 

Destacado

Writing DSL's in Scala
Writing DSL's in ScalaWriting DSL's in Scala
Writing DSL's in ScalaAbhijit Sharma
 
A Field Guide to DSL Design in Scala
A Field Guide to DSL Design in ScalaA Field Guide to DSL Design in Scala
A Field Guide to DSL Design in ScalaTomer Gabel
 
Using Scala for building DSLs
Using Scala for building DSLsUsing Scala for building DSLs
Using Scala for building DSLsIndicThreads
 
Domain specific languages and Scala
Domain specific languages and ScalaDomain specific languages and Scala
Domain specific languages and ScalaFilip Krikava
 
Type Parameterization
Type ParameterizationType Parameterization
Type ParameterizationKnoldus Inc.
 
Effective Programming In Scala
Effective Programming In ScalaEffective Programming In Scala
Effective Programming In ScalaHarsh Sharma
 
So various polymorphism in Scala
So various polymorphism in ScalaSo various polymorphism in Scala
So various polymorphism in Scalab0ris_1
 
Real-World Scala Design Patterns
Real-World Scala Design PatternsReal-World Scala Design Patterns
Real-World Scala Design PatternsNLJUG
 
Scala Implicits - Not to be feared
Scala Implicits - Not to be fearedScala Implicits - Not to be feared
Scala Implicits - Not to be fearedDerek Wyatt
 
Types by Adform Research, Saulius Valatka
Types by Adform Research, Saulius ValatkaTypes by Adform Research, Saulius Valatka
Types by Adform Research, Saulius ValatkaVasil Remeniuk
 
Variance in scala
Variance in scalaVariance in scala
Variance in scalaLyleK
 
Scala Types of Types @ Lambda Days
Scala Types of Types @ Lambda DaysScala Types of Types @ Lambda Days
Scala Types of Types @ Lambda DaysKonrad Malawski
 
JavaFX 2 and Scala - Like Milk and Cookies (33rd Degrees)
JavaFX 2 and Scala - Like Milk and Cookies (33rd Degrees)JavaFX 2 and Scala - Like Milk and Cookies (33rd Degrees)
JavaFX 2 and Scala - Like Milk and Cookies (33rd Degrees)Stephen Chin
 
Big Data Day LA 2016/ Hadoop/ Spark/ Kafka track - Data Provenance Support in...
Big Data Day LA 2016/ Hadoop/ Spark/ Kafka track - Data Provenance Support in...Big Data Day LA 2016/ Hadoop/ Spark/ Kafka track - Data Provenance Support in...
Big Data Day LA 2016/ Hadoop/ Spark/ Kafka track - Data Provenance Support in...Data Con LA
 
Python and Bigdata - An Introduction to Spark (PySpark)
Python and Bigdata -  An Introduction to Spark (PySpark)Python and Bigdata -  An Introduction to Spark (PySpark)
Python and Bigdata - An Introduction to Spark (PySpark)hiteshnd
 
Advanced Functional Programming in Scala
Advanced Functional Programming in ScalaAdvanced Functional Programming in Scala
Advanced Functional Programming in ScalaPatrick Nicolas
 
Introduction to Spark Internals
Introduction to Spark InternalsIntroduction to Spark Internals
Introduction to Spark InternalsPietro Michiardi
 
Everyday I'm Shuffling - Tips for Writing Better Spark Programs, Strata San J...
Everyday I'm Shuffling - Tips for Writing Better Spark Programs, Strata San J...Everyday I'm Shuffling - Tips for Writing Better Spark Programs, Strata San J...
Everyday I'm Shuffling - Tips for Writing Better Spark Programs, Strata San J...Databricks
 

Destacado (20)

Writing DSL's in Scala
Writing DSL's in ScalaWriting DSL's in Scala
Writing DSL's in Scala
 
A Field Guide to DSL Design in Scala
A Field Guide to DSL Design in ScalaA Field Guide to DSL Design in Scala
A Field Guide to DSL Design in Scala
 
Using Scala for building DSLs
Using Scala for building DSLsUsing Scala for building DSLs
Using Scala for building DSLs
 
Domain specific languages and Scala
Domain specific languages and ScalaDomain specific languages and Scala
Domain specific languages and Scala
 
Type Parameterization
Type ParameterizationType Parameterization
Type Parameterization
 
Effective Programming In Scala
Effective Programming In ScalaEffective Programming In Scala
Effective Programming In Scala
 
Scala collections
Scala collectionsScala collections
Scala collections
 
So various polymorphism in Scala
So various polymorphism in ScalaSo various polymorphism in Scala
So various polymorphism in Scala
 
Scala’s implicits
Scala’s implicitsScala’s implicits
Scala’s implicits
 
Real-World Scala Design Patterns
Real-World Scala Design PatternsReal-World Scala Design Patterns
Real-World Scala Design Patterns
 
Scala Implicits - Not to be feared
Scala Implicits - Not to be fearedScala Implicits - Not to be feared
Scala Implicits - Not to be feared
 
Types by Adform Research, Saulius Valatka
Types by Adform Research, Saulius ValatkaTypes by Adform Research, Saulius Valatka
Types by Adform Research, Saulius Valatka
 
Variance in scala
Variance in scalaVariance in scala
Variance in scala
 
Scala Types of Types @ Lambda Days
Scala Types of Types @ Lambda DaysScala Types of Types @ Lambda Days
Scala Types of Types @ Lambda Days
 
JavaFX 2 and Scala - Like Milk and Cookies (33rd Degrees)
JavaFX 2 and Scala - Like Milk and Cookies (33rd Degrees)JavaFX 2 and Scala - Like Milk and Cookies (33rd Degrees)
JavaFX 2 and Scala - Like Milk and Cookies (33rd Degrees)
 
Big Data Day LA 2016/ Hadoop/ Spark/ Kafka track - Data Provenance Support in...
Big Data Day LA 2016/ Hadoop/ Spark/ Kafka track - Data Provenance Support in...Big Data Day LA 2016/ Hadoop/ Spark/ Kafka track - Data Provenance Support in...
Big Data Day LA 2016/ Hadoop/ Spark/ Kafka track - Data Provenance Support in...
 
Python and Bigdata - An Introduction to Spark (PySpark)
Python and Bigdata -  An Introduction to Spark (PySpark)Python and Bigdata -  An Introduction to Spark (PySpark)
Python and Bigdata - An Introduction to Spark (PySpark)
 
Advanced Functional Programming in Scala
Advanced Functional Programming in ScalaAdvanced Functional Programming in Scala
Advanced Functional Programming in Scala
 
Introduction to Spark Internals
Introduction to Spark InternalsIntroduction to Spark Internals
Introduction to Spark Internals
 
Everyday I'm Shuffling - Tips for Writing Better Spark Programs, Strata San J...
Everyday I'm Shuffling - Tips for Writing Better Spark Programs, Strata San J...Everyday I'm Shuffling - Tips for Writing Better Spark Programs, Strata San J...
Everyday I'm Shuffling - Tips for Writing Better Spark Programs, Strata San J...
 

Similar a Simple Scala DSLs

Functional Programming With Scala
Functional Programming With ScalaFunctional Programming With Scala
Functional Programming With ScalaKnoldus Inc.
 
Core java by a introduction sandesh sharma
Core java by a introduction sandesh sharmaCore java by a introduction sandesh sharma
Core java by a introduction sandesh sharmaSandesh Sharma
 
Functional programming with Scala
Functional programming with ScalaFunctional programming with Scala
Functional programming with ScalaNeelkanth Sachdeva
 
Ifi7184 lesson3
Ifi7184 lesson3Ifi7184 lesson3
Ifi7184 lesson3Sónia
 
White Box testing by Pankaj Thakur, NITTTR Chandigarh
White Box testing by Pankaj Thakur, NITTTR ChandigarhWhite Box testing by Pankaj Thakur, NITTTR Chandigarh
White Box testing by Pankaj Thakur, NITTTR ChandigarhPankaj Thakur
 
Scilab as a calculator
Scilab as a calculatorScilab as a calculator
Scilab as a calculatorScilab
 
Functional programming-advantages
Functional programming-advantagesFunctional programming-advantages
Functional programming-advantagesSergei Winitzki
 
Guava Overview. Part 1 @ Bucharest JUG #1
Guava Overview. Part 1 @ Bucharest JUG #1 Guava Overview. Part 1 @ Bucharest JUG #1
Guava Overview. Part 1 @ Bucharest JUG #1 Andrei Savu
 
Java concepts and questions
Java concepts and questionsJava concepts and questions
Java concepts and questionsFarag Zakaria
 
New Functional Features of Java 8
New Functional Features of Java 8New Functional Features of Java 8
New Functional Features of Java 8franciscoortin
 
ScalaLanguage_ch_4_5.pptx
ScalaLanguage_ch_4_5.pptxScalaLanguage_ch_4_5.pptx
ScalaLanguage_ch_4_5.pptxjkapardhi
 
Java8: what's new and what's hot
Java8: what's new and what's hotJava8: what's new and what's hot
Java8: what's new and what's hotSergii Maliarov
 
JavaScript(Es5) Interview Questions & Answers
JavaScript(Es5)  Interview Questions & AnswersJavaScript(Es5)  Interview Questions & Answers
JavaScript(Es5) Interview Questions & AnswersRatnala Charan kumar
 

Similar a Simple Scala DSLs (20)

Functional Programming With Scala
Functional Programming With ScalaFunctional Programming With Scala
Functional Programming With Scala
 
Core java by a introduction sandesh sharma
Core java by a introduction sandesh sharmaCore java by a introduction sandesh sharma
Core java by a introduction sandesh sharma
 
Functional programming with Scala
Functional programming with ScalaFunctional programming with Scala
Functional programming with Scala
 
Java 8
Java 8Java 8
Java 8
 
Ifi7184 lesson3
Ifi7184 lesson3Ifi7184 lesson3
Ifi7184 lesson3
 
White Box testing by Pankaj Thakur, NITTTR Chandigarh
White Box testing by Pankaj Thakur, NITTTR ChandigarhWhite Box testing by Pankaj Thakur, NITTTR Chandigarh
White Box testing by Pankaj Thakur, NITTTR Chandigarh
 
Scilab as a calculator
Scilab as a calculatorScilab as a calculator
Scilab as a calculator
 
Methods
MethodsMethods
Methods
 
java8
java8java8
java8
 
Functional programming-advantages
Functional programming-advantagesFunctional programming-advantages
Functional programming-advantages
 
Guava Overview. Part 1 @ Bucharest JUG #1
Guava Overview. Part 1 @ Bucharest JUG #1 Guava Overview. Part 1 @ Bucharest JUG #1
Guava Overview. Part 1 @ Bucharest JUG #1
 
Lambdas puzzler - Peter Lawrey
Lambdas puzzler - Peter LawreyLambdas puzzler - Peter Lawrey
Lambdas puzzler - Peter Lawrey
 
Java concepts and questions
Java concepts and questionsJava concepts and questions
Java concepts and questions
 
Arrays and its properties IN SWIFT
Arrays and its properties IN SWIFTArrays and its properties IN SWIFT
Arrays and its properties IN SWIFT
 
New Functional Features of Java 8
New Functional Features of Java 8New Functional Features of Java 8
New Functional Features of Java 8
 
ScalaLanguage_ch_4_5.pptx
ScalaLanguage_ch_4_5.pptxScalaLanguage_ch_4_5.pptx
ScalaLanguage_ch_4_5.pptx
 
Scala ntnu
Scala ntnuScala ntnu
Scala ntnu
 
Java8: what's new and what's hot
Java8: what's new and what's hotJava8: what's new and what's hot
Java8: what's new and what's hot
 
JavaScript(Es5) Interview Questions & Answers
JavaScript(Es5)  Interview Questions & AnswersJavaScript(Es5)  Interview Questions & Answers
JavaScript(Es5) Interview Questions & Answers
 
Wien15 java8
Wien15 java8Wien15 java8
Wien15 java8
 

Último

Raspberry Pi 5: Challenges and Solutions in Bringing up an OpenGL/Vulkan Driv...
Raspberry Pi 5: Challenges and Solutions in Bringing up an OpenGL/Vulkan Driv...Raspberry Pi 5: Challenges and Solutions in Bringing up an OpenGL/Vulkan Driv...
Raspberry Pi 5: Challenges and Solutions in Bringing up an OpenGL/Vulkan Driv...Igalia
 
IAC 2024 - IA Fast Track to Search Focused AI Solutions
IAC 2024 - IA Fast Track to Search Focused AI SolutionsIAC 2024 - IA Fast Track to Search Focused AI Solutions
IAC 2024 - IA Fast Track to Search Focused AI SolutionsEnterprise Knowledge
 
Tata AIG General Insurance Company - Insurer Innovation Award 2024
Tata AIG General Insurance Company - Insurer Innovation Award 2024Tata AIG General Insurance Company - Insurer Innovation Award 2024
Tata AIG General Insurance Company - Insurer Innovation Award 2024The Digital Insurer
 
Automating Google Workspace (GWS) & more with Apps Script
Automating Google Workspace (GWS) & more with Apps ScriptAutomating Google Workspace (GWS) & more with Apps Script
Automating Google Workspace (GWS) & more with Apps Scriptwesley chun
 
08448380779 Call Girls In Friends Colony Women Seeking Men
08448380779 Call Girls In Friends Colony Women Seeking Men08448380779 Call Girls In Friends Colony Women Seeking Men
08448380779 Call Girls In Friends Colony Women Seeking MenDelhi Call girls
 
Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...
Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...
Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...Miguel Araújo
 
08448380779 Call Girls In Civil Lines Women Seeking Men
08448380779 Call Girls In Civil Lines Women Seeking Men08448380779 Call Girls In Civil Lines Women Seeking Men
08448380779 Call Girls In Civil Lines Women Seeking MenDelhi Call girls
 
08448380779 Call Girls In Greater Kailash - I Women Seeking Men
08448380779 Call Girls In Greater Kailash - I Women Seeking Men08448380779 Call Girls In Greater Kailash - I Women Seeking Men
08448380779 Call Girls In Greater Kailash - I Women Seeking MenDelhi Call girls
 
How to Troubleshoot Apps for the Modern Connected Worker
How to Troubleshoot Apps for the Modern Connected WorkerHow to Troubleshoot Apps for the Modern Connected Worker
How to Troubleshoot Apps for the Modern Connected WorkerThousandEyes
 
The Codex of Business Writing Software for Real-World Solutions 2.pptx
The Codex of Business Writing Software for Real-World Solutions 2.pptxThe Codex of Business Writing Software for Real-World Solutions 2.pptx
The Codex of Business Writing Software for Real-World Solutions 2.pptxMalak Abu Hammad
 
Factors to Consider When Choosing Accounts Payable Services Providers.pptx
Factors to Consider When Choosing Accounts Payable Services Providers.pptxFactors to Consider When Choosing Accounts Payable Services Providers.pptx
Factors to Consider When Choosing Accounts Payable Services Providers.pptxKatpro Technologies
 
08448380779 Call Girls In Diplomatic Enclave Women Seeking Men
08448380779 Call Girls In Diplomatic Enclave Women Seeking Men08448380779 Call Girls In Diplomatic Enclave Women Seeking Men
08448380779 Call Girls In Diplomatic Enclave Women Seeking MenDelhi Call girls
 
Driving Behavioral Change for Information Management through Data-Driven Gree...
Driving Behavioral Change for Information Management through Data-Driven Gree...Driving Behavioral Change for Information Management through Data-Driven Gree...
Driving Behavioral Change for Information Management through Data-Driven Gree...Enterprise Knowledge
 
Workshop - Best of Both Worlds_ Combine KG and Vector search for enhanced R...
Workshop - Best of Both Worlds_ Combine  KG and Vector search for  enhanced R...Workshop - Best of Both Worlds_ Combine  KG and Vector search for  enhanced R...
Workshop - Best of Both Worlds_ Combine KG and Vector search for enhanced R...Neo4j
 
Developing An App To Navigate The Roads of Brazil
Developing An App To Navigate The Roads of BrazilDeveloping An App To Navigate The Roads of Brazil
Developing An App To Navigate The Roads of BrazilV3cube
 
EIS-Webinar-Prompt-Knowledge-Eng-2024-04-08.pptx
EIS-Webinar-Prompt-Knowledge-Eng-2024-04-08.pptxEIS-Webinar-Prompt-Knowledge-Eng-2024-04-08.pptx
EIS-Webinar-Prompt-Knowledge-Eng-2024-04-08.pptxEarley Information Science
 
A Domino Admins Adventures (Engage 2024)
A Domino Admins Adventures (Engage 2024)A Domino Admins Adventures (Engage 2024)
A Domino Admins Adventures (Engage 2024)Gabriella Davis
 
The Role of Taxonomy and Ontology in Semantic Layers - Heather Hedden.pdf
The Role of Taxonomy and Ontology in Semantic Layers - Heather Hedden.pdfThe Role of Taxonomy and Ontology in Semantic Layers - Heather Hedden.pdf
The Role of Taxonomy and Ontology in Semantic Layers - Heather Hedden.pdfEnterprise Knowledge
 
Partners Life - Insurer Innovation Award 2024
Partners Life - Insurer Innovation Award 2024Partners Life - Insurer Innovation Award 2024
Partners Life - Insurer Innovation Award 2024The Digital Insurer
 
Finology Group – Insurtech Innovation Award 2024
Finology Group – Insurtech Innovation Award 2024Finology Group – Insurtech Innovation Award 2024
Finology Group – Insurtech Innovation Award 2024The Digital Insurer
 

Último (20)

Raspberry Pi 5: Challenges and Solutions in Bringing up an OpenGL/Vulkan Driv...
Raspberry Pi 5: Challenges and Solutions in Bringing up an OpenGL/Vulkan Driv...Raspberry Pi 5: Challenges and Solutions in Bringing up an OpenGL/Vulkan Driv...
Raspberry Pi 5: Challenges and Solutions in Bringing up an OpenGL/Vulkan Driv...
 
IAC 2024 - IA Fast Track to Search Focused AI Solutions
IAC 2024 - IA Fast Track to Search Focused AI SolutionsIAC 2024 - IA Fast Track to Search Focused AI Solutions
IAC 2024 - IA Fast Track to Search Focused AI Solutions
 
Tata AIG General Insurance Company - Insurer Innovation Award 2024
Tata AIG General Insurance Company - Insurer Innovation Award 2024Tata AIG General Insurance Company - Insurer Innovation Award 2024
Tata AIG General Insurance Company - Insurer Innovation Award 2024
 
Automating Google Workspace (GWS) & more with Apps Script
Automating Google Workspace (GWS) & more with Apps ScriptAutomating Google Workspace (GWS) & more with Apps Script
Automating Google Workspace (GWS) & more with Apps Script
 
08448380779 Call Girls In Friends Colony Women Seeking Men
08448380779 Call Girls In Friends Colony Women Seeking Men08448380779 Call Girls In Friends Colony Women Seeking Men
08448380779 Call Girls In Friends Colony Women Seeking Men
 
Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...
Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...
Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...
 
08448380779 Call Girls In Civil Lines Women Seeking Men
08448380779 Call Girls In Civil Lines Women Seeking Men08448380779 Call Girls In Civil Lines Women Seeking Men
08448380779 Call Girls In Civil Lines Women Seeking Men
 
08448380779 Call Girls In Greater Kailash - I Women Seeking Men
08448380779 Call Girls In Greater Kailash - I Women Seeking Men08448380779 Call Girls In Greater Kailash - I Women Seeking Men
08448380779 Call Girls In Greater Kailash - I Women Seeking Men
 
How to Troubleshoot Apps for the Modern Connected Worker
How to Troubleshoot Apps for the Modern Connected WorkerHow to Troubleshoot Apps for the Modern Connected Worker
How to Troubleshoot Apps for the Modern Connected Worker
 
The Codex of Business Writing Software for Real-World Solutions 2.pptx
The Codex of Business Writing Software for Real-World Solutions 2.pptxThe Codex of Business Writing Software for Real-World Solutions 2.pptx
The Codex of Business Writing Software for Real-World Solutions 2.pptx
 
Factors to Consider When Choosing Accounts Payable Services Providers.pptx
Factors to Consider When Choosing Accounts Payable Services Providers.pptxFactors to Consider When Choosing Accounts Payable Services Providers.pptx
Factors to Consider When Choosing Accounts Payable Services Providers.pptx
 
08448380779 Call Girls In Diplomatic Enclave Women Seeking Men
08448380779 Call Girls In Diplomatic Enclave Women Seeking Men08448380779 Call Girls In Diplomatic Enclave Women Seeking Men
08448380779 Call Girls In Diplomatic Enclave Women Seeking Men
 
Driving Behavioral Change for Information Management through Data-Driven Gree...
Driving Behavioral Change for Information Management through Data-Driven Gree...Driving Behavioral Change for Information Management through Data-Driven Gree...
Driving Behavioral Change for Information Management through Data-Driven Gree...
 
Workshop - Best of Both Worlds_ Combine KG and Vector search for enhanced R...
Workshop - Best of Both Worlds_ Combine  KG and Vector search for  enhanced R...Workshop - Best of Both Worlds_ Combine  KG and Vector search for  enhanced R...
Workshop - Best of Both Worlds_ Combine KG and Vector search for enhanced R...
 
Developing An App To Navigate The Roads of Brazil
Developing An App To Navigate The Roads of BrazilDeveloping An App To Navigate The Roads of Brazil
Developing An App To Navigate The Roads of Brazil
 
EIS-Webinar-Prompt-Knowledge-Eng-2024-04-08.pptx
EIS-Webinar-Prompt-Knowledge-Eng-2024-04-08.pptxEIS-Webinar-Prompt-Knowledge-Eng-2024-04-08.pptx
EIS-Webinar-Prompt-Knowledge-Eng-2024-04-08.pptx
 
A Domino Admins Adventures (Engage 2024)
A Domino Admins Adventures (Engage 2024)A Domino Admins Adventures (Engage 2024)
A Domino Admins Adventures (Engage 2024)
 
The Role of Taxonomy and Ontology in Semantic Layers - Heather Hedden.pdf
The Role of Taxonomy and Ontology in Semantic Layers - Heather Hedden.pdfThe Role of Taxonomy and Ontology in Semantic Layers - Heather Hedden.pdf
The Role of Taxonomy and Ontology in Semantic Layers - Heather Hedden.pdf
 
Partners Life - Insurer Innovation Award 2024
Partners Life - Insurer Innovation Award 2024Partners Life - Insurer Innovation Award 2024
Partners Life - Insurer Innovation Award 2024
 
Finology Group – Insurtech Innovation Award 2024
Finology Group – Insurtech Innovation Award 2024Finology Group – Insurtech Innovation Award 2024
Finology Group – Insurtech Innovation Award 2024
 

Simple Scala DSLs

  • 1. Simple Scala DSLs May 21, 2010 1
  • 3. A Definition A DSL is a custom way to represent logic designed to solve a specific problem. 2
  • 4. A Definition A DSL is a custom way to represent logic designed to solve a specific problem. I’m going to try and give you tools to stretch Scala’s syntax to match the way you think about the logic of your specific problem. 2
  • 5. Key Scala features • Syntactic sugar • Implicit methods • Options • Higher order functions 3
  • 6. Syntactic Sugar You can omit . and () for any method which takes a single parameter. map get “key” == map.get(“key”) 4
  • 7. Syntactic Sugar Methods whose names end in : bind to the right. “key” other: obj == obj.other:(“value”) val newList = item :: oldList val newList = oldList.::(item) 5
  • 8. Syntactic Sugar the apply() method a(b) == a.apply(b) map(“key”) == map.apply(“key”) 6
  • 9. Syntactic Sugar the update() method a(b) = c == a.update(b, c) a(b, c) = d == a.update(b, c, d) map(“key”) = “value” == map.update(“key”, “value”) 7
  • 10. Syntactic Sugar setters and getters object X { var y = 0 } object X { private var _z: Int = 0 def y = _z def y_=(i: Int) = _z = i } X.y => 0 X.y = 1 => Unit X.y => 1 8
  • 11. Syntactic Sugar tuples (a, b) == Tuple2[A,B](a, b) (a, b, c) == Tuple3[A,B,C](a, b, c) val (a, b) = sometuple // extracts 9
  • 12. Syntactic Sugar unapply() - used to extract values in pattern matching object Square { def unapply(p: Pair[Int, Int]) = p match { case (x, y) if x == y => Some(x) case _ => None } } (2, 2) match { case Square(side) => side*side case _ => -1 } 10
  • 13. Syntactic Sugar varargs - sugar for a variable length array def join(arr: String*) = arr.mkString(“,”) join(“a”) => “a” join(“a”, “b”) => “a,b” def join(arr: Array[String]) = arr.mkString(“,”) join(Array(“a”, “b”)) => “a,b” 11
  • 14. Syntactic Sugar unapplySeq() - an extractor that supports vararg matching object Join { def apply(l: String*) = l.mkString(“,”) def unapplySeq(s: String) = Some(s.split(“,”)) } Join(“1”, “2”, “3”) match { case Join(“1”, _*) => println(“starts w/1”) case _ => println(“doesn’t start w/1”) } 12
  • 16. Syntactic Sugar Case Classes are regular classes which export their constructor parameters and which provide a recursive decomposition mechanism via pattern matching. 13
  • 17. Syntactic Sugar Case Classes are regular classes which export their constructor parameters and which provide a recursive decomposition mechanism via pattern matching. case class Square(side: Int) 13
  • 18. Syntactic Sugar Case Classes are regular classes which export their constructor parameters and which provide a recursive decomposition mechanism via pattern matching. case class Square(side: Int) val s = Square(2) // apply() is defined 13
  • 19. Syntactic Sugar Case Classes are regular classes which export their constructor parameters and which provide a recursive decomposition mechanism via pattern matching. case class Square(side: Int) val s = Square(2) // apply() is defined s.side => 2 // member is exported 13
  • 20. Syntactic Sugar Case Classes are regular classes which export their constructor parameters and which provide a recursive decomposition mechanism via pattern matching. case class Square(side: Int) val s = Square(2) // apply() is defined s.side => 2 // member is exported val Square(x) = s // unapply() is defined 13
  • 21. Syntactic Sugar Case Classes are regular classes which export their constructor parameters and which provide a recursive decomposition mechanism via pattern matching. case class Square(side: Int) val s = Square(2) // apply() is defined s.side => 2 // member is exported val Square(x) = s // unapply() is defined s.toString ==> “Square(2)” 13
  • 22. Syntactic Sugar Case Classes are regular classes which export their constructor parameters and which provide a recursive decomposition mechanism via pattern matching. case class Square(side: Int) val s = Square(2) // apply() is defined s.side => 2 // member is exported val Square(x) = s // unapply() is defined s.toString ==> “Square(2)” s.hashCode ==> 630363263 13
  • 23. Syntactic Sugar Case Classes are regular classes which export their constructor parameters and which provide a recursive decomposition mechanism via pattern matching. case class Square(side: Int) val s = Square(2) // apply() is defined s.side => 2 // member is exported val Square(x) = s // unapply() is defined s.toString ==> “Square(2)” s.hashCode ==> 630363263 s == Square(2) ==> true 13
  • 25. Syntactic Sugar Many classes can be used in for comprehensions because they implement some combination of: map[B](f: (A) => B): Option[B] flatMap[B](f: (A) => Option[B]): Option[B] filter(p: (A) => Boolean): Option[A] foreach(f: (A) => Unit): Unit 14
  • 26. Syntactic Sugar Many classes can be used in for comprehensions because they implement some combination of: map[B](f: (A) => B): Option[B] flatMap[B](f: (A) => Option[B]): Option[B] filter(p: (A) => Boolean): Option[A] foreach(f: (A) => Unit): Unit for { i <- List(1,2,3) val x = i * 3 if x % 2 == 0 } yield x ==> List(6) List(1,2,3).map(_ * 3).filter(_ % 2 == 0) ==> List(6) 14
  • 27. Implicit Methods Implicit methods are a compromise between the closed approach to extension of Java and the open approach to extension in Ruby. Implicit Methods are: 15
  • 28. Implicit Methods Implicit methods are a compromise between the closed approach to extension of Java and the open approach to extension in Ruby. Implicit Methods are: • lexically scoped / non-global 15
  • 29. Implicit Methods Implicit methods are a compromise between the closed approach to extension of Java and the open approach to extension in Ruby. Implicit Methods are: • lexically scoped / non-global • statically typed 15
  • 30. Implicit Methods Implicit methods are inserted by the compiler under the following rules: 16
  • 31. Implicit Methods Implicit methods are inserted by the compiler under the following rules: • they are in scope 16
  • 32. Implicit Methods Implicit methods are inserted by the compiler under the following rules: • they are in scope • the selection is unambiguous 16
  • 33. Implicit Methods Implicit methods are inserted by the compiler under the following rules: • they are in scope • the selection is unambiguous • it is not already in an implicit i.e. no nesting 16
  • 34. Implicit Methods Implicit methods are inserted by the compiler under the following rules: • they are in scope • the selection is unambiguous • it is not already in an implicit i.e. no nesting • the code does not compile as written 16
  • 35. Implicit Methods: Usage Extending Abstractions: Java class IntWrapper(int i) { int timesTen() { return i * 10; } } int i = 2; new IntWrapper(i).timesTen(); 17
  • 36. Implicit Methods: Usage Extending Abstractions: Java Java’s abstractions are totally sealed and we must use explicit wrapping each time we wish to extend them. Pros: safe Cons: repetitive boilerplate at each call site 18
  • 37. Implicit Methods: Usage Extending Abstractions: Ruby class Int def timesTen self * 10 end end i = 2 i.timesTen 19
  • 38. Implicit Methods: Usage Extending Abstractions: Ruby Ruby’s abstractions are totally open. We can modify the behavior of existing classes and objects in pretty much any way we want. Pros: declarative, powerful and flexible Cons: easily abused and can be extremely difficult to debug 20
  • 39. Implicit Methods: Usage Extending Abstractions: Scala class IntWrapper(i: Int) { def timesTen = i * 10 } implicit def wrapint(i: Int) = new IntWrapper(i) val i = 2 i.timesTen 21
  • 40. Implicit Methods: Usage Extending Abstractions: Scala Scala’s approach is both powerful and safe. While it is certainly possible to abuse, it naturally encourages a safer approach through lexical scoping. Pros: more powerful than java, safer than ruby Cons: can result in unexpected behavior if not tightly scoped 22
  • 41. Implicit Methods: Usage Normalizing parameters def remainder[T <: Double](num: T): Double = num - num.floor 23
  • 42. Implicit Methods: Usage Normalizing parameters def remainder[T <: Double](num: T): Double = num - num.floor remainder(.4) ==> 0 23
  • 43. Implicit Methods: Usage Normalizing parameters def remainder[T <: Double](num: T): Double = num - num.floor remainder(.4) ==> 0 remainder(1.2) ==> 1.2 23
  • 44. Implicit Methods: Usage Normalizing parameters def remainder[T <: Double](num: T): Double = num - num.floor remainder(.4) ==> 0 remainder(1.2) ==> 1.2 remainder(120d) ==> 0 23
  • 46. Implicit Methods: Usage Normalizing parameters remainder(120) ==> error: inferred type arguments [Int] do not conform to method remainder's type parameter bounds [T <: Double] 24
  • 47. Implicit Methods: Usage Normalizing parameters remainder(120) ==> error: inferred type arguments [Int] do not conform to method remainder's type parameter bounds [T <: Double] implicit def i2d(i: Int): Double = i.toDouble 24
  • 48. Implicit Methods: Usage Normalizing parameters remainder(120) ==> error: inferred type arguments [Int] do not conform to method remainder's type parameter bounds [T <: Double] implicit def i2d(i: Int): Double = i.toDouble remainder(120) ==> 0 24
  • 49. Options Options are scala’s answer to null. Options are a very simple, 3-part class hierarchy: 25
  • 50. Options Options are scala’s answer to null. Options are a very simple, 3-part class hierarchy: • sealed abstract class Option[+A] extends Product 25
  • 51. Options Options are scala’s answer to null. Options are a very simple, 3-part class hierarchy: • sealed abstract class Option[+A] extends Product • case final class Some[+A](val x : A) extends Option[A] 25
  • 52. Options Options are scala’s answer to null. Options are a very simple, 3-part class hierarchy: • sealed abstract class Option[+A] extends Product • case final class Some[+A](val x : A) extends Option[A] • case object None extends Option[Nothing] 25
  • 53. Options: Common Methods def get: A Some(1).get ==> 1 None.get ==> java.util.NoSuchElementException! 26
  • 54. Options: Common Methods def getOrElse[B >: A](default: => B): B Some(1).getOrElse(2) ==> 1 None.getOrElse(2) ==> 2 27
  • 55. Options: Common Methods def map[B](f: (A) => B): Option[B] Some(1).map(_.toString) ==> Some(“1”) None.map(_.toString) ==> None 28
  • 56. Options: Usage Replacing Null Checks A (contrived) Java example: int result = -1; int x = calcX(); if (x != null) { int y = calcY(); if (y != null) { result = x * y; } } 29
  • 57. Options: Usage Replacing Null Checks def calcX: Option[Int] def calcY: Option[Int] for { val x <- Some(3) val y <- Some(2) } yield x * y ==> Some(6) 30
  • 58. Options: Usage Replacing Null Checks for { val x <- None val y <- Some(2) } yield x * y ==> None 31
  • 59. Options: Usage Replacing Null Checks (for { val x <- None val y <- Some(2) } yield x * y).getOrElse(-1) ==> -1 32
  • 60. Options: Usage Replacing Null Checks (for { val x <- Some(3) val y <- Some(2) } yield x * y).getOrElse(-1) ==> 6 33
  • 61. Options: Usage Safely Transforming Values val x: Option[Int] = calcOptionalX() def xform(i: Int): Int 34
  • 62. Options: Usage Safely Transforming Values val x: Option[Int] = calcOptionalX() def xform(i: Int): Int (x map xform) getOrElse -1 34
  • 63. Options: Usage Safely Transforming Values val x: Option[Int] = calcOptionalX() def xform(i: Int): Int (x map xform) getOrElse -1 (for (i <- x) yield xform(i)).getOrElse(-1) 34
  • 65. Implicits + Options val m = Map(“1” -> 1,“map” -> Map(“2” -> 2)) 35
  • 66. Implicits + Options val m = Map(“1” -> 1,“map” -> Map(“2” -> 2)) We’d like to be able to access the map like this: m/”key1”/”key2”/”key3” 35
  • 67. Implicits + Options val m = Map(“1” -> 1,“map” -> Map(“2” -> 2)) We’d like to be able to access the map like this: m/”key1”/”key2”/”key3” But, we’d like to not have to constantly check nulls or Options. 35
  • 68. Implicits + Options class MapWrapper(map: Map[String, Any]) { def /(s: String): Option[Any] = map.get(s) } implicit def a2mw(a: Any) = new MapWrapper(a.asInstanceOf[Map[String, Any]]) 36
  • 69. Implicits + Options class MapWrapper(map: Map[String, Any]) { def /(s: String): Option[Any] = map.get(s) } implicit def a2mw(a: Any) = new MapWrapper(a.asInstanceOf[Map[String, Any]]) m/”a” ==> None 36
  • 70. Implicits + Options class MapWrapper(map: Map[String, Any]) { def /(s: String): Option[Any] = map.get(s) } implicit def a2mw(a: Any) = new MapWrapper(a.asInstanceOf[Map[String, Any]]) m/”a” ==> None m/”1” ==> Some(1) 36
  • 71. Implicits + Options class MapWrapper(map: Map[String, Any]) { def /(s: String): Option[Any] = map.get(s) } implicit def a2mw(a: Any) = new MapWrapper(a.asInstanceOf[Map[String, Any]]) m/”a” ==> None m/”1” ==> Some(1) m/”map”/”2” ==> ClassCastException! 36
  • 72. Implicits + Options class OptionMapWrapper( o: Option[MapWrapper]) { def /(s: String) = o match { case Some(mw) => mw/s case _ => None } } implicit def o2omw(o: Option[Any]) = new OptionMapWrapper(o map a2mw) 37
  • 73. Implicits + Options class OptionMapWrapper( o: Option[MapWrapper]) { def /(s: String) = o match { case Some(mw) => mw/s case _ => None } } implicit def o2omw(o: Option[Any]) = new OptionMapWrapper(o map a2mw) m/”map”/”2” ==> Some(2) 37
  • 74. Implicits + Options class OptionMapWrapper( o: Option[MapWrapper]) { def /(s: String) = o match { case Some(mw) => mw/s case _ => None } } implicit def o2omw(o: Option[Any]) = new OptionMapWrapper(o map a2mw) m/”map”/”2” ==> Some(2) m/”map”/”next”/”blah” ==> None 37
  • 75. Higher Order Functions Higher order functions are functions that: • take functions as parameters AND / OR • result in a function 38
  • 77. Higher Order Functions Let’s say we’d like to write a little system for easily running statements asynchronously via either threads or actors. 39
  • 78. Higher Order Functions Let’s say we’d like to write a little system for easily running statements asynchronously via either threads or actors. What we’d like to get to: run (println(“hello”)) using threads run (println(“hello”)) using actors 39
  • 79. Higher Order Functions trait RunCtx { def run(f: => Unit): Unit } class Runner(f: => Unit) { def using(ctx: RunCtx) = ctx run f } def run(f: => Unit) = new Runner(f) 40
  • 80. Higher Order Functions object actors extends RunCtx { def run(f: => Unit) = scala.actors.Actor.actor(f) } object threads extends RunCtx { def run(f: => Unit) = { object t extends Thread { override def run = f } t.start } } 41
  • 81. Thank You! email: lincoln@hotpotato.com twitter: 11nc hotpotato: lincoln Questions? 42

Notas del editor