KEMBAR78
A bit about Scala | PDF
НЕМНОГО О SCALA
     Владимир Парфиненко
  vladimir.parfinenko@gmail.com
              @cypok
NEW

       SCALA
       Martin Odersky
 разрабатывал Scala с 2001
 года в École Polytechnique
   Fédérale de Lausanne,
релиз состоялся в 2003 году.
ПОПУЛЯРНОСТЬ

• 11
   место – RedMonk Programming Language Rankings,
 популярность на Stack Overflow и GitHub

• 36   место – TIOBE index, популярность поисковых запросов
ИДЕИ SCALA


• Безопасность   и эффективность

• Гибкость   языка, мощный синтаксис

• Объектно-ориентированность

• Функциональность
БЕЗОПАСНОСТЬ И ЭФФЕКТИВНОСТЬ
HELLO WORLD!

$ cat > HelloWorld.scala
object HelloWorld extends App {
  println("Hello, world!")
}

$ scalac HelloWorld.scala

$ scala HelloWorld
Hello, world!
STATIC TYPING

var i = 37
i = 42
i = "Foo" // error: type mismatch;
           // found   : java.lang.String("Foo")
           // required: Int
ГИБКОСТЬ ЯЗЫКА, МОЩНЫЙ СИНТАКСИС
HELLO REPL!

scala> val repl = Map('R' -> "Read", 'E' -> "Eval",
     |                'P' -> "Print", 'L' -> "Loop")

scala> for ((k, v) <- repl) println(k + " is for " + v)
R is for Read
E is for Eval
P is for Print
L is for Loop
DSL

class DominatorsSuite extends FunSuite with ShouldMatchers
                          with GraphBuilderDSL {
  test("diamond") {
    calcDominatorsOver(0 -> (1 || 2) -> 3)
    idom(1) should be (0)
    idom(2) should be (0)                        0
    idom(3) should be (0)
  }
}
                                             1       2


                                                 3
ОБЪЕКТНО-ОРИЕНТИРОВАННОСТЬ
BACK TO THE JAVA
// Person.java
public class Person {
    public final String name;
    public final int age;

    public Person(String name, int age) {
        this.name = name;
        this.age = age;
    }
}

// Mainstreamless.scala
object Mainstreamless extends App {
  val p = new Person("John", 20)
  println(p.name + " is " + p.age + " years old")
}
SCALA STRIKES BACK
class Person(val name: String, val age: Int)




object Mainstreamless extends App {
  val p = new Person("John", 20)
  println(p.name + " is " + p.age + " years old")
}
OOP: CLASSES
abstract class Animal {
  def name: String
}

class Person(firstName: String, lastName: String)
    extends Animal {
  val name = firstName + " " + lastName
}

class Student(firstName: String, lastName: String, val year: Int)
    extends Person(firstName, lastName)
OOP: TRAITS
trait Ordered[A] {
  def compare(that: A): Int

    def   < (that: A): Boolean =    (this compare that)   <    0
    def   > (that: A): Boolean =    (this compare that)   >    0
    def   <= (that: A): Boolean =   (this compare that)   <=   0
    def   >= (that: A): Boolean =   (this compare that)   >=   0
    def   compareTo(that: A): Int   = compare(that)
}

class Money extends Ordered[Money] with SomeOtherTrait {
  def compare(that: Money) = ...
}
OOP: TYPES
class Duck {
  def quack = println("Quaaaaaack!")
  def feathers = println("The duck has white and gray feathers.")
}

class Person {
  def quack = println("The person imitates a duck.")
  def feathers = println("The person takes a feather
                          from the ground and shows it.")
}

def inTheForest(duck: { def quack; def feathers }) = {
  duck.quack
  duck.feathers
}
OOP: TYPES
scala> inTheForest(new Duck)
Quaaaaaack!
The duck has white and gray feathers.

scala> inTheForest(new Person)
The person imitates a duck.
The person takes a feather from the ground and shows it.



scala> inTheForest("Duck")
error: type mismatch;
 found   : java.lang.String("Duck")
 required: AnyRef{def quack: Unit; def feathers: Unit}
       inTheForest("Duck")
λ
ФУНКЦИОНАЛЬНОСТЬ
FUNCTIONS
def inc(x: Int): Int = {
  x + 1
}

def inc(x: Int) = x + 1

val inc = { x: Int => x + 1 }



inc(3) // 4

Seq(1, 2, 3) map inc // Seq(2, 3, 4)

// 1 + 2 + 3
Seq(1, 2, 3) reduce { x, y => x + y }
Seq(1, 2, 3) reduce { _ + _ }
SCALA COLLECTIONS

• Seq
                              TraversableOnce
  • IndexedSeq, Buffer, …
                            Iterator    Traversable
• Set
                                         Iterable
  • HashSet, BitSet, …
                                  Seq      Set        Map
• Map

  • HashMap, TreeMap, …
SCALA COLLECTIONS

• collect        • fold      • partition

• count          • forall    • reduce

• exists         • foreach   • splitAt

• filter          • groupBy   • take

• find            • map       • to

• flatMap         • max/min   •…
DEMO
        import java.util.ArrayList;
        // ...
        Person[] people, minors, adults;
        void foo() {
            ArrayList<Person> minorsList = new ArrayList<Person>();
Java




            ArrayList<Person> adultsList = new ArrayList<Person>();
            for (Person person : people)
                (person.age < 18 ? minorsList : adultsList).
                     add(person);
            minors = minorsList.toArray(new Person[minorsList.size()]);
            adults = adultsList.toArray(new Person[adultsList.size()]);
        }
Scala




        val people: Array[Person]
        val (minors, adults) = people partition { _.age < 18 }
PATTERN MATCHING


    val str = num match {
      case 1 => "one"
      case 2 => "two"
      case _ => "many"
    }
PATTERN MATCHING


val str = anything match {
  case x: Int if x > 0 => "positive integer"
  case x: Float if x > 0 => "positive real"
  case _: String => "string"
  case _ => "unknown"
}
CASE CLASSES
sealed class Element

case   class   Var(name: String) extends Element
case   class   Num(value: Int) extends Element
case   class   Neg(arg: Element) extends Element
case   class   Add(arg1: Element, arg2: Element) extends Element

def optimize(elem: Element): Element = elem match {
  case Neg(Neg(x))              => optimize(x)
  case Add(x, Num(0))           => optimize(x)
  case Neg(Num(x))              => Num(-x)
  case Add(x, Neg(y)) if x == y => Num(0)
  case Add(Num(x), Num(y))      => Num(x + y)
  case Neg(x)                   => Neg(optimize(x))
  case Add(x, y)                => Add(optimize(x), optimize(y))
  case _                        => elem
}
One more thing...
BONUS: FUNCTIONAL


 def modN(n: Int)(x: Int) = ((x % n) == 0)

 val nums = Seq(1, 2, 3, 4, 5, 6, 7, 8)

 nums filter modN(2) // Seq(2, 4, 6, 8)
 nums filter modN(3) // Seq(3, 6)
BONUS: CONCURRENCY


actor {
  receive {
    case people: Set[Person] =>
      val (minors, adults) = people partition { _.age < 18 }
      School ! minors
      Work ! adults
  }
}
BONUS: PARALLELISM


val people: Array[Person]

val (minors, adults) = people partition { _.age < 18 }

val (minors, adults) = people.par partition { _.age < 18 }




                                     ag ic!
                                    M
BONUS: FUTURES
val f: Future[List[String]] = future {
  session.getRecentPosts
}

f onFailure {
  case t => println("An error has occured: " + t.getMessage)
}

f onSuccess {
  case posts => posts foreach println
}
ЗАДАЧКА

val expr = Div(Add(Var("a"), Num(37)), Num(2))
expr.draw()



                  a + 37
                  ------
                    2
РЕСУРСЫ

• http://github.com/cypok/mainstreamless        – условие задачи

• http://www.scala-lang.org

• http://docs.scala-lang.org   – guides & tutorials

• Programming    in Scala: Second Edition – good book

• http://scala-ide.org   – Scala IDE for Eclipse

• http://plugins.intellij.net/plugin/?id=1347   – IntelliJ IDEA plugin

A bit about Scala

  • 1.
    НЕМНОГО О SCALA Владимир Парфиненко vladimir.parfinenko@gmail.com @cypok
  • 2.
    NEW SCALA Martin Odersky разрабатывал Scala с 2001 года в École Polytechnique Fédérale de Lausanne, релиз состоялся в 2003 году.
  • 3.
    ПОПУЛЯРНОСТЬ • 11 место – RedMonk Programming Language Rankings, популярность на Stack Overflow и GitHub • 36 место – TIOBE index, популярность поисковых запросов
  • 4.
    ИДЕИ SCALA • Безопасность и эффективность • Гибкость языка, мощный синтаксис • Объектно-ориентированность • Функциональность
  • 5.
  • 6.
    HELLO WORLD! $ cat> HelloWorld.scala object HelloWorld extends App { println("Hello, world!") } $ scalac HelloWorld.scala $ scala HelloWorld Hello, world!
  • 7.
    STATIC TYPING var i= 37 i = 42 i = "Foo" // error: type mismatch; // found : java.lang.String("Foo") // required: Int
  • 8.
  • 9.
    HELLO REPL! scala> valrepl = Map('R' -> "Read", 'E' -> "Eval", | 'P' -> "Print", 'L' -> "Loop") scala> for ((k, v) <- repl) println(k + " is for " + v) R is for Read E is for Eval P is for Print L is for Loop
  • 10.
    DSL class DominatorsSuite extendsFunSuite with ShouldMatchers with GraphBuilderDSL { test("diamond") { calcDominatorsOver(0 -> (1 || 2) -> 3) idom(1) should be (0) idom(2) should be (0) 0 idom(3) should be (0) } } 1 2 3
  • 11.
  • 12.
    BACK TO THEJAVA // Person.java public class Person { public final String name; public final int age; public Person(String name, int age) { this.name = name; this.age = age; } } // Mainstreamless.scala object Mainstreamless extends App { val p = new Person("John", 20) println(p.name + " is " + p.age + " years old") }
  • 13.
    SCALA STRIKES BACK classPerson(val name: String, val age: Int) object Mainstreamless extends App { val p = new Person("John", 20) println(p.name + " is " + p.age + " years old") }
  • 14.
    OOP: CLASSES abstract classAnimal { def name: String } class Person(firstName: String, lastName: String) extends Animal { val name = firstName + " " + lastName } class Student(firstName: String, lastName: String, val year: Int) extends Person(firstName, lastName)
  • 15.
    OOP: TRAITS trait Ordered[A]{ def compare(that: A): Int def < (that: A): Boolean = (this compare that) < 0 def > (that: A): Boolean = (this compare that) > 0 def <= (that: A): Boolean = (this compare that) <= 0 def >= (that: A): Boolean = (this compare that) >= 0 def compareTo(that: A): Int = compare(that) } class Money extends Ordered[Money] with SomeOtherTrait { def compare(that: Money) = ... }
  • 16.
    OOP: TYPES class Duck{ def quack = println("Quaaaaaack!") def feathers = println("The duck has white and gray feathers.") } class Person { def quack = println("The person imitates a duck.") def feathers = println("The person takes a feather from the ground and shows it.") } def inTheForest(duck: { def quack; def feathers }) = { duck.quack duck.feathers }
  • 17.
    OOP: TYPES scala> inTheForest(newDuck) Quaaaaaack! The duck has white and gray feathers. scala> inTheForest(new Person) The person imitates a duck. The person takes a feather from the ground and shows it. scala> inTheForest("Duck") error: type mismatch; found : java.lang.String("Duck") required: AnyRef{def quack: Unit; def feathers: Unit} inTheForest("Duck")
  • 18.
  • 19.
    FUNCTIONS def inc(x: Int):Int = { x + 1 } def inc(x: Int) = x + 1 val inc = { x: Int => x + 1 } inc(3) // 4 Seq(1, 2, 3) map inc // Seq(2, 3, 4) // 1 + 2 + 3 Seq(1, 2, 3) reduce { x, y => x + y } Seq(1, 2, 3) reduce { _ + _ }
  • 20.
    SCALA COLLECTIONS • Seq TraversableOnce • IndexedSeq, Buffer, … Iterator Traversable • Set Iterable • HashSet, BitSet, … Seq Set Map • Map • HashMap, TreeMap, …
  • 21.
    SCALA COLLECTIONS • collect • fold • partition • count • forall • reduce • exists • foreach • splitAt • filter • groupBy • take • find • map • to • flatMap • max/min •…
  • 22.
    DEMO import java.util.ArrayList; // ... Person[] people, minors, adults; void foo() { ArrayList<Person> minorsList = new ArrayList<Person>(); Java ArrayList<Person> adultsList = new ArrayList<Person>(); for (Person person : people) (person.age < 18 ? minorsList : adultsList). add(person); minors = minorsList.toArray(new Person[minorsList.size()]); adults = adultsList.toArray(new Person[adultsList.size()]); } Scala val people: Array[Person] val (minors, adults) = people partition { _.age < 18 }
  • 23.
    PATTERN MATCHING val str = num match { case 1 => "one" case 2 => "two" case _ => "many" }
  • 24.
    PATTERN MATCHING val str= anything match { case x: Int if x > 0 => "positive integer" case x: Float if x > 0 => "positive real" case _: String => "string" case _ => "unknown" }
  • 25.
    CASE CLASSES sealed classElement case class Var(name: String) extends Element case class Num(value: Int) extends Element case class Neg(arg: Element) extends Element case class Add(arg1: Element, arg2: Element) extends Element def optimize(elem: Element): Element = elem match { case Neg(Neg(x)) => optimize(x) case Add(x, Num(0)) => optimize(x) case Neg(Num(x)) => Num(-x) case Add(x, Neg(y)) if x == y => Num(0) case Add(Num(x), Num(y)) => Num(x + y) case Neg(x) => Neg(optimize(x)) case Add(x, y) => Add(optimize(x), optimize(y)) case _ => elem }
  • 26.
  • 27.
    BONUS: FUNCTIONAL defmodN(n: Int)(x: Int) = ((x % n) == 0) val nums = Seq(1, 2, 3, 4, 5, 6, 7, 8) nums filter modN(2) // Seq(2, 4, 6, 8) nums filter modN(3) // Seq(3, 6)
  • 28.
    BONUS: CONCURRENCY actor { receive { case people: Set[Person] => val (minors, adults) = people partition { _.age < 18 } School ! minors Work ! adults } }
  • 29.
    BONUS: PARALLELISM val people:Array[Person] val (minors, adults) = people partition { _.age < 18 } val (minors, adults) = people.par partition { _.age < 18 } ag ic! M
  • 30.
    BONUS: FUTURES val f:Future[List[String]] = future { session.getRecentPosts } f onFailure { case t => println("An error has occured: " + t.getMessage) } f onSuccess { case posts => posts foreach println }
  • 31.
    ЗАДАЧКА val expr =Div(Add(Var("a"), Num(37)), Num(2)) expr.draw() a + 37 ------ 2
  • 32.
    РЕСУРСЫ • http://github.com/cypok/mainstreamless – условие задачи • http://www.scala-lang.org • http://docs.scala-lang.org – guides & tutorials • Programming in Scala: Second Edition – good book • http://scala-ide.org – Scala IDE for Eclipse • http://plugins.intellij.net/plugin/?id=1347 – IntelliJ IDEA plugin