SlideShare ist ein Scribd-Unternehmen logo
1 von 332
Downloaden Sie, um offline zu lesen
꽃보다
Scala !
김상범 | @taokim
“
만약, 2003년경에 누군가 나에게
  Programming in Scala
    라는 책을 보여줬다면
 나는 절대로 Groovy를 만들지
       않았을 것이다


                                            ”
    James Strachan, the creator of Groovy
TOC


1. Scala?

2. Functional Style

3. Pattern Matching

4. Horizontal Scale
Scala?
Scala?




object HelloWorld {
  def main(args:Array[String]){
    println("Hello, world!")
  }
}
Scala?
Scala?


Quick Scala Facts
Scala?


       Quick Scala Facts
JVM/.NET 에서 구동되는 범용 multi-paradigm 언
어
Scala?


        Quick Scala Facts
JVM/.NET 에서 구동되는 범용 multi-paradigm 언
어
Created by Martin Odersky
Scala?


                Quick Scala Facts
    JVM/.NET 에서 구동되는 범용 multi-paradigm 언
    어
    Created by Martin Odersky
✓   EPFL 의 교수
Scala?


                 Quick Scala Facts
    JVM/.NET 에서 구동되는 범용 multi-paradigm 언
    어
    Created by Martin Odersky
✓   EPFL 의 교수

✓   javac(Sun’s java compiler)
Scala?


                 Quick Scala Facts
    JVM/.NET 에서 구동되는 범용 multi-paradigm 언
    어
    Created by Martin Odersky
✓   EPFL 의 교수

✓   javac(Sun’s java compiler)

✓   Generic Java (“make Java better”)
Scala?


                 Quick Scala Facts
    JVM/.NET 에서 구동되는 범용 multi-paradigm 언
    어
    Created by Martin Odersky
✓   EPFL 의 교수

✓   javac(Sun’s java compiler)

✓   Generic Java (“make Java better”)

✓   Since 2001
Scala?


                    Quick Scala Facts
    JVM/.NET 에서 구동되는 범용 multi-paradigm 언
    어
    Created by Martin Odersky
✓   EPFL 의 교수

✓   javac(Sun’s java compiler)

✓   Generic Java (“make Java better”)

✓   Since 2001
    => 최신 안정화 버전 : 2.9.2 final (2012/04/14)
Scala?


                    Quick Scala Facts
    JVM/.NET 에서 구동되는 범용 multi-paradigm 언
    어
    Created by Martin Odersky
✓   EPFL 의 교수

✓   javac(Sun’s java compiler)

✓   Generic Java (“make Java better”)

✓   Since 2001
    => 최신 안정화 버전 : 2.9.2 final (2012/04/14)

    => 개발 버전 : 2.10.0 RC1 (2012/10/19)
Scala?
Scala?


Quick Scala Facts
Scala?


       Quick Scala Facts
더 짧고 더 명료한 코드
Scala?


       Quick Scala Facts
더 짧고 더 명료한 코드
강력한 표현력과 DSL을 통한 확장성
Scala?


       Quick Scala Facts
더 짧고 더 명료한 코드
강력한 표현력과 DSL을 통한 확장성
Java 와의 상호 운영성
Scala?


       Quick Scala Facts
더 짧고 더 명료한 코드
강력한 표현력과 DSL을 통한 확장성
Java 와의 상호 운영성
강력한 정적 타입 시스템
Scala?


       Quick Scala Facts
더 짧고 더 명료한 코드
강력한 표현력과 DSL을 통한 확장성
Java 와의 상호 운영성
강력한 정적 타입 시스템
객체 지향과 함수형 스타일을 모두 지원
Scala?


       Quick Scala Facts
더 짧고 더 명료한 코드
강력한 표현력과 DSL을 통한 확장성
Java 와의 상호 운영성
강력한 정적 타입 시스템
객체 지향과 함수형 스타일을 모두 지원
동일한 목적의 자바 코드와 동일한 성능
Scala?


       Quick Scala Facts
더 짧고 더 명료한 코드
강력한 표현력과 DSL을 통한 확장성
Java 와의 상호 운영성
강력한 정적 타입 시스템
객체 지향과 함수형 스타일을 모두 지원
동일한 목적의 자바 코드와 동일한 성능
광범위한 상업적 적용
Scala?


       Quick Scala Facts
더 짧고 더 명료한 코드
강력한 표현력과 DSL을 통한 확장성
Java 와의 상호 운영성
강력한 정적 타입 시스템
객체 지향과 함수형 스타일을 모두 지원
동일한 목적의 자바 코드와 동일한 성능
광범위한 상업적 적용
강력한 동시성 처리
Scala?


                Less code
 표현의 간결함
 자바에 비해 코드 사이즈가 1/3 ~2/3 정도로 감소함
 절반의 코드는
✓ 코드를 이해하는데 절반의 시간이 필요함을 뜻하며
✓ 버그의 가능성 역시 절반으로 감소함
A class...




                                            class Person(val name: String, val age: Int)
class Person {
 public final String name;
 public final int age;

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




class Person {
 private final String name;                                                       case class Person(name: String,
 private final int age;
                                                                                  age: Int)
    public Person(String name, int age) {
      super();
      this.name = name;
      this.age = age;
    }

    public String getName() {
      return name;
    }

    public int getAge() {
      return age;
    }

    @Override
    public boolean equals(Object other) {
     if (this == other) {
       return true;
     } else if (other instanceof Person) {
       Person p = (Person) other;
       return name == null ? p.name == null : name.equals(p.name)
          && age == p.age;

        } else {
          return false;
        }
    }

    @Override
    public int hashCode() {
      int h = name == null ? 0 : name.hashCode();
      return 39 * h + age;
    }

    @Override
    public String toString() {
      return new StringBuilder("Person(").append(name).append(",").append(age)
         .append(")").toString();
    }
}
[H3 2012] 꽃보다 Scala
Scala?
Scala?


Great interoperability with Java
Scala?


Great interoperability with Java
Scala는 자바와 소스 코드 레벨에서만 다름
Scala?


Great interoperability with Java
Scala는 자바와 소스 코드 레벨에서만 다름
컴파일되면 “.class” 파일이 나옴
Scala?


Great interoperability with Java
Scala는 자바와 소스 코드 레벨에서만 다름
컴파일되면 “.class” 파일이 나옴
Scala코드에서 Java클래스를 그대로 import 해서 사용
Scala?


Great interoperability with Java
Scala는 자바와 소스 코드 레벨에서만 다름
컴파일되면 “.class” 파일이 나옴
Scala코드에서 Java클래스를 그대로 import 해서 사용
한 프로젝트에서 Java와 Scala 파일을 섞어서 사용 가능
Scala?


Great interoperability with Java
Scala는 자바와 소스 코드 레벨에서만 다름
컴파일되면 “.class” 파일이 나옴
Scala코드에서 Java클래스를 그대로 import 해서 사용
한 프로젝트에서 Java와 Scala 파일을 섞어서 사용 가능
Java 가 지원되는 어떤 환경/클라우드에도 배포 가능
Scala?


Great interoperability with Java
Scala는 자바와 소스 코드 레벨에서만 다름
컴파일되면 “.class” 파일이 나옴
Scala코드에서 Java클래스를 그대로 import 해서 사용
한 프로젝트에서 Java와 Scala 파일을 섞어서 사용 가능
Java 가 지원되는 어떤 환경/클라우드에도 배포 가능
그리고 Android ~
Great interoperability with Java




import java.net._
import java.io._

val u = new URL(
  "http://www.scala-lang.org/")
val in = u.openStream()
val br = new BufferedReader(
  new InputStreamReader(in))
Popularity and Use Grow


                 Commercial Adoptions
   Twitter
✓ 메시지 패싱 시스템을 Ruby에서 Scala 기반으로 변경
✓ Finagle, Gizzard, Kestrel, ...

   Linked-in
✓ 소셜 그래프 서비스 (380-400M transaction/day)
✓ Apache Kafka

   Foursquare
✓ 웹을 포함한 모든 서비스가 Scala로 작성됨

   Tumblr
✓ 분산 시스템을 위해 Finagle 선택
Programming Language Popularity
                                                                    1    JavaScript

                                                                    2       Java

                                                                    3       PHP

                                                                    4      Python

                                                                    5       Ruby

                                                                    6        C#

                                                                    7       C++

                                                                    8        C

                                                                    9   Objective-C

                                                                10         Shell

                                                                11          Perl

                                                                12         Scala

                                                                13        Haskell

                                                                14          ASP

                                                                15        Assembly

                                                                16      ActionScript

                                                                17           R

                                                                18      VisualBasic

                                                                19      CoffeeScript

                                                                20         Groovy



출처: http://redmonk.com/sogrady/2012/09/12/language-rankings-9-12/
Scala Job trends




출처: http://www.indeed.com/jobtrends/scala.html
근데,
어렵진 않나요?...
LISP, Haskell, Erlang, Clojure
 등의 함수형 언어에 익숙하다면
          쉽습니다
Ruby, Python, Javascript
 등의 언어에 익숙하다면
  어렵진 않을 겁니다 :)
자바만
주로 해오셨다면...
불지옥을 보시게
될지도 모릅니다 ...
불지옥을 보시게
될지도 모릅니다 ...
[H3 2012] 꽃보다 Scala
Problems of Java
Problems of Java
자바코드 == 대하소설
Problems of Java
  자바코드 == 대하소설
✓ 제한된 vocabulary
Problems of Java
  자바코드 == 대하소설
✓ 제한된 vocabulary
✓ 수 많은 third party 라이브러리 필수
Problems of Java
  자바코드 == 대하소설
✓ 제한된 vocabulary
✓ 수 많은 third party 라이브러리 필수
✓ 너무 적은 언어의 기능/개념
Problems of Java
  자바코드 == 대하소설
✓ 제한된 vocabulary
✓ 수 많은 third party 라이브러리 필수
✓ 너무 적은 언어의 기능/개념
✓ Need more syntactic sugars!
Problems of Java
  자바코드 == 대하소설
✓ 제한된 vocabulary
✓ 수 많은 third party 라이브러리 필수
✓ 너무 적은 언어의 기능/개념
✓ Need more syntactic sugars!
Problems of Java
  자바코드 == 대하소설
✓ 제한된 vocabulary
✓ 수 많은 third party 라이브러리 필수
✓ 너무 적은 언어의 기능/개념
✓ Need more syntactic sugars!
  이미 legacy, 너무 느린 발전 속도
Problems of Java
  자바코드 == 대하소설
✓ 제한된 vocabulary
✓ 수 많은 third party 라이브러리 필수
✓ 너무 적은 언어의 기능/개념
✓ Need more syntactic sugars!
  이미 legacy, 너무 느린 발전 속도
  Oracle...
Functional Style
   think f(x)!
f(x)?
f(x)?
g(f(x))
Imperative
   vs
Functional
명령형?


                      Imperative style
   우리에게 익숙한 그것 :)
✓ C, C++, Java, ...
   컴퓨터에게 절차적으로 명령을 내리는 방식
✓ “x 와 y 를 더하고, 결과를 z에 담고, z를 화면에 출력”

   Advantages
✓ 본질적으로 컴퓨터는 명령을 받고 수행하는 기계
✓ 많은 프로그래밍 언어가 명령형이며, 수많은 개발자가 이 방식에 익숙함
함수형?
함수형?


Functional style
함수형?


        Functional style
값의 변환 transformation 을 강조
함수형?


            Functional style
 값의 변환 transformation 을 강조
✓ 값을 입력 받고 새로운 값을 리턴함
함수형?


            Functional style
 값의 변환 transformation 을 강조
✓ 값을 입력 받고 새로운 값을 리턴함

 변경 불가능한 상태 immutable state 를 강조
함수형?


                  Functional style
  값의 변환 transformation 을 강조
✓ 값을 입력 받고 새로운 값을 리턴함

  변경 불가능한 상태 immutable state 를 강조
✓ referentially transparent (e.g., java.lang.String)
함수형?


                  Functional style
  값의 변환 transformation 을 강조
✓ 값을 입력 받고 새로운 값을 리턴함

  변경 불가능한 상태 immutable state 를 강조
✓ referentially transparent (e.g., java.lang.String)

  부수 효과 없음 no side-effects 을 강조
함수형?


                  Functional style
  값의 변환 transformation 을 강조
✓ 값을 입력 받고 새로운 값을 리턴함

  변경 불가능한 상태 immutable state 를 강조
✓ referentially transparent (e.g., java.lang.String)

  부수 효과 없음 no side-effects 을 강조
✓ 언제 계산 evaluation 을 하던, 같은 값을 리턴
함수형?
함수형?


Functional style
함수형?


        Functional style
최상위 개념으로서의 함수 first-class function
함수형?


                Functional style
  최상위 개념으로서의 함수 first-class function
✓ “function everywhere”
함수형?


                Functional style
  최상위 개념으로서의 함수 first-class function
✓ “function everywhere”

  Advantages
함수형?


                Functional style
  최상위 개념으로서의 함수 first-class function
✓ “function everywhere”

  Advantages
✓ 본질적으로 병렬화가 가능하며 thread-safe 함
함수형?


                Functional style
  최상위 개념으로서의 함수 first-class function
✓ “function everywhere”

  Advantages
✓ 본질적으로 병렬화가 가능하며 thread-safe 함
✓ Lazy evaluation 과 같은 최적화가 용이
함수형?


                Functional style
  최상위 개념으로서의 함수 first-class function
✓ “function everywhere”

  Advantages
✓ 본질적으로 병렬화가 가능하며 thread-safe 함
✓ Lazy evaluation 과 같은 최적화가 용이
✓ 함수를 연계하여, 코드를 좀 더 유연한 형태의 일반화 용이
명령형 vs 함수형



명령형 Imperative   함수형 Functional

 명령 command        함수 function

 문장 sentence     표현식 expression

 변수 variable         값 value

변경가능 mutable     변경불가 immutable

   루프 loop        재귀 recursion
명령형 vs 함수형


             Scala?
Scala 는 양쪽 스타일 모두를 지원
문제의 영역 domain 에 맞는 방식을 선택
일반적으로는 명령형보다 함수형을 권장
Imperative Style(Java)


               전달된 리스트 자체를 바꾸기


public static void addOneToAll(ArrayList<Integer> items){
  for (int i = 0; i < items.size(); ++i) {
    items.set(i, items.get(i) + 1);
  }
}
Functional Style(Java)


       원본은 그대로 두고 새로운 List 를 리턴


public static List<Integer> addOneToAll(List<Integer> items) {
  ArrayList<Integer> result = new ArrayList<Integer>();
  for (int i : items) {
    result.add(i + 1);
  }
  return result;
}
Functional Style(Java)


    Functional Enables Composition


public static List<Integer> addTwoToAll(List<Integer> items) {
  return addOneToAll(addOneToAll(items));
}
Function in Scala
Function in Math




f(x) = x + 1
Function in Scala




def f(x:Int):Int = x+1
Function in Scala




함수 인자 타입


 def f(x:Int):Int = x+1
Function in Scala



                    함수의 계산 결
                      과 타입
                     (리턴타입)
함수 인자 타입


 def f(x:Int):Int = x+1
Function in Scala
Function in Scala




def f(x:Int) = x + 1
Function in Scala




def f(x:Int) = x + 1
def g(x:Int) = x * x
Function in Scala




def f(x:Int) = x + 1
def g(x:Int) = x * x
def h(x:String, y:Int) = x + y
Function in Scala




def f(x:Int) = x + 1
def g(x:Int) = x * x
def h(x:String, y:Int) = x + y
Function in Scala




def f(x:Int) = x + 1
def g(x:Int) = x * x
def h(x:String, y:Int) = x + y

 => 추론 가능한 타입 선언 생략 가능
Function in Scala




def f(x:Int) = x + 1
def g(x:Int) = x * x
def h(x:String, y:Int) = x + y

 => 추론 가능한 타입 선언 생략 가능
 => 첫 등장시에만 타입 선언
Function call in Scala




h("result:", f(g(3)))
Anonymous function(λ expression) in Scala




   (x:Int) => x + 1
(x:Int,y:Int) => x < y
Anonymous function




val people: List[Person]
val minors =
 people.filter((p:Person) => p.age < 20)
Anonymous function : short form




val people: List[Person]
val minors =
 people.filter(p => p.age < 20)
Anonymous function : placeholder




val people: List[Person]
val minors =
 people.filter(_.age < 20)
addOneToAll in Scala


                            Imperative
def addOneToAll(items: collection.mutable.ListBuffer[Int])= {
  var i = 0
  while (i < items.length) {
    items.update(i, items(i) + 1)
    i += 1
  }
}




                             Functional
def addOneToAll(items: List[Int]) = items map (_ + 1)
Functional Style with Collection
Functional Style with Collection


collection.map(f(x))
Functional Style with Collection


   collection.map(f(x))
모든 collection 에 존재
Functional Style with Collection


   collection.map(f(x))
모든 collection 에 존재
함수 f 를 전달 받아 collection 의 각 item 에 f 를 적용
Functional Style with Collection


   collection.map(f(x))
모든 collection 에 존재
함수 f 를 전달 받아 collection 의 각 item 에 f 를 적용
f 의 결과를 같은 사이즈의 같은 collection 에 담아 리턴
Functional Style with Collection


           collection.map(f(x))
      모든 collection 에 존재
      함수 f 를 전달 받아 collection 의 각 item 에 f 를 적용
      f 의 결과를 같은 사이즈의 같은 collection 에 담아 리턴


scala> val strs = List("aaa", "bb", "c")
Functional Style with Collection


           collection.map(f(x))
      모든 collection 에 존재
      함수 f 를 전달 받아 collection 의 각 item 에 f 를 적용
      f 의 결과를 같은 사이즈의 같은 collection 에 담아 리턴


scala> val strs = List("aaa", "bb", "c")
strs: List[java.lang.String] = List(aaa, bb, c)
Functional Style with Collection


           collection.map(f(x))
      모든 collection 에 존재
      함수 f 를 전달 받아 collection 의 각 item 에 f 를 적용
      f 의 결과를 같은 사이즈의 같은 collection 에 담아 리턴


scala> val strs = List("aaa", "bb", "c")
strs: List[java.lang.String] = List(aaa, bb, c)

scala> val ints = strs.map(str => str.length)
Functional Style with Collection


           collection.map(f(x))
      모든 collection 에 존재
      함수 f 를 전달 받아 collection 의 각 item 에 f 를 적용
      f 의 결과를 같은 사이즈의 같은 collection 에 담아 리턴


scala> val strs = List("aaa", "bb", "c")
strs: List[java.lang.String] = List(aaa, bb, c)

scala> val ints = strs.map(str => str.length)
ints: List[Int] = List(3, 2, 1)
Functional Style with Collection


           collection.map(f(x))
      모든 collection 에 존재
      함수 f 를 전달 받아 collection 의 각 item 에 f 를 적용
      f 의 결과를 같은 사이즈의 같은 collection 에 담아 리턴


scala> val strs = List("aaa", "bb", "c")
strs: List[java.lang.String] = List(aaa, bb, c)

scala> val ints = strs.map(str => str.length)
ints: List[Int] = List(3, 2, 1)

                                                  String => Int
Functional Style with Collection


           collection.map(f(x))
      모든 collection 에 존재
      함수 f 를 전달 받아 collection 의 각 item 에 f 를 적용
      f 의 결과를 같은 사이즈의 같은 collection 에 담아 리턴


scala> val strs = List("aaa", "bb", "c")
strs: List[java.lang.String] = List(aaa, bb, c)

scala> val ints = strs.map(str => str.length)
ints: List[Int] = List(3, 2, 1)

                                                  String => Int
Functional Style with Collection


           collection.map(f(x))
      모든 collection 에 존재
      함수 f 를 전달 받아 collection 의 각 item 에 f 를 적용
      f 의 결과를 같은 사이즈의 같은 collection 에 담아 리턴


scala> val strs = List("aaa", "bb", "c")
strs: List[java.lang.String] = List(aaa, bb, c)

scala> val ints = strs.map(str => str.length)
ints: List[Int] = List(3, 2, 1)

                                                  String => Int
Functional Style with Collection


           collection.map(f(x))
      모든 collection 에 존재
      함수 f 를 전달 받아 collection 의 각 item 에 f 를 적용
      f 의 결과를 같은 사이즈의 같은 collection 에 담아 리턴


scala> val strs = List("aaa", "bb", "c")
strs: List[java.lang.String] = List(aaa, bb, c)

scala> val ints = strs.map(str => str.length)
ints: List[Int] = List(3, 2, 1)

                                                  String => Int
Functional Style with Collection


           collection.map(f(x))
      모든 collection 에 존재
      함수 f 를 전달 받아 collection 의 각 item 에 f 를 적용
      f 의 결과를 같은 사이즈의 같은 collection 에 담아 리턴


scala> val strs = List("aaa", "bb", "c")
strs: List[java.lang.String] = List(aaa, bb, c)

scala> val ints = strs.map(str => str.length)
ints: List[Int] = List(3, 2, 1)

                                                  String => Int
Functional Style with Collection


           collection.map(f(x))
      모든 collection 에 존재
      함수 f 를 전달 받아 collection 의 각 item 에 f 를 적용
      f 의 결과를 같은 사이즈의 같은 collection 에 담아 리턴


scala> val strs = List("aaa", "bb", "c")
strs: List[java.lang.String] = List(aaa, bb, c)

scala> val ints = strs.map(str => str.length)
ints: List[Int] = List(3, 2, 1)

                                                  String => Int
Functional Style with Collection
Functional Style with Collection


collection.reduce(f(x,y))
Functional Style with Collection


collection.reduce(f(x,y))
모든 collection 에 존재
Functional Style with Collection


collection.reduce(f(x,y))
모든 collection 에 존재
collection 에 존재하는 값들을 하나의 값으로 만듬
Functional Style with Collection


     collection.reduce(f(x,y))
      모든 collection 에 존재
      collection 에 존재하는 값들을 하나의 값으로 만듬



scala> val nums = 1 to 5 //1.to(5)
Functional Style with Collection


     collection.reduce(f(x,y))
      모든 collection 에 존재
      collection 에 존재하는 값들을 하나의 값으로 만듬



scala> val nums = 1 to 5 //1.to(5)
nums: Range.Inclusive = Range(1, 2, 3, 4, 5)
Functional Style with Collection


     collection.reduce(f(x,y))
      모든 collection 에 존재
      collection 에 존재하는 값들을 하나의 값으로 만듬



scala> val nums = 1 to 5 //1.to(5)
nums: Range.Inclusive = Range(1, 2, 3, 4, 5)

scala> val fact = nums.reduce((acc,num)=>acc*num)
Functional Style with Collection


     collection.reduce(f(x,y))
      모든 collection 에 존재
      collection 에 존재하는 값들을 하나의 값으로 만듬



scala> val nums = 1 to 5 //1.to(5)
nums: Range.Inclusive = Range(1, 2, 3, 4, 5)

scala> val fact = nums.reduce((acc,num)=>acc*num)
fact: Int = 120
Functional Style with Collection


     collection.reduce(f(x,y))
      모든 collection 에 존재
      collection 에 존재하는 값들을 하나의 값으로 만듬



scala> val nums = 1 to 5 //1.to(5)
nums: Range.Inclusive = Range(1, 2, 3, 4, 5)

scala> val fact = nums.reduce((acc,num)=>acc*num)
fact: Int = 120

                                               (Int,Int)=> Int
reduce


돌돌돌~ 말아 보아요~
reduce



1   2   3   4
reduce



11 2 2   3   4
 1*2
  2
reduce



11 2 2 3               3   4
 1*2
  2
       2   *       3


               6
reduce



11 2 2 3                        3 4   4
 1*2
  2
       2   *       3


               6
                       6   *    4



                           24
reduce



11 2 2 3                        3 4              45
 1*2
  2
       2   *       3


               6
                       6   *    4



                           24       24       *
                                         5



                                    120
Functional Style: map reduce
Functional Style: map reduce


val people :Array[Person] = ...
Functional Style: map reduce


val people :Array[Person] = ...
val sum = people.map(_.age).reduce(_ + _)
Functional Style: map reduce


val people :Array[Person] = ...
val sum = people.map(_.age).reduce(_ + _)
val avg = sum / people.length
Functional Style: map reduce


val people :Array[Person] = ...
val sum = people.map(_.age).reduce(_ + _)
val avg = sum / people.length



    scala> val people = Array(Person("Charles", 50),
Functional Style: map reduce


val people :Array[Person] = ...
val sum = people.map(_.age).reduce(_ + _)
val avg = sum / people.length



    scala> val people = Array(Person("Charles", 50),
       | Person("G.Ne", 60), Person("Jane", 59)) people:
    Array[Person] = Array(Person(Charles,50), Person(G.Ne,60),
    Person(Jane,59))
Functional Style: map reduce


val people :Array[Person] = ...
val sum = people.map(_.age).reduce(_ + _)
val avg = sum / people.length



    scala> val people = Array(Person("Charles", 50),
       | Person("G.Ne", 60), Person("Jane", 59)) people:
    Array[Person] = Array(Person(Charles,50), Person(G.Ne,60),
    Person(Jane,59))

    scala> val ages = people.map(p => p.age)
Functional Style: map reduce


val people :Array[Person] = ...
val sum = people.map(_.age).reduce(_ + _)
val avg = sum / people.length



    scala> val people = Array(Person("Charles", 50),
       | Person("G.Ne", 60), Person("Jane", 59)) people:
    Array[Person] = Array(Person(Charles,50), Person(G.Ne,60),
    Person(Jane,59))

    scala> val ages = people.map(p => p.age)
    ages: Array[Int] = Array(50, 60, 59)
Functional Style: map reduce


val people :Array[Person] = ...
val sum = people.map(_.age).reduce(_ + _)
val avg = sum / people.length



    scala> val people = Array(Person("Charles", 50),
       | Person("G.Ne", 60), Person("Jane", 59)) people:
    Array[Person] = Array(Person(Charles,50), Person(G.Ne,60),
    Person(Jane,59))

    scala> val ages = people.map(p => p.age)
    ages: Array[Int] = Array(50, 60, 59)

    scala> ages.reduce((acc, age) => acc + age)
Functional Style: map reduce


val people :Array[Person] = ...
val sum = people.map(_.age).reduce(_ + _)
val avg = sum / people.length



    scala> val people = Array(Person("Charles", 50),
       | Person("G.Ne", 60), Person("Jane", 59)) people:
    Array[Person] = Array(Person(Charles,50), Person(G.Ne,60),
    Person(Jane,59))

    scala> val ages = people.map(p => p.age)
    ages: Array[Int] = Array(50, 60, 59)

    scala> ages.reduce((acc, age) => acc + age)
    res7: Int = 169
Functional Style: map reduce


val people :Array[Person] = ...
val sum = people.map(_.age).reduce(_ + _)
val avg = sum / people.length



    scala> val people = Array(Person("Charles", 50),
       | Person("G.Ne", 60), Person("Jane", 59)) people:
    Array[Person] = Array(Person(Charles,50), Person(G.Ne,60),
    Person(Jane,59))

    scala> val ages = people.map(p => p.age)
                                                        50 + 60 = 110
    ages: Array[Int] = Array(50, 60, 59)               110 + 59 = 169
    scala> ages.reduce((acc, age) => acc + age)
    res7: Int = 169
Functional style


                       Functional is ...
  Just a pattern and NOT a syntax.
✓ Java이냐 Scala 이냐 관계 없이 Functional 하게 코드를 작성 할 수 있음
✓ Functional Java:
  => http://functionaljava.org/

  => http://code.google.com/p/guava-libraries/


  Not only for academic languages
✓ Java를 제외한 Ruby, Python, Javascript 같은 대부분의 언어들은 functional
  style 을 위한 다양한 도구를 지원함
Pattern Matching
match/case
match/case



val new = old match {
 case 패턴1 => 값1
    case 패턴2 => 값2
    case _ => 기본값
}
Pattern matching


            Matching on values

val times = 1

val numStr = times match {
  case 1 => "one"
  case 2 => "two"
  case _ => "some other number"
}
Pattern matching


          Matching with guards

val times = 1

val numStr = times match {
  case i if i == 1 => "one"
  case i if i == 2 => "two"
  case _ => "some other number"
}
Pattern matching


              Matching on type

def bigger(o: Any): Any = {
  o match {
    case i: Int if i < 0 => i - 1
    case i: Int => i + 1
    case d: Double if d < 0.0 => d - 0.1
    case d: Double => d + 0.1
    case text: String => text + "s"
  }
}
Pattern matching


           Matching on class member

class Calculator(val brand: String, val model: String)

def calcType(calc: Calculator) = calc match {
  case c if c.brand == "hp" && c.model == "20B" =>
   "financial"
  case c if c.brand == "hp" && c.model == "48G" =>
   "scientific"
  case c if c.brand == "hp" && c.model == "30B" =>
   "business"
  case _ =>
   "unknown"
}
case class
case class Calculator(brand: String, model: String)
case class
case class Calculator(brand: String, model: String)




                         accessor, equals(==), hashCode(##), toString,
                         copy, pattern matching, factory function
case class
case class


scala> val a = Calculator("hp", "20B")
case class


scala> val a = Calculator("hp", "20B")
a: Calculator = Calculator(hp,20B)
case class


scala> val a = Calculator("hp", "20B")
a: Calculator = Calculator(hp,20B)

scala> a ##
case class


scala> val a = Calculator("hp", "20B")
a: Calculator = Calculator(hp,20B)

scala> a ##
res58: Int = 1619269961
case class


scala> val a = Calculator("hp", "20B")
a: Calculator = Calculator(hp,20B)

scala> a ##
res58: Int = 1619269961

scala> a toString
case class


scala> val a = Calculator("hp", "20B")
a: Calculator = Calculator(hp,20B)

scala> a ##
res58: Int = 1619269961

scala> a toString
res59: String = Calculator(hp,20B)
case class


scala> val a = Calculator("hp", "20B")
a: Calculator = Calculator(hp,20B)

scala> a ##
res58: Int = 1619269961

scala> a toString
res59: String = Calculator(hp,20B)

scala> a.copy(model = "48G")
case class


scala> val a = Calculator("hp", "20B")
a: Calculator = Calculator(hp,20B)

scala> a ##
res58: Int = 1619269961

scala> a toString
res59: String = Calculator(hp,20B)

scala> a.copy(model = "48G")
res60: Calculator = Calculator(hp,48G)
case class


scala> val a = Calculator("hp", "20B")
a: Calculator = Calculator(hp,20B)

scala> a ##
res58: Int = 1619269961

scala> a toString
res59: String = Calculator(hp,20B)

scala> a.copy(model = "48G")
res60: Calculator = Calculator(hp,48G)

scala> val b = Calculator("hp", "20B")
case class


scala> val a = Calculator("hp", "20B")
a: Calculator = Calculator(hp,20B)

scala> a ##
res58: Int = 1619269961

scala> a toString
res59: String = Calculator(hp,20B)

scala> a.copy(model = "48G")
res60: Calculator = Calculator(hp,48G)

scala> val b = Calculator("hp", "20B")
b: Calculator = Calculator(hp,20B)
case class


scala> val a = Calculator("hp", "20B")
a: Calculator = Calculator(hp,20B)

scala> a ##
res58: Int = 1619269961

scala> a toString
res59: String = Calculator(hp,20B)

scala> a.copy(model = "48G")
res60: Calculator = Calculator(hp,48G)

scala> val b = Calculator("hp", "20B")
b: Calculator = Calculator(hp,20B)

scala> a == b
case class


scala> val a = Calculator("hp", "20B")
a: Calculator = Calculator(hp,20B)

scala> a ##
res58: Int = 1619269961

scala> a toString
res59: String = Calculator(hp,20B)

scala> a.copy(model = "48G")
res60: Calculator = Calculator(hp,48G)

scala> val b = Calculator("hp", "20B")
b: Calculator = Calculator(hp,20B)

scala> a == b
res61: Boolean = true
Pattern Matching: case class
Pattern Matching: case class


def calcType(calc: Calculator) = calc match {
Pattern Matching: case class


def calcType(calc: Calculator) = calc match {
 case Calculator("hp", "20B") => "financial"
Pattern Matching: case class


def calcType(calc: Calculator) = calc match {
 case Calculator("hp", "20B") => "financial"
 case Calculator("hp", "48G") => "scientific"
Pattern Matching: case class


def calcType(calc: Calculator) = calc match {
 case Calculator("hp", "20B") => "financial"
 case Calculator("hp", "48G") => "scientific"
 case Calculator("hp", "30B") => "business"
Pattern Matching: case class


def calcType(calc: Calculator) = calc match {
 case Calculator("hp", "20B") => "financial"
 case Calculator("hp", "48G") => "scientific"
 case Calculator("hp", "30B") => "business"
 case Calculator(b, m) =>
Pattern Matching: case class


def calcType(calc: Calculator) = calc match {
 case Calculator("hp", "20B") => "financial"
 case Calculator("hp", "48G") => "scientific"
 case Calculator("hp", "30B") => "business"
 case Calculator(b, m) =>
  "Calculator: %s %s is of unknown type".format(b, m)
Pattern Matching: case class


def calcType(calc: Calculator) = calc match {
  case Calculator("hp", "20B") => "financial"
  case Calculator("hp", "48G") => "scientific"
  case Calculator("hp", "30B") => "business"
  case Calculator(b, m) =>
   "Calculator: %s %s is of unknown type".format(b, m)
}
Pattern Matching: case class


def calcType(calc: Calculator) = calc match {
  case Calculator("hp", "20B") => "financial"
  case Calculator("hp", "48G") => "scientific"
  case Calculator("hp", "30B") => "business"
  case Calculator(b, m) =>
   "Calculator: %s %s is of unknown type".format(b, m)
}




scala> calcType(Calculator("hp", "20B"))
Pattern Matching: case class


def calcType(calc: Calculator) = calc match {
  case Calculator("hp", "20B") => "financial"
  case Calculator("hp", "48G") => "scientific"
  case Calculator("hp", "30B") => "business"
  case Calculator(b, m) =>
   "Calculator: %s %s is of unknown type".format(b, m)
}




scala> calcType(Calculator("hp", "20B"))
res62: java.lang.String = financial
Pattern Matching: case class


def calcType(calc: Calculator) = calc match {
  case Calculator("hp", "20B") => "financial"
  case Calculator("hp", "48G") => "scientific"
  case Calculator("hp", "30B") => "business"
  case Calculator(b, m) =>
   "Calculator: %s %s is of unknown type".format(b, m)
}




scala> calcType(Calculator("hp", "20B"))
res62: java.lang.String = financial

scala> calcType(Calculator("hp", "48G"))
Pattern Matching: case class


def calcType(calc: Calculator) = calc match {
  case Calculator("hp", "20B") => "financial"
  case Calculator("hp", "48G") => "scientific"
  case Calculator("hp", "30B") => "business"
  case Calculator(b, m) =>
   "Calculator: %s %s is of unknown type".format(b, m)
}




scala> calcType(Calculator("hp", "20B"))
res62: java.lang.String = financial

scala> calcType(Calculator("hp", "48G"))
res63: java.lang.String = scientific
Pattern Matching: case class


def calcType(calc: Calculator) = calc match {
  case Calculator("hp", "20B") => "financial"
  case Calculator("hp", "48G") => "scientific"
  case Calculator("hp", "30B") => "business"
  case Calculator(b, m) =>
   "Calculator: %s %s is of unknown type".format(b, m)
}




scala> calcType(Calculator("hp", "20B"))
res62: java.lang.String = financial

scala> calcType(Calculator("hp", "48G"))
res63: java.lang.String = scientific

scala> calcType(Calculator("kth", "h3"))
Pattern Matching: case class


def calcType(calc: Calculator) = calc match {
  case Calculator("hp", "20B") => "financial"
  case Calculator("hp", "48G") => "scientific"
  case Calculator("hp", "30B") => "business"
  case Calculator(b, m) =>
   "Calculator: %s %s is of unknown type".format(b, m)
}




scala> calcType(Calculator("hp", "20B"))
res62: java.lang.String = financial

scala> calcType(Calculator("hp", "48G"))
res63: java.lang.String = scientific

scala> calcType(Calculator("kth", "h3"))
res64: java.lang.String = Calculator: kth h3 is of unknown type
Pattern Matching: case class
Pattern Matching: case class


scala> val calcs = List(Calculator("hp", "20B"),
Pattern Matching: case class


scala> val calcs = List(Calculator("hp", "20B"),
   | Calculator("hp", "48G"), Calculator("hp", "30B"),
Pattern Matching: case class


scala> val calcs = List(Calculator("hp", "20B"),
   | Calculator("hp", "48G"), Calculator("hp", "30B"),
   | Calculator("kth", "h3"))
Pattern Matching: case class


scala> val calcs = List(Calculator("hp", "20B"),
   | Calculator("hp", "48G"), Calculator("hp", "30B"),
   | Calculator("kth", "h3"))

calcs: List[Calculator] = List(Calculator(hp,20B), Calculator(hp,48G),
Calculator(hp,30B), Calculator(kth,h3))
Pattern Matching: case class


scala> val calcs = List(Calculator("hp", "20B"),
   | Calculator("hp", "48G"), Calculator("hp", "30B"),
   | Calculator("kth", "h3"))

calcs: List[Calculator] = List(Calculator(hp,20B), Calculator(hp,48G),
Calculator(hp,30B), Calculator(kth,h3))

scala> calcs.map(calcType).foreach(println)
Pattern Matching: case class


scala> val calcs = List(Calculator("hp", "20B"),
   | Calculator("hp", "48G"), Calculator("hp", "30B"),
   | Calculator("kth", "h3"))

calcs: List[Calculator] = List(Calculator(hp,20B), Calculator(hp,48G),
Calculator(hp,30B), Calculator(kth,h3))

scala> calcs.map(calcType).foreach(println)
financial
Pattern Matching: case class


scala> val calcs = List(Calculator("hp", "20B"),
   | Calculator("hp", "48G"), Calculator("hp", "30B"),
   | Calculator("kth", "h3"))

calcs: List[Calculator] = List(Calculator(hp,20B), Calculator(hp,48G),
Calculator(hp,30B), Calculator(kth,h3))

scala> calcs.map(calcType).foreach(println)
financial
scientific
Pattern Matching: case class


scala> val calcs = List(Calculator("hp", "20B"),
   | Calculator("hp", "48G"), Calculator("hp", "30B"),
   | Calculator("kth", "h3"))

calcs: List[Calculator] = List(Calculator(hp,20B), Calculator(hp,48G),
Calculator(hp,30B), Calculator(kth,h3))

scala> calcs.map(calcType).foreach(println)
financial
scientific
business
Pattern Matching: case class


scala> val calcs = List(Calculator("hp", "20B"),
   | Calculator("hp", "48G"), Calculator("hp", "30B"),
   | Calculator("kth", "h3"))

calcs: List[Calculator] = List(Calculator(hp,20B), Calculator(hp,48G),
Calculator(hp,30B), Calculator(kth,h3))

scala> calcs.map(calcType).foreach(println)
financial
scientific
business
Calculator: kth h3 is of unknown type
Pattern Matching: case class
Pattern Matching: case class


Example: Activity Stream
Pattern Matching: case class


   Example: Activity Stream
Facebook timeline
Pattern Matching: case class


   Example: Activity Stream
Facebook timeline
SNS 사용자들의 활동 내역을 추상화
Pattern Matching: case class


   Example: Activity Stream
Facebook timeline
SNS 사용자들의 활동 내역을 추상화
이번 예제에서는 write/like 만 고려
Pattern Matching: case class


   Example: Activity Stream
Facebook timeline
SNS 사용자들의 활동 내역을 추상화
이번 예제에서는 write/like 만 고려
Pattern Matching: case class


   Example: Activity Stream
Facebook timeline
SNS 사용자들의 활동 내역을 추상화
이번 예제에서는 write/like 만 고려



   “Someone likes my post”
Example: Activity Stream


Activity = S(주어) + V(동사) + O(목적어)
Example: Activity Stream


 Activity = S(주어) + V(동사) + O(목적어)


case class Activity(
  sub: Noun,
  verb: String,
  obj: Noun
)
Example: Activity Stream


Person and Post
Example: Activity Stream


             Person and Post

trait Noun
Example: Activity Stream


                     Person and Post

trait Noun

case class Person(name: String, age: Int) extends Noun {
Example: Activity Stream


                     Person and Post

trait Noun

case class Person(name: String, age: Int) extends Noun {
 def followers: List[Person] = ...
Example: Activity Stream


                     Person and Post

trait Noun

case class Person(name: String, age: Int) extends Noun {
  def followers: List[Person] = ...
}
Example: Activity Stream


                     Person and Post

trait Noun

case class Person(name: String, age: Int) extends Noun {
  def followers: List[Person] = ...
}
Example: Activity Stream


                     Person and Post

trait Noun

case class Person(name: String, age: Int) extends Noun {
  def followers: List[Person] = ...
}

case class Post(author: Person, text: String) extends Noun
Example: Activity Stream


Activity
Example: Activity Stream


                     Activity

val jane = Person("Jane", 59)
Example: Activity Stream


                     Activity

val jane = Person("Jane", 59)

val charles = Person("Charles", 50)
Example: Activity Stream


                     Activity

val jane = Person("Jane", 59)

val charles = Person("Charles", 50)

val post = Post(jane, "hello, world")
Example: Activity Stream


                      Activity

val jane = Person("Jane", 59)

val charles = Person("Charles", 50)

val post = Post(jane, "hello, world")

val a1 = Activity(jane, "write", post)
Example: Activity Stream


                      Activity

val jane = Person("Jane", 59)

val charles = Person("Charles", 50)

val post = Post(jane, "hello, world")

val a1 = Activity(jane, "write", post)

val a2 = Activity(charles, "like", post)
Example: Activity Stream


Push or Email
Example: Activity Stream


                Push or Email

def sendPush(to: Person, msg: String)
Example: Activity Stream


                Push or Email

def sendPush(to: Person, msg: String)

def sendEmail(to: Person, msg: String)
Example: Activity Stream


Notification
Example: Activity Stream


                            Notification

def sendNoti(a: Activity) = {
Example: Activity Stream


                            Notification

def sendNoti(a: Activity) = {
 a match {
Example: Activity Stream


                          Notification

def sendNoti(a: Activity) = {
 a match {
  case Activity(someone: Person, "like", Post(author, _)) =>
Example: Activity Stream


                          Notification

def sendNoti(a: Activity) = {
 a match {
  case Activity(someone: Person, "like", Post(author, _)) =>
    sendPush(
Example: Activity Stream


                          Notification

def sendNoti(a: Activity) = {
 a match {
  case Activity(someone: Person, "like", Post(author, _)) =>
    sendPush(
     author,
Example: Activity Stream


                          Notification

def sendNoti(a: Activity) = {
 a match {
  case Activity(someone: Person, "like", Post(author, _)) =>
    sendPush(
     author,
     "%s likes your post".format(someone.name))
Example: Activity Stream


                          Notification

def sendNoti(a: Activity) = {
 a match {
  case Activity(someone: Person, "like", Post(author, _)) =>
    sendPush(
     author,
     "%s likes your post".format(someone.name))
  case Activity(someone: Person, "write", _) =>
Example: Activity Stream


                          Notification

def sendNoti(a: Activity) = {
 a match {
  case Activity(someone: Person, "like", Post(author, _)) =>
    sendPush(
     author,
     "%s likes your post".format(someone.name))
  case Activity(someone: Person, "write", _) =>
    someone.followers.foreach(
Example: Activity Stream


                          Notification

def sendNoti(a: Activity) = {
 a match {
  case Activity(someone: Person, "like", Post(author, _)) =>
    sendPush(
     author,
     "%s likes your post".format(someone.name))
  case Activity(someone: Person, "write", _) =>
    someone.followers.foreach(
     p =>
Example: Activity Stream


                          Notification

def sendNoti(a: Activity) = {
 a match {
  case Activity(someone: Person, "like", Post(author, _)) =>
    sendPush(
     author,
     "%s likes your post".format(someone.name))
  case Activity(someone: Person, "write", _) =>
    someone.followers.foreach(
     p =>
      sendEmail(
Example: Activity Stream


                          Notification

def sendNoti(a: Activity) = {
 a match {
  case Activity(someone: Person, "like", Post(author, _)) =>
    sendPush(
     author,
     "%s likes your post".format(someone.name))
  case Activity(someone: Person, "write", _) =>
    someone.followers.foreach(
     p =>
      sendEmail(
       p, "%s write new post".format(someone.name)))
Example: Activity Stream


                           Notification

def sendNoti(a: Activity) = {
 a match {
   case Activity(someone: Person, "like", Post(author, _)) =>
    sendPush(
     author,
     "%s likes your post".format(someone.name))
   case Activity(someone: Person, "write", _) =>
    someone.followers.foreach(
     p =>
      sendEmail(
        p, "%s write new post".format(someone.name)))
 }
Example: Activity Stream


                           Notification

def sendNoti(a: Activity) = {
  a match {
    case Activity(someone: Person, "like", Post(author, _)) =>
     sendPush(
      author,
      "%s likes your post".format(someone.name))
    case Activity(someone: Person, "write", _) =>
     someone.followers.foreach(
      p =>
       sendEmail(
         p, "%s write new post".format(someone.name)))
  }
}
조금 더 우아하게!
좀 더 우아하게 !

object Activities {
 trait Activity
 trait Noun

    case class write(sub: Noun, obj: Noun) extends Activity
    case class like(sub: Noun, obj: Noun) extends Activity

    case class Sub(n: Noun) {
      def like(obj: Noun) = Activities.like(n, obj)
      def write(obj: Noun) = Activities.write(n, obj)
    }

    implicit def nounToSub(n: Noun) = Sub(n)

    case class Person(name: String, age: Int) extends Noun {
      def followers: List[Person] = Nil
    }

    case class Post(author: Person, text: String) extends Noun
}
좀 더 우아하게!
좀 더 우아하게!



val jane = Person("Jane", 59)
좀 더 우아하게!



val jane = Person("Jane", 59)

val charles = Person("Charles", 50)
좀 더 우아하게!



val jane = Person("Jane", 59)

val charles = Person("Charles", 50)

val post = Post(jane, "hello, world")
좀 더 우아하게!



val jane = Person("Jane", 59)

val charles = Person("Charles", 50)

val post = Post(jane, "hello, world")

val a1 = jane write post
좀 더 우아하게!



val jane = Person("Jane", 59)

val charles = Person("Charles", 50)

val post = Post(jane, "hello, world")

val a1 = jane write post

val a2 = charles like post
좀 더 우아하게!



val jane = Person("Jane", 59)

val charles = Person("Charles", 50)

val post = Post(jane, "hello, world")

val a1 = jane write post

val a2 = charles like post

def sendNoti(a: Activity) {
좀 더 우아하게!



val jane = Person("Jane", 59)

val charles = Person("Charles", 50)

val post = Post(jane, "hello, world")

val a1 = jane write post

val a2 = charles like post

def sendNoti(a: Activity) {
 a match {
좀 더 우아하게!



val jane = Person("Jane", 59)

val charles = Person("Charles", 50)

val post = Post(jane, "hello, world")

val a1 = jane write post

val a2 = charles like post

def sendNoti(a: Activity) {
 a match {
  case someone write post => ...
좀 더 우아하게!



val jane = Person("Jane", 59)

val charles = Person("Charles", 50)

val post = Post(jane, "hello, world")

val a1 = jane write post

val a2 = charles like post

def sendNoti(a: Activity) {
 a match {
  case someone write post => ...
  case Person(name, age) like Post(author, text) => ...
좀 더 우아하게!



val jane = Person("Jane", 59)

val charles = Person("Charles", 50)

val post = Post(jane, "hello, world")

val a1 = jane write post

val a2 = charles like post

def sendNoti(a: Activity) {
 a match {
   case someone write post => ...
   case Person(name, age) like Post(author, text) => ...
 }
좀 더 우아하게!



val jane = Person("Jane", 59)

val charles = Person("Charles", 50)

val post = Post(jane, "hello, world")

val a1 = jane write post

val a2 = charles like post

def sendNoti(a: Activity) {
  a match {
    case someone write post => ...
    case Person(name, age) like Post(author, text) => ...
  }
}
Pattern Matching
Pattern Matching


More usage
Pattern Matching


            More usage
val Person(name, age) = Person(“tao”,35)
Pattern Matching


            More usage
val Person(name, age) = Person(“tao”,35)
“for” expression
Pattern Matching


              More usage
val Person(name, age) = Person(“tao”,35)
“for” expression
Collections
Pattern Matching


              More usage
val Person(name, age) = Person(“tao”,35)
“for” expression
Collections
Extractors
Pattern Matching


              More usage
val Person(name, age) = Person(“tao”,35)
“for” expression
Collections
Extractors
XML
Horizontal Scale
Horizontal Scale


  The Multi-core Era
✓ Moore Law
  => 반도체 집적 회로의 성능은 18개월 마다 2배로 증간한다

  => 최근에는 클럭수가 아닌 코어의 증가로 이루어짐


  The Big-data Era
✓ 마구 쏟아지는 엄청난 데이터를 처리해야함
  병렬/동시/분산 처리가 중요해짐
✓ 하지만, 동시성 문제는 언제나 어렵다
왜?
Horizontal Scale


                   Root Cause
  공유된 변경 가능한 상태 shared mutable state
  동기화 synchronization
✓ monitor & lock

  예측 불가능한 상황을 피하기 위해서는
✓ 변경 가능한 상태 mutable state 를 만들지 말아야 함
✓ 즉, functional style 로 코드를 작성해야함
“ 프로그램들은 버그로 가득차
Thread를 사용하는 대부분의

                 있다
   - Havoc Pennington @ Dreamforce 2011

                                          ”
Thread-less
concurrency
Actor model
Actor model
Actor model


Actor Model
Actor model


        Actor Model
동시성 문제를 위한 더 단순한 고수준의 추상화 모델
Actor model


                    Actor Model
  동시성 문제를 위한 더 단순한 고수준의 추상화 모델
✓ Actors are objects which encapsulate state and behavior
Actor model


                    Actor Model
  동시성 문제를 위한 더 단순한 고수준의 추상화 모델
✓ Actors are objects which encapsulate state and behavior

  Erlang 이라는 언어를 통해 널리 알려짐
Actor model


                    Actor Model
  동시성 문제를 위한 더 단순한 고수준의 추상화 모델
✓ Actors are objects which encapsulate state and behavior

  Erlang 이라는 언어를 통해 널리 알려짐
  Message passing, no shared memory
Actor model


                    Actor Model
  동시성 문제를 위한 더 단순한 고수준의 추상화 모델
✓ Actors are objects which encapsulate state and behavior

  Erlang 이라는 언어를 통해 널리 알려짐
  Message passing, no shared memory
  Event loop
Worker vs Actor


                     Worker



Queue                Worker
             take                 lock
                                         Shared
 Job                                     Memory
                    Worker #3
       put


                     Worker
Worker vs Actor


                           Actor #1
                 mailbox
                                           message


messages                   Actor #2

   To: Actor#1



                           Actor #3



                           Actor #4
Scala Actor
“   Bruce: “그 때(루비를 만들었을 당시)로 돌아간다
    면, 어떤 기능에 변화를 주고 싶으세요?”

    Matz: “Thread를 없애고, Actor 나 또는 좀 더 진
    보된 형태의 동시성 기능을 추가했을거에요”


       Interview with Yukihiro Matsumoto (the creator of Ruby)
          from the book, “Seven Languages in Seven Weeks”




                                                                 ”
Scala Actor
Scala Actor


Akka
Scala Actor


              Akka
Scala로 작성된 Actor model 구현
Scala Actor


                Akka
Scala로 작성된 Actor model 구현
TypeSafe Stack with Play! Framework
Scala Actor


                Akka
Scala로 작성된 Actor model 구현
TypeSafe Stack with Play! Framework
곧 Scala에 built-in 될 예정
Scala Actor


                       Akka
  Scala로 작성된 Actor model 구현
  TypeSafe Stack with Play! Framework
  곧 Scala에 built-in 될 예정
✓ 기존 Scala 자체 구현은 deprecate 될 예정
Scala Actor


                       Akka
  Scala로 작성된 Actor model 구현
  TypeSafe Stack with Play! Framework
  곧 Scala에 built-in 될 예정
✓ 기존 Scala 자체 구현은 deprecate 될 예정

  자바를 위한 별도 API 제공
Scala Actor


                       Akka
  Scala로 작성된 Actor model 구현
  TypeSafe Stack with Play! Framework
  곧 Scala에 built-in 될 예정
✓ 기존 Scala 자체 구현은 deprecate 될 예정

  자바를 위한 별도 API 제공
  Asynchronous/non-blocking
Scala Actor


                       Akka
  Scala로 작성된 Actor model 구현
  TypeSafe Stack with Play! Framework
  곧 Scala에 built-in 될 예정
✓ 기존 Scala 자체 구현은 deprecate 될 예정

  자바를 위한 별도 API 제공
  Asynchronous/non-blocking
  격리된 변경 가능 상태 Isolated mutable state
Akka


                                   Actor

import akka.actor.Actor
import akka.actor.Props
import akka.event.Logging

class MyActor extends Actor {
 val log = Logging(context.system, this)
 def receive = {
   case "test"   log.info("received test")
        case _   log.info("received unknown message")
    }
}
Akka


                                   Actor

import akka.actor.Actor
import akka.actor.Props
import akka.event.Logging

class MyActor extends Actor {
 val log = Logging(context.system, this)
 def receive = {
   case "test"   log.info("received test")
        case _   log.info("received unknown message")
    }
}
Akka
Akka


Creating actor
Akka


                      Creating actor

val system = ActorSystem("MySystem")
val myActor = system.actorOf(Props[MyActor], name = "myactor")
Akka


                      Creating actor

val system = ActorSystem("MySystem")
val myActor = system.actorOf(Props[MyActor], name = "myactor")




                  Sending a message
Akka


                        Creating actor

val system = ActorSystem("MySystem")
val myActor = system.actorOf(Props[MyActor], name = "myactor")




                       Sending a message

myActor ! "test"
myActor.tell("test")
Akka


                        Creating actor

val system = ActorSystem("MySystem")
val myActor = system.actorOf(Props[MyActor], name = "myactor")




                       Sending a message

myActor ! "test"
myActor.tell("test")

                               Tell: Fire and Forget
Akka
Akka


Replying
Akka


                             Replying

def receive = {
 case "ping"    sender ! "pong"
 ...
Akka


                             Replying

def receive = {
 case "ping"    sender ! "pong"
 ...



                                  Asking
Akka


                             Replying

def receive = {
 case "ping"    sender ! "pong"
 ...



                                  Asking

val future1 = pingpongActor ? "ping"
val future2 = pingpongActor.ask("ping")
Example: ActivityStream
Example: ActivityStream

class NotiActor extends Actor {
Example: ActivityStream

class NotiActor extends Actor {
 def sendPush(to: Person, msg: String) {
Example: ActivityStream

class NotiActor extends Actor {
 def sendPush(to: Person, msg: String) {
   println("Send Push [To: %s][Msg: %s]".format(to, msg))
Example: ActivityStream

class NotiActor extends Actor {
 def sendPush(to: Person, msg: String) {
   println("Send Push [To: %s][Msg: %s]".format(to, msg))
 }
Example: ActivityStream

class NotiActor extends Actor {
 def sendPush(to: Person, msg: String) {
   println("Send Push [To: %s][Msg: %s]".format(to, msg))
 }

 def sendEmail(to: Person, msg: String) {
Example: ActivityStream

class NotiActor extends Actor {
 def sendPush(to: Person, msg: String) {
   println("Send Push [To: %s][Msg: %s]".format(to, msg))
 }

 def sendEmail(to: Person, msg: String) {
  println("Send Email [To: %s][Msg: %s]".format(to, msg))
Example: ActivityStream

class NotiActor extends Actor {
 def sendPush(to: Person, msg: String) {
   println("Send Push [To: %s][Msg: %s]".format(to, msg))
 }

 def sendEmail(to: Person, msg: String) {
   println("Send Email [To: %s][Msg: %s]".format(to, msg))
 }
Example: ActivityStream

class NotiActor extends Actor {
 def sendPush(to: Person, msg: String) {
   println("Send Push [To: %s][Msg: %s]".format(to, msg))
 }

 def sendEmail(to: Person, msg: String) {
   println("Send Email [To: %s][Msg: %s]".format(to, msg))
 }

 def receive = {
Example: ActivityStream

class NotiActor extends Actor {
 def sendPush(to: Person, msg: String) {
   println("Send Push [To: %s][Msg: %s]".format(to, msg))
 }

 def sendEmail(to: Person, msg: String) {
   println("Send Email [To: %s][Msg: %s]".format(to, msg))
 }

 def receive = {
  case Person(name, _) like Post(author, _) =>
Example: ActivityStream

class NotiActor extends Actor {
 def sendPush(to: Person, msg: String) {
   println("Send Push [To: %s][Msg: %s]".format(to, msg))
 }

 def sendEmail(to: Person, msg: String) {
   println("Send Email [To: %s][Msg: %s]".format(to, msg))
 }

 def receive = {
  case Person(name, _) like Post(author, _) =>
   sendPush(author, "%s likes your post".format(name))
Example: ActivityStream

class NotiActor extends Actor {
 def sendPush(to: Person, msg: String) {
   println("Send Push [To: %s][Msg: %s]".format(to, msg))
 }

 def sendEmail(to: Person, msg: String) {
   println("Send Email [To: %s][Msg: %s]".format(to, msg))
 }

 def receive = {
  case Person(name, _) like Post(author, _) =>
   sendPush(author, "%s likes your post".format(name))
  case (someone@Person(name, _)) write _ =>
Example: ActivityStream

class NotiActor extends Actor {
 def sendPush(to: Person, msg: String) {
   println("Send Push [To: %s][Msg: %s]".format(to, msg))
 }

 def sendEmail(to: Person, msg: String) {
   println("Send Email [To: %s][Msg: %s]".format(to, msg))
 }

 def receive = {
  case Person(name, _) like Post(author, _) =>
   sendPush(author, "%s likes your post".format(name))
  case (someone@Person(name, _)) write _ =>
   someone.followers.foreach{
Example: ActivityStream

class NotiActor extends Actor {
 def sendPush(to: Person, msg: String) {
   println("Send Push [To: %s][Msg: %s]".format(to, msg))
 }

 def sendEmail(to: Person, msg: String) {
   println("Send Email [To: %s][Msg: %s]".format(to, msg))
 }

 def receive = {
  case Person(name, _) like Post(author, _) =>
   sendPush(author, "%s likes your post".format(name))
  case (someone@Person(name, _)) write _ =>
   someone.followers.foreach{
     p =>
Example: ActivityStream

class NotiActor extends Actor {
 def sendPush(to: Person, msg: String) {
   println("Send Push [To: %s][Msg: %s]".format(to, msg))
 }

 def sendEmail(to: Person, msg: String) {
   println("Send Email [To: %s][Msg: %s]".format(to, msg))
 }

 def receive = {
  case Person(name, _) like Post(author, _) =>
   sendPush(author, "%s likes your post".format(name))
  case (someone@Person(name, _)) write _ =>
   someone.followers.foreach{
     p =>
      sendEmail(p,
Example: ActivityStream

class NotiActor extends Actor {
 def sendPush(to: Person, msg: String) {
   println("Send Push [To: %s][Msg: %s]".format(to, msg))
 }

 def sendEmail(to: Person, msg: String) {
   println("Send Email [To: %s][Msg: %s]".format(to, msg))
 }

 def receive = {
  case Person(name, _) like Post(author, _) =>
   sendPush(author, "%s likes your post".format(name))
  case (someone@Person(name, _)) write _ =>
   someone.followers.foreach{
     p =>
      sendEmail(p,
       "Your friend(%s) write new post".format(name))
Example: ActivityStream

class NotiActor extends Actor {
 def sendPush(to: Person, msg: String) {
   println("Send Push [To: %s][Msg: %s]".format(to, msg))
 }

 def sendEmail(to: Person, msg: String) {
   println("Send Email [To: %s][Msg: %s]".format(to, msg))
 }

 def receive = {
  case Person(name, _) like Post(author, _) =>
   sendPush(author, "%s likes your post".format(name))
  case (someone@Person(name, _)) write _ =>
   someone.followers.foreach{
     p =>
      sendEmail(p,
       "Your friend(%s) write new post".format(name))
   }
Example: ActivityStream

class NotiActor extends Actor {
 def sendPush(to: Person, msg: String) {
   println("Send Push [To: %s][Msg: %s]".format(to, msg))
 }

 def sendEmail(to: Person, msg: String) {
   println("Send Email [To: %s][Msg: %s]".format(to, msg))
 }

 def receive = {
   case Person(name, _) like Post(author, _) =>
    sendPush(author, "%s likes your post".format(name))
   case (someone@Person(name, _)) write _ =>
    someone.followers.foreach{
      p =>
       sendEmail(p,
        "Your friend(%s) write new post".format(name))
    }
 }
Example: ActivityStream

class NotiActor extends Actor {
 def sendPush(to: Person, msg: String) {
   println("Send Push [To: %s][Msg: %s]".format(to, msg))
 }

    def sendEmail(to: Person, msg: String) {
      println("Send Email [To: %s][Msg: %s]".format(to, msg))
    }

    def receive = {
      case Person(name, _) like Post(author, _) =>
       sendPush(author, "%s likes your post".format(name))
      case (someone@Person(name, _)) write _ =>
       someone.followers.foreach{
         p =>
          sendEmail(p,
           "Your friend(%s) write new post".format(name))
       }
    }
}
Example: ActivityStream


Sending activities
Example: ActivityStream


                    Sending activities

val jane = Person("Jane", 59)
Example: ActivityStream


                    Sending activities

val jane = Person("Jane", 59)
val charles = Person("Charles", 50)
Example: ActivityStream


                     Sending activities

val jane = Person("Jane", 59)
val charles = Person("Charles", 50)
val post = Post(jane, "hello, world")
Example: ActivityStream


                     Sending activities

val jane = Person("Jane", 59)
val charles = Person("Charles", 50)
val post = Post(jane, "hello, world")

val system = ActorSystem("ActivityStream")
Example: ActivityStream


                     Sending activities

val jane = Person("Jane", 59)
val charles = Person("Charles", 50)
val post = Post(jane, "hello, world")

val system = ActorSystem("ActivityStream")
val notiActor = system.actorOf(
Example: ActivityStream


                     Sending activities

val jane = Person("Jane", 59)
val charles = Person("Charles", 50)
val post = Post(jane, "hello, world")

val system = ActorSystem("ActivityStream")
val notiActor = system.actorOf(
 Props[NotiActor], "notification")
Example: ActivityStream


                     Sending activities

val jane = Person("Jane", 59)
val charles = Person("Charles", 50)
val post = Post(jane, "hello, world")

val system = ActorSystem("ActivityStream")
val notiActor = system.actorOf(
 Props[NotiActor], "notification")

notiActor ! (jane write post)
Example: ActivityStream


                      Sending activities

val jane = Person("Jane", 59)
val charles = Person("Charles", 50)
val post = Post(jane, "hello, world")

val system = ActorSystem("ActivityStream")
val notiActor = system.actorOf(
 Props[NotiActor], "notification")

notiActor ! (jane write post)
notiActor ! (charles like post)
Example: ActivityStream


Scale Up (Concurrency)
Example: ActivityStream


              Scale Up (Concurrency)

val notiActor = system.actorOf(
 Props[NotiActor].withRouter(RoundRobinRouter(5))
 "notication")
Example: ActivityStream


              Scale Up (Concurrency)

val notiActor = system.actorOf(
 Props[NotiActor].withRouter(RoundRobinRouter(5))
 "notication")




val notiActor = system.actorOf(
 Props[NotiActor].withRouter(SmallestMailboxRouter(5))
 "notication")
Example: ActivityStream


Scale Out (Remoting)
Example: ActivityStream


                Scale Out (Remoting)

val notiActor = context.actorFor(
  "akka://activity@192.168.10.2:2552/user/notification")
Example: ActivityStream


                 Scale Out (Remoting)

val notiActor = context.actorFor(
  "akka://activity@192.168.10.2:2552/user/notification")




val notiActor = context.actorFor(
  "cluster://acitivties/notification")
Example: ActivityStream


                 Scale Out (Remoting)

val notiActor = context.actorFor(
  "akka://activity@192.168.10.2:2552/user/notification")




val notiActor = context.actorFor(
  "cluster://acitivties/notification")



                                          Location Transparency
                                              coming soon !
Example: ActivityStream


                 Scale Out (Remoting)

val notiActor = context.actorFor(
  "akka://activity@192.168.10.2:2552/user/notification")




val notiActor = context.actorFor(
  "cluster://acitivties/notification")   ?


                                            Location Transparency
                                                coming soon !
Akka


            More Usage
Event Bus
Scheduler
Fault Tolerance
STM (Software Transactional Memory)
FSM (Finite State Machine)
Asynchronous IO
Extensions for ZeroMQ, Camel, ...
Scala?
더 강력한 표현력
더 강력한 동시성 처리
기존 JVM 기반 환경 재사
       용
다른 언어는
같은 문제를
다른 방법으로
해결합니다
참고문헌과 더 읽을 거리들


    Programming in Scala, 2nd edition
✓   http://www.artima.com/shop/programming_in_scala_2ed

    http://www.scala-lang.org/
    http://doc.akka.io/docs/akka/2.0.3/
    http://en.wikipedia.org/wiki/Scala
    http://en.wikipedia.org/wiki/Functional_programming
    http://en.wikipedia.org/wiki/Actor_model
    http://twitter.github.com/scala_school/
    꽃보다 Scala(long version)
✓   https://docs.google.com/document/pub?
    id=1kSNKKKwM8rjGhn9Gnw-6Q0VCImpwSRZ7_QzwNwXgMxM

    http://blog.typesafe.com/scala-on-heroku
    Seven Languages in Seven Weeks
✓   http://www.amazon.co.uk/Seven-Languages-Weeks-Programming-Programmers/dp/193435659X
참고문헌과 더 읽을 거리들



    Functional
  Programming
Principles in Scala
    https://
www.coursera.org/
 course/progfun
  by Martin Odersky, the creator of Scala
Q&A

Weitere ähnliche Inhalte

Was ist angesagt?

Java Virtual Machine, Call stack, Java Byte Code
Java Virtual Machine, Call stack, Java Byte CodeJava Virtual Machine, Call stack, Java Byte Code
Java Virtual Machine, Call stack, Java Byte CodeJavajigi Jaesung
 
ORM을 활용할 경우의 설계, 개발 과정
ORM을 활용할 경우의 설계, 개발 과정ORM을 활용할 경우의 설계, 개발 과정
ORM을 활용할 경우의 설계, 개발 과정Javajigi Jaesung
 
[세미나] 20160819 Java 프로그래머를 위한 Scala 튜토리얼
[세미나] 20160819 Java 프로그래머를 위한 Scala 튜토리얼[세미나] 20160819 Java 프로그래머를 위한 Scala 튜토리얼
[세미나] 20160819 Java 프로그래머를 위한 Scala 튜토리얼Sanghoon Yoon
 
Java collections framework
Java collections frameworkJava collections framework
Java collections framework경주 전
 
Apache Htrace overview (20160520)
Apache Htrace overview (20160520)Apache Htrace overview (20160520)
Apache Htrace overview (20160520)Steve Min
 
Spring data jpa
Spring data jpaSpring data jpa
Spring data jpaTaesin Um
 
Oop design principle
Oop design principleOop design principle
Oop design principleRyan Park
 

Was ist angesagt? (12)

Java Virtual Machine, Call stack, Java Byte Code
Java Virtual Machine, Call stack, Java Byte CodeJava Virtual Machine, Call stack, Java Byte Code
Java Virtual Machine, Call stack, Java Byte Code
 
ORM을 활용할 경우의 설계, 개발 과정
ORM을 활용할 경우의 설계, 개발 과정ORM을 활용할 경우의 설계, 개발 과정
ORM을 활용할 경우의 설계, 개발 과정
 
Java 기초
Java 기초Java 기초
Java 기초
 
Scalability
ScalabilityScalability
Scalability
 
[세미나] 20160819 Java 프로그래머를 위한 Scala 튜토리얼
[세미나] 20160819 Java 프로그래머를 위한 Scala 튜토리얼[세미나] 20160819 Java 프로그래머를 위한 Scala 튜토리얼
[세미나] 20160819 Java 프로그래머를 위한 Scala 튜토리얼
 
Java extends
Java extendsJava extends
Java extends
 
Java collections framework
Java collections frameworkJava collections framework
Java collections framework
 
HTTP web server 구현
HTTP web server 구현HTTP web server 구현
HTTP web server 구현
 
Apache Htrace overview (20160520)
Apache Htrace overview (20160520)Apache Htrace overview (20160520)
Apache Htrace overview (20160520)
 
Java class
Java classJava class
Java class
 
Spring data jpa
Spring data jpaSpring data jpa
Spring data jpa
 
Oop design principle
Oop design principleOop design principle
Oop design principle
 

Andere mochten auch

함수형 프로그래밍 언어 스칼라(Scala) 소개
함수형 프로그래밍 언어 스칼라(Scala) 소개함수형 프로그래밍 언어 스칼라(Scala) 소개
함수형 프로그래밍 언어 스칼라(Scala) 소개DongHee Kim
 
Scala스터디 - 배열사용하기
Scala스터디 - 배열사용하기Scala스터디 - 배열사용하기
Scala스터디 - 배열사용하기창규 김
 
[A4]de view2012 scala-michinisougu
[A4]de view2012 scala-michinisougu[A4]de view2012 scala-michinisougu
[A4]de view2012 scala-michinisouguNAVER D2
 
SK플래닛 M&C부문 D-spark #6 Social TV
SK플래닛 M&C부문 D-spark #6 Social TVSK플래닛 M&C부문 D-spark #6 Social TV
SK플래닛 M&C부문 D-spark #6 Social TVD:rink
 
D spark Season2 3rd_뭐든지 인식하는 recognition 기술
D spark Season2 3rd_뭐든지 인식하는 recognition 기술D spark Season2 3rd_뭐든지 인식하는 recognition 기술
D spark Season2 3rd_뭐든지 인식하는 recognition 기술D:rink
 
SK플래닛 M&C부문 D-spark #5 Digital Attraction, Digital Themepark
SK플래닛 M&C부문 D-spark #5 Digital Attraction, Digital Themepark  SK플래닛 M&C부문 D-spark #5 Digital Attraction, Digital Themepark
SK플래닛 M&C부문 D-spark #5 Digital Attraction, Digital Themepark D:rink
 
Legacy System에 BigData적용하기 (DevOn발표자료_1027)
Legacy System에 BigData적용하기 (DevOn발표자료_1027)Legacy System에 BigData적용하기 (DevOn발표자료_1027)
Legacy System에 BigData적용하기 (DevOn발표자료_1027)Tae Young Lee
 
SK플래닛 M&C부문 D-spark #9 “디지털・소셜 시대, 컨텐츠 마케팅 째려보기”
SK플래닛 M&C부문 D-spark #9 “디지털・소셜 시대, 컨텐츠 마케팅 째려보기”SK플래닛 M&C부문 D-spark #9 “디지털・소셜 시대, 컨텐츠 마케팅 째려보기”
SK플래닛 M&C부문 D-spark #9 “디지털・소셜 시대, 컨텐츠 마케팅 째려보기”D:rink
 
Apache kafka intro_20150313_springloops
Apache kafka intro_20150313_springloopsApache kafka intro_20150313_springloops
Apache kafka intro_20150313_springloopsSungMin OH
 
CS152 Programming Paradigm
CS152 Programming Paradigm CS152 Programming Paradigm
CS152 Programming Paradigm Kaya Ota
 
Hot Trend Lambda Expressions, Compare C# With Java
Hot Trend Lambda Expressions, Compare C# With JavaHot Trend Lambda Expressions, Compare C# With Java
Hot Trend Lambda Expressions, Compare C# With JavaDexter Jung
 
Programming Paradigm
Programming ParadigmProgramming Paradigm
Programming ParadigmSabahtHussein
 
D spark Season2 2nd적정기술과비즈니스
D spark Season2 2nd적정기술과비즈니스D spark Season2 2nd적정기술과비즈니스
D spark Season2 2nd적정기술과비즈니스D:rink
 
자바 전문가를 위한 스칼라 프로그래밍 언어
자바 전문가를 위한 스칼라 프로그래밍 언어자바 전문가를 위한 스칼라 프로그래밍 언어
자바 전문가를 위한 스칼라 프로그래밍 언어Jong Wook Kim
 
D spark Season2 4th_retail이 technology를 만났을 때
D spark Season2 4th_retail이 technology를 만났을 때D spark Season2 4th_retail이 technology를 만났을 때
D spark Season2 4th_retail이 technology를 만났을 때D:rink
 
15. 생각의 탄생 생각도구 13 통합
15. 생각의 탄생 생각도구 13 통합15. 생각의 탄생 생각도구 13 통합
15. 생각의 탄생 생각도구 13 통합hansei university
 
격변하는 프로그래밍 언어, 이제는 Let it go
격변하는 프로그래밍 언어, 이제는 Let it go격변하는 프로그래밍 언어, 이제는 Let it go
격변하는 프로그래밍 언어, 이제는 Let it goChris Ohk
 
5. 생각의 탄생 생각도구 3 추상화
5. 생각의 탄생 생각도구 3 추상화5. 생각의 탄생 생각도구 3 추상화
5. 생각의 탄생 생각도구 3 추상화hansei university
 

Andere mochten auch (20)

함수형 프로그래밍 언어 스칼라(Scala) 소개
함수형 프로그래밍 언어 스칼라(Scala) 소개함수형 프로그래밍 언어 스칼라(Scala) 소개
함수형 프로그래밍 언어 스칼라(Scala) 소개
 
Scala스터디 - 배열사용하기
Scala스터디 - 배열사용하기Scala스터디 - 배열사용하기
Scala스터디 - 배열사용하기
 
[A4]de view2012 scala-michinisougu
[A4]de view2012 scala-michinisougu[A4]de view2012 scala-michinisougu
[A4]de view2012 scala-michinisougu
 
SK플래닛 M&C부문 D-spark #6 Social TV
SK플래닛 M&C부문 D-spark #6 Social TVSK플래닛 M&C부문 D-spark #6 Social TV
SK플래닛 M&C부문 D-spark #6 Social TV
 
D spark Season2 3rd_뭐든지 인식하는 recognition 기술
D spark Season2 3rd_뭐든지 인식하는 recognition 기술D spark Season2 3rd_뭐든지 인식하는 recognition 기술
D spark Season2 3rd_뭐든지 인식하는 recognition 기술
 
SK플래닛 M&C부문 D-spark #5 Digital Attraction, Digital Themepark
SK플래닛 M&C부문 D-spark #5 Digital Attraction, Digital Themepark  SK플래닛 M&C부문 D-spark #5 Digital Attraction, Digital Themepark
SK플래닛 M&C부문 D-spark #5 Digital Attraction, Digital Themepark
 
Legacy System에 BigData적용하기 (DevOn발표자료_1027)
Legacy System에 BigData적용하기 (DevOn발표자료_1027)Legacy System에 BigData적용하기 (DevOn발표자료_1027)
Legacy System에 BigData적용하기 (DevOn발표자료_1027)
 
SK플래닛 M&C부문 D-spark #9 “디지털・소셜 시대, 컨텐츠 마케팅 째려보기”
SK플래닛 M&C부문 D-spark #9 “디지털・소셜 시대, 컨텐츠 마케팅 째려보기”SK플래닛 M&C부문 D-spark #9 “디지털・소셜 시대, 컨텐츠 마케팅 째려보기”
SK플래닛 M&C부문 D-spark #9 “디지털・소셜 시대, 컨텐츠 마케팅 째려보기”
 
Apache kafka intro_20150313_springloops
Apache kafka intro_20150313_springloopsApache kafka intro_20150313_springloops
Apache kafka intro_20150313_springloops
 
CS152 Programming Paradigm
CS152 Programming Paradigm CS152 Programming Paradigm
CS152 Programming Paradigm
 
Java start01 in 2hours
Java start01 in 2hoursJava start01 in 2hours
Java start01 in 2hours
 
Hot Trend Lambda Expressions, Compare C# With Java
Hot Trend Lambda Expressions, Compare C# With JavaHot Trend Lambda Expressions, Compare C# With Java
Hot Trend Lambda Expressions, Compare C# With Java
 
Programming Paradigm
Programming ParadigmProgramming Paradigm
Programming Paradigm
 
D spark Season2 2nd적정기술과비즈니스
D spark Season2 2nd적정기술과비즈니스D spark Season2 2nd적정기술과비즈니스
D spark Season2 2nd적정기술과비즈니스
 
자바 전문가를 위한 스칼라 프로그래밍 언어
자바 전문가를 위한 스칼라 프로그래밍 언어자바 전문가를 위한 스칼라 프로그래밍 언어
자바 전문가를 위한 스칼라 프로그래밍 언어
 
Standard Algorithms
Standard AlgorithmsStandard Algorithms
Standard Algorithms
 
D spark Season2 4th_retail이 technology를 만났을 때
D spark Season2 4th_retail이 technology를 만났을 때D spark Season2 4th_retail이 technology를 만났을 때
D spark Season2 4th_retail이 technology를 만났을 때
 
15. 생각의 탄생 생각도구 13 통합
15. 생각의 탄생 생각도구 13 통합15. 생각의 탄생 생각도구 13 통합
15. 생각의 탄생 생각도구 13 통합
 
격변하는 프로그래밍 언어, 이제는 Let it go
격변하는 프로그래밍 언어, 이제는 Let it go격변하는 프로그래밍 언어, 이제는 Let it go
격변하는 프로그래밍 언어, 이제는 Let it go
 
5. 생각의 탄생 생각도구 3 추상화
5. 생각의 탄생 생각도구 3 추상화5. 생각의 탄생 생각도구 3 추상화
5. 생각의 탄생 생각도구 3 추상화
 

Ähnlich wie [H3 2012] 꽃보다 Scala

Scala, Scalability
Scala, ScalabilityScala, Scalability
Scala, ScalabilityDongwook Lee
 
Gradle 한번 살펴보기
Gradle 한번 살펴보기Gradle 한번 살펴보기
Gradle 한번 살펴보기Junseo Youn
 
2.apache spark 실습
2.apache spark 실습2.apache spark 실습
2.apache spark 실습동현 강
 
Zeppelin(Spark)으로 데이터 분석하기
Zeppelin(Spark)으로 데이터 분석하기Zeppelin(Spark)으로 데이터 분석하기
Zeppelin(Spark)으로 데이터 분석하기SangWoo Kim
 
Scala, Spring-Boot, JPA의 불편하면서도 즐거운 동거
Scala, Spring-Boot, JPA의 불편하면서도 즐거운 동거Scala, Spring-Boot, JPA의 불편하면서도 즐거운 동거
Scala, Spring-Boot, JPA의 불편하면서도 즐거운 동거Javajigi Jaesung
 
안드로이드 빌드: 설탕없는 세계
안드로이드 빌드: 설탕없는 세계안드로이드 빌드: 설탕없는 세계
안드로이드 빌드: 설탕없는 세계Leonardo YongUk Kim
 
Java9 특징 훑어보기
Java9 특징 훑어보기Java9 특징 훑어보기
Java9 특징 훑어보기duriepark 유현석
 
Isomorphicspring Isomorphic - spring web seminar 2015
Isomorphicspring Isomorphic - spring web seminar 2015Isomorphicspring Isomorphic - spring web seminar 2015
Isomorphicspring Isomorphic - spring web seminar 2015sung yong jung
 
스파르탄Js in sidejs5
스파르탄Js in sidejs5스파르탄Js in sidejs5
스파르탄Js in sidejs5Jin-Hyun Park
 
[236] 카카오의데이터파이프라인 윤도영
[236] 카카오의데이터파이프라인 윤도영[236] 카카오의데이터파이프라인 윤도영
[236] 카카오의데이터파이프라인 윤도영NAVER D2
 
Introduction to Fork Join Framework_SYS4U I&C
Introduction to Fork Join Framework_SYS4U I&CIntroduction to Fork Join Framework_SYS4U I&C
Introduction to Fork Join Framework_SYS4U I&Csys4u
 
Spring Boot + React + Gradle in VSCode
Spring Boot + React + Gradle in VSCodeSpring Boot + React + Gradle in VSCode
Spring Boot + React + Gradle in VSCodedpTablo
 
How to use apache spark (based on the java example)
How to use apache spark (based on the java example)How to use apache spark (based on the java example)
How to use apache spark (based on the java example)월간 IT 슬라이드
 
레일스를 이용한 애자일 웹 개발 가이드
레일스를 이용한 애자일 웹 개발 가이드레일스를 이용한 애자일 웹 개발 가이드
레일스를 이용한 애자일 웹 개발 가이드Sukjoon Kim
 
Hancom MDS Conference - KAKAO DEVOPS Practice (카카오 스토리의 Devops 사례)
Hancom MDS Conference - KAKAO DEVOPS Practice (카카오 스토리의 Devops 사례)Hancom MDS Conference - KAKAO DEVOPS Practice (카카오 스토리의 Devops 사례)
Hancom MDS Conference - KAKAO DEVOPS Practice (카카오 스토리의 Devops 사례)knight1128
 
올챙이 현재와 미래
올챙이 현재와 미래올챙이 현재와 미래
올챙이 현재와 미래cho hyun jong
 

Ähnlich wie [H3 2012] 꽃보다 Scala (20)

Scala, Scalability
Scala, ScalabilityScala, Scalability
Scala, Scalability
 
Gradle 한번 살펴보기
Gradle 한번 살펴보기Gradle 한번 살펴보기
Gradle 한번 살펴보기
 
2.apache spark 실습
2.apache spark 실습2.apache spark 실습
2.apache spark 실습
 
Zeppelin(Spark)으로 데이터 분석하기
Zeppelin(Spark)으로 데이터 분석하기Zeppelin(Spark)으로 데이터 분석하기
Zeppelin(Spark)으로 데이터 분석하기
 
Scala, Spring-Boot, JPA의 불편하면서도 즐거운 동거
Scala, Spring-Boot, JPA의 불편하면서도 즐거운 동거Scala, Spring-Boot, JPA의 불편하면서도 즐거운 동거
Scala, Spring-Boot, JPA의 불편하면서도 즐거운 동거
 
안드로이드 빌드: 설탕없는 세계
안드로이드 빌드: 설탕없는 세계안드로이드 빌드: 설탕없는 세계
안드로이드 빌드: 설탕없는 세계
 
JDK 변천사
JDK 변천사JDK 변천사
JDK 변천사
 
Java9 특징 훑어보기
Java9 특징 훑어보기Java9 특징 훑어보기
Java9 특징 훑어보기
 
Isomorphicspring Isomorphic - spring web seminar 2015
Isomorphicspring Isomorphic - spring web seminar 2015Isomorphicspring Isomorphic - spring web seminar 2015
Isomorphicspring Isomorphic - spring web seminar 2015
 
스파르탄Js in sidejs5
스파르탄Js in sidejs5스파르탄Js in sidejs5
스파르탄Js in sidejs5
 
[236] 카카오의데이터파이프라인 윤도영
[236] 카카오의데이터파이프라인 윤도영[236] 카카오의데이터파이프라인 윤도영
[236] 카카오의데이터파이프라인 윤도영
 
Introduction to Fork Join Framework_SYS4U I&C
Introduction to Fork Join Framework_SYS4U I&CIntroduction to Fork Join Framework_SYS4U I&C
Introduction to Fork Join Framework_SYS4U I&C
 
Spring Boot + React + Gradle in VSCode
Spring Boot + React + Gradle in VSCodeSpring Boot + React + Gradle in VSCode
Spring Boot + React + Gradle in VSCode
 
How to use apache spark (based on the java example)
How to use apache spark (based on the java example)How to use apache spark (based on the java example)
How to use apache spark (based on the java example)
 
레일스를 이용한 애자일 웹 개발 가이드
레일스를 이용한 애자일 웹 개발 가이드레일스를 이용한 애자일 웹 개발 가이드
레일스를 이용한 애자일 웹 개발 가이드
 
4-1. javascript
4-1. javascript4-1. javascript
4-1. javascript
 
Java the good parts
Java the good partsJava the good parts
Java the good parts
 
Hancom MDS Conference - KAKAO DEVOPS Practice (카카오 스토리의 Devops 사례)
Hancom MDS Conference - KAKAO DEVOPS Practice (카카오 스토리의 Devops 사례)Hancom MDS Conference - KAKAO DEVOPS Practice (카카오 스토리의 Devops 사례)
Hancom MDS Conference - KAKAO DEVOPS Practice (카카오 스토리의 Devops 사례)
 
Apache Spark
Apache SparkApache Spark
Apache Spark
 
올챙이 현재와 미래
올챙이 현재와 미래올챙이 현재와 미래
올챙이 현재와 미래
 

Mehr von KTH, 케이티하이텔

[발표자료]안드로메다에서 온 디자이너이야기 5차 next_web_지훈_20130221
[발표자료]안드로메다에서 온 디자이너이야기 5차 next_web_지훈_20130221[발표자료]안드로메다에서 온 디자이너이야기 5차 next_web_지훈_20130221
[발표자료]안드로메다에서 온 디자이너이야기 5차 next_web_지훈_20130221KTH, 케이티하이텔
 
KTH_Detail day_안드로메다에서 온 디자이너이야기_3차_디자인기본요소_박지환
KTH_Detail day_안드로메다에서 온 디자이너이야기_3차_디자인기본요소_박지환KTH_Detail day_안드로메다에서 온 디자이너이야기_3차_디자인기본요소_박지환
KTH_Detail day_안드로메다에서 온 디자이너이야기_3차_디자인기본요소_박지환KTH, 케이티하이텔
 
KTH_Detail day_안드로메다에서 온 디자이너이야기_2차(2)_디자인사례_정덕주
KTH_Detail day_안드로메다에서 온 디자이너이야기_2차(2)_디자인사례_정덕주KTH_Detail day_안드로메다에서 온 디자이너이야기_2차(2)_디자인사례_정덕주
KTH_Detail day_안드로메다에서 온 디자이너이야기_2차(2)_디자인사례_정덕주KTH, 케이티하이텔
 
KTH_Detail day_안드로메다에서 온 디자이너이야기_2차(1)_디자인프로세스,협업_한재기
KTH_Detail day_안드로메다에서 온 디자이너이야기_2차(1)_디자인프로세스,협업_한재기KTH_Detail day_안드로메다에서 온 디자이너이야기_2차(1)_디자인프로세스,협업_한재기
KTH_Detail day_안드로메다에서 온 디자이너이야기_2차(1)_디자인프로세스,협업_한재기KTH, 케이티하이텔
 
KTH_Detail day_안드로메다에서 온 디자이너이야기_1차_디자인용어_지훈
KTH_Detail day_안드로메다에서 온 디자이너이야기_1차_디자인용어_지훈KTH_Detail day_안드로메다에서 온 디자이너이야기_1차_디자인용어_지훈
KTH_Detail day_안드로메다에서 온 디자이너이야기_1차_디자인용어_지훈KTH, 케이티하이텔
 
[H3 2012] 내컴에선 잘되던데? - vagrant로 서버와 동일한 개발환경 꾸미기
[H3 2012] 내컴에선 잘되던데? - vagrant로 서버와 동일한 개발환경 꾸미기[H3 2012] 내컴에선 잘되던데? - vagrant로 서버와 동일한 개발환경 꾸미기
[H3 2012] 내컴에선 잘되던데? - vagrant로 서버와 동일한 개발환경 꾸미기KTH, 케이티하이텔
 
[H3 2012] Open API 와 Ruby on Rails 에 대한 이야기
[H3 2012] Open API 와 Ruby on Rails 에 대한 이야기[H3 2012] Open API 와 Ruby on Rails 에 대한 이야기
[H3 2012] Open API 와 Ruby on Rails 에 대한 이야기KTH, 케이티하이텔
 
[H3 2012] Bridge over troubled water : make plug-in for Appspresso
[H3 2012] Bridge over troubled water : make plug-in for Appspresso[H3 2012] Bridge over troubled water : make plug-in for Appspresso
[H3 2012] Bridge over troubled water : make plug-in for AppspressoKTH, 케이티하이텔
 
[H3 2012] 스마트모바일 환경에서의 App.품질관리전략
[H3 2012] 스마트모바일 환경에서의 App.품질관리전략[H3 2012] 스마트모바일 환경에서의 App.품질관리전략
[H3 2012] 스마트모바일 환경에서의 App.품질관리전략KTH, 케이티하이텔
 
[H3 2012] 스타트업 개발사의 생존필수 아이템, BaaS 모바일 고객센터
[H3 2012] 스타트업 개발사의 생존필수 아이템, BaaS 모바일 고객센터[H3 2012] 스타트업 개발사의 생존필수 아이템, BaaS 모바일 고객센터
[H3 2012] 스타트업 개발사의 생존필수 아이템, BaaS 모바일 고객센터KTH, 케이티하이텔
 
[H3 2012] Local based SNS를 이용한 타겟 마케팅
[H3 2012] Local based SNS를 이용한 타겟 마케팅[H3 2012] Local based SNS를 이용한 타겟 마케팅
[H3 2012] Local based SNS를 이용한 타겟 마케팅KTH, 케이티하이텔
 
[H3 2012] 오픈소스로 개발 실력 쌓기
[H3 2012] 오픈소스로 개발 실력 쌓기[H3 2012] 오픈소스로 개발 실력 쌓기
[H3 2012] 오픈소스로 개발 실력 쌓기KTH, 케이티하이텔
 
[H3 2012] 앱(APP) 중심으로 생각하기 - DevOps와 자동화
[H3 2012] 앱(APP) 중심으로 생각하기 - DevOps와 자동화[H3 2012] 앱(APP) 중심으로 생각하기 - DevOps와 자동화
[H3 2012] 앱(APP) 중심으로 생각하기 - DevOps와 자동화KTH, 케이티하이텔
 
[H3 2012] 하이브리드앱 제작 사례 공유 - 푸딩얼굴인식 3.0
[H3 2012] 하이브리드앱 제작 사례 공유 - 푸딩얼굴인식 3.0[H3 2012] 하이브리드앱 제작 사례 공유 - 푸딩얼굴인식 3.0
[H3 2012] 하이브리드앱 제작 사례 공유 - 푸딩얼굴인식 3.0KTH, 케이티하이텔
 
[H3 2012] Cloud Database Service - Hulahoop를 소개합니다.
[H3 2012] Cloud Database Service - Hulahoop를 소개합니다.[H3 2012] Cloud Database Service - Hulahoop를 소개합니다.
[H3 2012] Cloud Database Service - Hulahoop를 소개합니다.KTH, 케이티하이텔
 
[H3 2012] 기획/디자인/개발자 모두 알아야 하는 '대박앱의 비밀'
[H3 2012] 기획/디자인/개발자 모두 알아야 하는 '대박앱의 비밀'[H3 2012] 기획/디자인/개발자 모두 알아야 하는 '대박앱의 비밀'
[H3 2012] 기획/디자인/개발자 모두 알아야 하는 '대박앱의 비밀'KTH, 케이티하이텔
 
[H3 2012] OAuth2 - API 인증을위한 만능 도구상자
[H3 2012] OAuth2 - API 인증을위한 만능 도구상자[H3 2012] OAuth2 - API 인증을위한 만능 도구상자
[H3 2012] OAuth2 - API 인증을위한 만능 도구상자KTH, 케이티하이텔
 
[H3 2012] 오픈 소스로 구현하는 실시간 데이터 처리를 위한 CEP
[H3 2012] 오픈 소스로 구현하는 실시간 데이터 처리를 위한 CEP[H3 2012] 오픈 소스로 구현하는 실시간 데이터 처리를 위한 CEP
[H3 2012] 오픈 소스로 구현하는 실시간 데이터 처리를 위한 CEPKTH, 케이티하이텔
 

Mehr von KTH, 케이티하이텔 (20)

[발표자료]안드로메다에서 온 디자이너이야기 5차 next_web_지훈_20130221
[발표자료]안드로메다에서 온 디자이너이야기 5차 next_web_지훈_20130221[발표자료]안드로메다에서 온 디자이너이야기 5차 next_web_지훈_20130221
[발표자료]안드로메다에서 온 디자이너이야기 5차 next_web_지훈_20130221
 
KTH_Detail day_안드로메다에서 온 디자이너이야기_3차_디자인기본요소_박지환
KTH_Detail day_안드로메다에서 온 디자이너이야기_3차_디자인기본요소_박지환KTH_Detail day_안드로메다에서 온 디자이너이야기_3차_디자인기본요소_박지환
KTH_Detail day_안드로메다에서 온 디자이너이야기_3차_디자인기본요소_박지환
 
KTH_Detail day_안드로메다에서 온 디자이너이야기_2차(2)_디자인사례_정덕주
KTH_Detail day_안드로메다에서 온 디자이너이야기_2차(2)_디자인사례_정덕주KTH_Detail day_안드로메다에서 온 디자이너이야기_2차(2)_디자인사례_정덕주
KTH_Detail day_안드로메다에서 온 디자이너이야기_2차(2)_디자인사례_정덕주
 
KTH_Detail day_안드로메다에서 온 디자이너이야기_2차(1)_디자인프로세스,협업_한재기
KTH_Detail day_안드로메다에서 온 디자이너이야기_2차(1)_디자인프로세스,협업_한재기KTH_Detail day_안드로메다에서 온 디자이너이야기_2차(1)_디자인프로세스,협업_한재기
KTH_Detail day_안드로메다에서 온 디자이너이야기_2차(1)_디자인프로세스,협업_한재기
 
KTH_Detail day_안드로메다에서 온 디자이너이야기_1차_디자인용어_지훈
KTH_Detail day_안드로메다에서 온 디자이너이야기_1차_디자인용어_지훈KTH_Detail day_안드로메다에서 온 디자이너이야기_1차_디자인용어_지훈
KTH_Detail day_안드로메다에서 온 디자이너이야기_1차_디자인용어_지훈
 
[H3 2012] 내컴에선 잘되던데? - vagrant로 서버와 동일한 개발환경 꾸미기
[H3 2012] 내컴에선 잘되던데? - vagrant로 서버와 동일한 개발환경 꾸미기[H3 2012] 내컴에선 잘되던데? - vagrant로 서버와 동일한 개발환경 꾸미기
[H3 2012] 내컴에선 잘되던데? - vagrant로 서버와 동일한 개발환경 꾸미기
 
[H3 2012] Open API 와 Ruby on Rails 에 대한 이야기
[H3 2012] Open API 와 Ruby on Rails 에 대한 이야기[H3 2012] Open API 와 Ruby on Rails 에 대한 이야기
[H3 2012] Open API 와 Ruby on Rails 에 대한 이야기
 
[H3 2012] UX, 애자일하고 싶어요
[H3 2012] UX, 애자일하고 싶어요[H3 2012] UX, 애자일하고 싶어요
[H3 2012] UX, 애자일하고 싶어요
 
[H3 2012] Instant Prototyping with ROR
[H3 2012] Instant Prototyping with ROR[H3 2012] Instant Prototyping with ROR
[H3 2012] Instant Prototyping with ROR
 
[H3 2012] Bridge over troubled water : make plug-in for Appspresso
[H3 2012] Bridge over troubled water : make plug-in for Appspresso[H3 2012] Bridge over troubled water : make plug-in for Appspresso
[H3 2012] Bridge over troubled water : make plug-in for Appspresso
 
[H3 2012] 스마트모바일 환경에서의 App.품질관리전략
[H3 2012] 스마트모바일 환경에서의 App.품질관리전략[H3 2012] 스마트모바일 환경에서의 App.품질관리전략
[H3 2012] 스마트모바일 환경에서의 App.품질관리전략
 
[H3 2012] 스타트업 개발사의 생존필수 아이템, BaaS 모바일 고객센터
[H3 2012] 스타트업 개발사의 생존필수 아이템, BaaS 모바일 고객센터[H3 2012] 스타트업 개발사의 생존필수 아이템, BaaS 모바일 고객센터
[H3 2012] 스타트업 개발사의 생존필수 아이템, BaaS 모바일 고객센터
 
[H3 2012] Local based SNS를 이용한 타겟 마케팅
[H3 2012] Local based SNS를 이용한 타겟 마케팅[H3 2012] Local based SNS를 이용한 타겟 마케팅
[H3 2012] Local based SNS를 이용한 타겟 마케팅
 
[H3 2012] 오픈소스로 개발 실력 쌓기
[H3 2012] 오픈소스로 개발 실력 쌓기[H3 2012] 오픈소스로 개발 실력 쌓기
[H3 2012] 오픈소스로 개발 실력 쌓기
 
[H3 2012] 앱(APP) 중심으로 생각하기 - DevOps와 자동화
[H3 2012] 앱(APP) 중심으로 생각하기 - DevOps와 자동화[H3 2012] 앱(APP) 중심으로 생각하기 - DevOps와 자동화
[H3 2012] 앱(APP) 중심으로 생각하기 - DevOps와 자동화
 
[H3 2012] 하이브리드앱 제작 사례 공유 - 푸딩얼굴인식 3.0
[H3 2012] 하이브리드앱 제작 사례 공유 - 푸딩얼굴인식 3.0[H3 2012] 하이브리드앱 제작 사례 공유 - 푸딩얼굴인식 3.0
[H3 2012] 하이브리드앱 제작 사례 공유 - 푸딩얼굴인식 3.0
 
[H3 2012] Cloud Database Service - Hulahoop를 소개합니다.
[H3 2012] Cloud Database Service - Hulahoop를 소개합니다.[H3 2012] Cloud Database Service - Hulahoop를 소개합니다.
[H3 2012] Cloud Database Service - Hulahoop를 소개합니다.
 
[H3 2012] 기획/디자인/개발자 모두 알아야 하는 '대박앱의 비밀'
[H3 2012] 기획/디자인/개발자 모두 알아야 하는 '대박앱의 비밀'[H3 2012] 기획/디자인/개발자 모두 알아야 하는 '대박앱의 비밀'
[H3 2012] 기획/디자인/개발자 모두 알아야 하는 '대박앱의 비밀'
 
[H3 2012] OAuth2 - API 인증을위한 만능 도구상자
[H3 2012] OAuth2 - API 인증을위한 만능 도구상자[H3 2012] OAuth2 - API 인증을위한 만능 도구상자
[H3 2012] OAuth2 - API 인증을위한 만능 도구상자
 
[H3 2012] 오픈 소스로 구현하는 실시간 데이터 처리를 위한 CEP
[H3 2012] 오픈 소스로 구현하는 실시간 데이터 처리를 위한 CEP[H3 2012] 오픈 소스로 구현하는 실시간 데이터 처리를 위한 CEP
[H3 2012] 오픈 소스로 구현하는 실시간 데이터 처리를 위한 CEP
 

[H3 2012] 꽃보다 Scala

  • 2. “ 만약, 2003년경에 누군가 나에게 Programming in Scala 라는 책을 보여줬다면 나는 절대로 Groovy를 만들지 않았을 것이다 ” James Strachan, the creator of Groovy
  • 3. TOC 1. Scala? 2. Functional Style 3. Pattern Matching 4. Horizontal Scale
  • 5. Scala? object HelloWorld { def main(args:Array[String]){ println("Hello, world!") } }
  • 8. Scala? Quick Scala Facts JVM/.NET 에서 구동되는 범용 multi-paradigm 언 어
  • 9. Scala? Quick Scala Facts JVM/.NET 에서 구동되는 범용 multi-paradigm 언 어 Created by Martin Odersky
  • 10. Scala? Quick Scala Facts JVM/.NET 에서 구동되는 범용 multi-paradigm 언 어 Created by Martin Odersky ✓ EPFL 의 교수
  • 11. Scala? Quick Scala Facts JVM/.NET 에서 구동되는 범용 multi-paradigm 언 어 Created by Martin Odersky ✓ EPFL 의 교수 ✓ javac(Sun’s java compiler)
  • 12. Scala? Quick Scala Facts JVM/.NET 에서 구동되는 범용 multi-paradigm 언 어 Created by Martin Odersky ✓ EPFL 의 교수 ✓ javac(Sun’s java compiler) ✓ Generic Java (“make Java better”)
  • 13. Scala? Quick Scala Facts JVM/.NET 에서 구동되는 범용 multi-paradigm 언 어 Created by Martin Odersky ✓ EPFL 의 교수 ✓ javac(Sun’s java compiler) ✓ Generic Java (“make Java better”) ✓ Since 2001
  • 14. Scala? Quick Scala Facts JVM/.NET 에서 구동되는 범용 multi-paradigm 언 어 Created by Martin Odersky ✓ EPFL 의 교수 ✓ javac(Sun’s java compiler) ✓ Generic Java (“make Java better”) ✓ Since 2001 => 최신 안정화 버전 : 2.9.2 final (2012/04/14)
  • 15. Scala? Quick Scala Facts JVM/.NET 에서 구동되는 범용 multi-paradigm 언 어 Created by Martin Odersky ✓ EPFL 의 교수 ✓ javac(Sun’s java compiler) ✓ Generic Java (“make Java better”) ✓ Since 2001 => 최신 안정화 버전 : 2.9.2 final (2012/04/14) => 개발 버전 : 2.10.0 RC1 (2012/10/19)
  • 18. Scala? Quick Scala Facts 더 짧고 더 명료한 코드
  • 19. Scala? Quick Scala Facts 더 짧고 더 명료한 코드 강력한 표현력과 DSL을 통한 확장성
  • 20. Scala? Quick Scala Facts 더 짧고 더 명료한 코드 강력한 표현력과 DSL을 통한 확장성 Java 와의 상호 운영성
  • 21. Scala? Quick Scala Facts 더 짧고 더 명료한 코드 강력한 표현력과 DSL을 통한 확장성 Java 와의 상호 운영성 강력한 정적 타입 시스템
  • 22. Scala? Quick Scala Facts 더 짧고 더 명료한 코드 강력한 표현력과 DSL을 통한 확장성 Java 와의 상호 운영성 강력한 정적 타입 시스템 객체 지향과 함수형 스타일을 모두 지원
  • 23. Scala? Quick Scala Facts 더 짧고 더 명료한 코드 강력한 표현력과 DSL을 통한 확장성 Java 와의 상호 운영성 강력한 정적 타입 시스템 객체 지향과 함수형 스타일을 모두 지원 동일한 목적의 자바 코드와 동일한 성능
  • 24. Scala? Quick Scala Facts 더 짧고 더 명료한 코드 강력한 표현력과 DSL을 통한 확장성 Java 와의 상호 운영성 강력한 정적 타입 시스템 객체 지향과 함수형 스타일을 모두 지원 동일한 목적의 자바 코드와 동일한 성능 광범위한 상업적 적용
  • 25. Scala? Quick Scala Facts 더 짧고 더 명료한 코드 강력한 표현력과 DSL을 통한 확장성 Java 와의 상호 운영성 강력한 정적 타입 시스템 객체 지향과 함수형 스타일을 모두 지원 동일한 목적의 자바 코드와 동일한 성능 광범위한 상업적 적용 강력한 동시성 처리
  • 26. Scala? Less code 표현의 간결함 자바에 비해 코드 사이즈가 1/3 ~2/3 정도로 감소함 절반의 코드는 ✓ 코드를 이해하는데 절반의 시간이 필요함을 뜻하며 ✓ 버그의 가능성 역시 절반으로 감소함
  • 27. A class... class Person(val name: String, val age: Int) class Person { public final String name; public final int age; public Person(String name, int age) { this.name = name; this.age = age; } }
  • 28. VO/POJO class Person { private final String name; case class Person(name: String, private final int age; age: Int) public Person(String name, int age) { super(); this.name = name; this.age = age; } public String getName() { return name; } public int getAge() { return age; } @Override public boolean equals(Object other) { if (this == other) { return true; } else if (other instanceof Person) { Person p = (Person) other; return name == null ? p.name == null : name.equals(p.name) && age == p.age; } else { return false; } } @Override public int hashCode() { int h = name == null ? 0 : name.hashCode(); return 39 * h + age; } @Override public String toString() { return new StringBuilder("Person(").append(name).append(",").append(age) .append(")").toString(); } }
  • 32. Scala? Great interoperability with Java Scala는 자바와 소스 코드 레벨에서만 다름
  • 33. Scala? Great interoperability with Java Scala는 자바와 소스 코드 레벨에서만 다름 컴파일되면 “.class” 파일이 나옴
  • 34. Scala? Great interoperability with Java Scala는 자바와 소스 코드 레벨에서만 다름 컴파일되면 “.class” 파일이 나옴 Scala코드에서 Java클래스를 그대로 import 해서 사용
  • 35. Scala? Great interoperability with Java Scala는 자바와 소스 코드 레벨에서만 다름 컴파일되면 “.class” 파일이 나옴 Scala코드에서 Java클래스를 그대로 import 해서 사용 한 프로젝트에서 Java와 Scala 파일을 섞어서 사용 가능
  • 36. Scala? Great interoperability with Java Scala는 자바와 소스 코드 레벨에서만 다름 컴파일되면 “.class” 파일이 나옴 Scala코드에서 Java클래스를 그대로 import 해서 사용 한 프로젝트에서 Java와 Scala 파일을 섞어서 사용 가능 Java 가 지원되는 어떤 환경/클라우드에도 배포 가능
  • 37. Scala? Great interoperability with Java Scala는 자바와 소스 코드 레벨에서만 다름 컴파일되면 “.class” 파일이 나옴 Scala코드에서 Java클래스를 그대로 import 해서 사용 한 프로젝트에서 Java와 Scala 파일을 섞어서 사용 가능 Java 가 지원되는 어떤 환경/클라우드에도 배포 가능 그리고 Android ~
  • 38. Great interoperability with Java import java.net._ import java.io._ val u = new URL( "http://www.scala-lang.org/") val in = u.openStream() val br = new BufferedReader( new InputStreamReader(in))
  • 39. Popularity and Use Grow Commercial Adoptions Twitter ✓ 메시지 패싱 시스템을 Ruby에서 Scala 기반으로 변경 ✓ Finagle, Gizzard, Kestrel, ... Linked-in ✓ 소셜 그래프 서비스 (380-400M transaction/day) ✓ Apache Kafka Foursquare ✓ 웹을 포함한 모든 서비스가 Scala로 작성됨 Tumblr ✓ 분산 시스템을 위해 Finagle 선택
  • 40. Programming Language Popularity 1 JavaScript 2 Java 3 PHP 4 Python 5 Ruby 6 C# 7 C++ 8 C 9 Objective-C 10 Shell 11 Perl 12 Scala 13 Haskell 14 ASP 15 Assembly 16 ActionScript 17 R 18 VisualBasic 19 CoffeeScript 20 Groovy 출처: http://redmonk.com/sogrady/2012/09/12/language-rankings-9-12/
  • 41. Scala Job trends 출처: http://www.indeed.com/jobtrends/scala.html
  • 43. LISP, Haskell, Erlang, Clojure 등의 함수형 언어에 익숙하다면 쉽습니다
  • 44. Ruby, Python, Javascript 등의 언어에 익숙하다면 어렵진 않을 겁니다 :)
  • 50. Problems of Java 자바코드 == 대하소설
  • 51. Problems of Java 자바코드 == 대하소설 ✓ 제한된 vocabulary
  • 52. Problems of Java 자바코드 == 대하소설 ✓ 제한된 vocabulary ✓ 수 많은 third party 라이브러리 필수
  • 53. Problems of Java 자바코드 == 대하소설 ✓ 제한된 vocabulary ✓ 수 많은 third party 라이브러리 필수 ✓ 너무 적은 언어의 기능/개념
  • 54. Problems of Java 자바코드 == 대하소설 ✓ 제한된 vocabulary ✓ 수 많은 third party 라이브러리 필수 ✓ 너무 적은 언어의 기능/개념 ✓ Need more syntactic sugars!
  • 55. Problems of Java 자바코드 == 대하소설 ✓ 제한된 vocabulary ✓ 수 많은 third party 라이브러리 필수 ✓ 너무 적은 언어의 기능/개념 ✓ Need more syntactic sugars!
  • 56. Problems of Java 자바코드 == 대하소설 ✓ 제한된 vocabulary ✓ 수 많은 third party 라이브러리 필수 ✓ 너무 적은 언어의 기능/개념 ✓ Need more syntactic sugars! 이미 legacy, 너무 느린 발전 속도
  • 57. Problems of Java 자바코드 == 대하소설 ✓ 제한된 vocabulary ✓ 수 많은 third party 라이브러리 필수 ✓ 너무 적은 언어의 기능/개념 ✓ Need more syntactic sugars! 이미 legacy, 너무 느린 발전 속도 Oracle...
  • 58. Functional Style think f(x)!
  • 59. f(x)?
  • 60. f(x)?
  • 62. Imperative vs Functional
  • 63. 명령형? Imperative style 우리에게 익숙한 그것 :) ✓ C, C++, Java, ... 컴퓨터에게 절차적으로 명령을 내리는 방식 ✓ “x 와 y 를 더하고, 결과를 z에 담고, z를 화면에 출력” Advantages ✓ 본질적으로 컴퓨터는 명령을 받고 수행하는 기계 ✓ 많은 프로그래밍 언어가 명령형이며, 수많은 개발자가 이 방식에 익숙함
  • 66. 함수형? Functional style 값의 변환 transformation 을 강조
  • 67. 함수형? Functional style 값의 변환 transformation 을 강조 ✓ 값을 입력 받고 새로운 값을 리턴함
  • 68. 함수형? Functional style 값의 변환 transformation 을 강조 ✓ 값을 입력 받고 새로운 값을 리턴함 변경 불가능한 상태 immutable state 를 강조
  • 69. 함수형? Functional style 값의 변환 transformation 을 강조 ✓ 값을 입력 받고 새로운 값을 리턴함 변경 불가능한 상태 immutable state 를 강조 ✓ referentially transparent (e.g., java.lang.String)
  • 70. 함수형? Functional style 값의 변환 transformation 을 강조 ✓ 값을 입력 받고 새로운 값을 리턴함 변경 불가능한 상태 immutable state 를 강조 ✓ referentially transparent (e.g., java.lang.String) 부수 효과 없음 no side-effects 을 강조
  • 71. 함수형? Functional style 값의 변환 transformation 을 강조 ✓ 값을 입력 받고 새로운 값을 리턴함 변경 불가능한 상태 immutable state 를 강조 ✓ referentially transparent (e.g., java.lang.String) 부수 효과 없음 no side-effects 을 강조 ✓ 언제 계산 evaluation 을 하던, 같은 값을 리턴
  • 74. 함수형? Functional style 최상위 개념으로서의 함수 first-class function
  • 75. 함수형? Functional style 최상위 개념으로서의 함수 first-class function ✓ “function everywhere”
  • 76. 함수형? Functional style 최상위 개념으로서의 함수 first-class function ✓ “function everywhere” Advantages
  • 77. 함수형? Functional style 최상위 개념으로서의 함수 first-class function ✓ “function everywhere” Advantages ✓ 본질적으로 병렬화가 가능하며 thread-safe 함
  • 78. 함수형? Functional style 최상위 개념으로서의 함수 first-class function ✓ “function everywhere” Advantages ✓ 본질적으로 병렬화가 가능하며 thread-safe 함 ✓ Lazy evaluation 과 같은 최적화가 용이
  • 79. 함수형? Functional style 최상위 개념으로서의 함수 first-class function ✓ “function everywhere” Advantages ✓ 본질적으로 병렬화가 가능하며 thread-safe 함 ✓ Lazy evaluation 과 같은 최적화가 용이 ✓ 함수를 연계하여, 코드를 좀 더 유연한 형태의 일반화 용이
  • 80. 명령형 vs 함수형 명령형 Imperative 함수형 Functional 명령 command 함수 function 문장 sentence 표현식 expression 변수 variable 값 value 변경가능 mutable 변경불가 immutable 루프 loop 재귀 recursion
  • 81. 명령형 vs 함수형 Scala? Scala 는 양쪽 스타일 모두를 지원 문제의 영역 domain 에 맞는 방식을 선택 일반적으로는 명령형보다 함수형을 권장
  • 82. Imperative Style(Java) 전달된 리스트 자체를 바꾸기 public static void addOneToAll(ArrayList<Integer> items){ for (int i = 0; i < items.size(); ++i) { items.set(i, items.get(i) + 1); } }
  • 83. Functional Style(Java) 원본은 그대로 두고 새로운 List 를 리턴 public static List<Integer> addOneToAll(List<Integer> items) { ArrayList<Integer> result = new ArrayList<Integer>(); for (int i : items) { result.add(i + 1); } return result; }
  • 84. Functional Style(Java) Functional Enables Composition public static List<Integer> addTwoToAll(List<Integer> items) { return addOneToAll(addOneToAll(items)); }
  • 87. Function in Scala def f(x:Int):Int = x+1
  • 88. Function in Scala 함수 인자 타입 def f(x:Int):Int = x+1
  • 89. Function in Scala 함수의 계산 결 과 타입 (리턴타입) 함수 인자 타입 def f(x:Int):Int = x+1
  • 91. Function in Scala def f(x:Int) = x + 1
  • 92. Function in Scala def f(x:Int) = x + 1 def g(x:Int) = x * x
  • 93. Function in Scala def f(x:Int) = x + 1 def g(x:Int) = x * x def h(x:String, y:Int) = x + y
  • 94. Function in Scala def f(x:Int) = x + 1 def g(x:Int) = x * x def h(x:String, y:Int) = x + y
  • 95. Function in Scala def f(x:Int) = x + 1 def g(x:Int) = x * x def h(x:String, y:Int) = x + y => 추론 가능한 타입 선언 생략 가능
  • 96. Function in Scala def f(x:Int) = x + 1 def g(x:Int) = x * x def h(x:String, y:Int) = x + y => 추론 가능한 타입 선언 생략 가능 => 첫 등장시에만 타입 선언
  • 97. Function call in Scala h("result:", f(g(3)))
  • 98. Anonymous function(λ expression) in Scala (x:Int) => x + 1 (x:Int,y:Int) => x < y
  • 99. Anonymous function val people: List[Person] val minors = people.filter((p:Person) => p.age < 20)
  • 100. Anonymous function : short form val people: List[Person] val minors = people.filter(p => p.age < 20)
  • 101. Anonymous function : placeholder val people: List[Person] val minors = people.filter(_.age < 20)
  • 102. addOneToAll in Scala Imperative def addOneToAll(items: collection.mutable.ListBuffer[Int])= { var i = 0 while (i < items.length) { items.update(i, items(i) + 1) i += 1 } } Functional def addOneToAll(items: List[Int]) = items map (_ + 1)
  • 103. Functional Style with Collection
  • 104. Functional Style with Collection collection.map(f(x))
  • 105. Functional Style with Collection collection.map(f(x)) 모든 collection 에 존재
  • 106. Functional Style with Collection collection.map(f(x)) 모든 collection 에 존재 함수 f 를 전달 받아 collection 의 각 item 에 f 를 적용
  • 107. Functional Style with Collection collection.map(f(x)) 모든 collection 에 존재 함수 f 를 전달 받아 collection 의 각 item 에 f 를 적용 f 의 결과를 같은 사이즈의 같은 collection 에 담아 리턴
  • 108. Functional Style with Collection collection.map(f(x)) 모든 collection 에 존재 함수 f 를 전달 받아 collection 의 각 item 에 f 를 적용 f 의 결과를 같은 사이즈의 같은 collection 에 담아 리턴 scala> val strs = List("aaa", "bb", "c")
  • 109. Functional Style with Collection collection.map(f(x)) 모든 collection 에 존재 함수 f 를 전달 받아 collection 의 각 item 에 f 를 적용 f 의 결과를 같은 사이즈의 같은 collection 에 담아 리턴 scala> val strs = List("aaa", "bb", "c") strs: List[java.lang.String] = List(aaa, bb, c)
  • 110. Functional Style with Collection collection.map(f(x)) 모든 collection 에 존재 함수 f 를 전달 받아 collection 의 각 item 에 f 를 적용 f 의 결과를 같은 사이즈의 같은 collection 에 담아 리턴 scala> val strs = List("aaa", "bb", "c") strs: List[java.lang.String] = List(aaa, bb, c) scala> val ints = strs.map(str => str.length)
  • 111. Functional Style with Collection collection.map(f(x)) 모든 collection 에 존재 함수 f 를 전달 받아 collection 의 각 item 에 f 를 적용 f 의 결과를 같은 사이즈의 같은 collection 에 담아 리턴 scala> val strs = List("aaa", "bb", "c") strs: List[java.lang.String] = List(aaa, bb, c) scala> val ints = strs.map(str => str.length) ints: List[Int] = List(3, 2, 1)
  • 112. Functional Style with Collection collection.map(f(x)) 모든 collection 에 존재 함수 f 를 전달 받아 collection 의 각 item 에 f 를 적용 f 의 결과를 같은 사이즈의 같은 collection 에 담아 리턴 scala> val strs = List("aaa", "bb", "c") strs: List[java.lang.String] = List(aaa, bb, c) scala> val ints = strs.map(str => str.length) ints: List[Int] = List(3, 2, 1) String => Int
  • 113. Functional Style with Collection collection.map(f(x)) 모든 collection 에 존재 함수 f 를 전달 받아 collection 의 각 item 에 f 를 적용 f 의 결과를 같은 사이즈의 같은 collection 에 담아 리턴 scala> val strs = List("aaa", "bb", "c") strs: List[java.lang.String] = List(aaa, bb, c) scala> val ints = strs.map(str => str.length) ints: List[Int] = List(3, 2, 1) String => Int
  • 114. Functional Style with Collection collection.map(f(x)) 모든 collection 에 존재 함수 f 를 전달 받아 collection 의 각 item 에 f 를 적용 f 의 결과를 같은 사이즈의 같은 collection 에 담아 리턴 scala> val strs = List("aaa", "bb", "c") strs: List[java.lang.String] = List(aaa, bb, c) scala> val ints = strs.map(str => str.length) ints: List[Int] = List(3, 2, 1) String => Int
  • 115. Functional Style with Collection collection.map(f(x)) 모든 collection 에 존재 함수 f 를 전달 받아 collection 의 각 item 에 f 를 적용 f 의 결과를 같은 사이즈의 같은 collection 에 담아 리턴 scala> val strs = List("aaa", "bb", "c") strs: List[java.lang.String] = List(aaa, bb, c) scala> val ints = strs.map(str => str.length) ints: List[Int] = List(3, 2, 1) String => Int
  • 116. Functional Style with Collection collection.map(f(x)) 모든 collection 에 존재 함수 f 를 전달 받아 collection 의 각 item 에 f 를 적용 f 의 결과를 같은 사이즈의 같은 collection 에 담아 리턴 scala> val strs = List("aaa", "bb", "c") strs: List[java.lang.String] = List(aaa, bb, c) scala> val ints = strs.map(str => str.length) ints: List[Int] = List(3, 2, 1) String => Int
  • 117. Functional Style with Collection collection.map(f(x)) 모든 collection 에 존재 함수 f 를 전달 받아 collection 의 각 item 에 f 를 적용 f 의 결과를 같은 사이즈의 같은 collection 에 담아 리턴 scala> val strs = List("aaa", "bb", "c") strs: List[java.lang.String] = List(aaa, bb, c) scala> val ints = strs.map(str => str.length) ints: List[Int] = List(3, 2, 1) String => Int
  • 118. Functional Style with Collection
  • 119. Functional Style with Collection collection.reduce(f(x,y))
  • 120. Functional Style with Collection collection.reduce(f(x,y)) 모든 collection 에 존재
  • 121. Functional Style with Collection collection.reduce(f(x,y)) 모든 collection 에 존재 collection 에 존재하는 값들을 하나의 값으로 만듬
  • 122. Functional Style with Collection collection.reduce(f(x,y)) 모든 collection 에 존재 collection 에 존재하는 값들을 하나의 값으로 만듬 scala> val nums = 1 to 5 //1.to(5)
  • 123. Functional Style with Collection collection.reduce(f(x,y)) 모든 collection 에 존재 collection 에 존재하는 값들을 하나의 값으로 만듬 scala> val nums = 1 to 5 //1.to(5) nums: Range.Inclusive = Range(1, 2, 3, 4, 5)
  • 124. Functional Style with Collection collection.reduce(f(x,y)) 모든 collection 에 존재 collection 에 존재하는 값들을 하나의 값으로 만듬 scala> val nums = 1 to 5 //1.to(5) nums: Range.Inclusive = Range(1, 2, 3, 4, 5) scala> val fact = nums.reduce((acc,num)=>acc*num)
  • 125. Functional Style with Collection collection.reduce(f(x,y)) 모든 collection 에 존재 collection 에 존재하는 값들을 하나의 값으로 만듬 scala> val nums = 1 to 5 //1.to(5) nums: Range.Inclusive = Range(1, 2, 3, 4, 5) scala> val fact = nums.reduce((acc,num)=>acc*num) fact: Int = 120
  • 126. Functional Style with Collection collection.reduce(f(x,y)) 모든 collection 에 존재 collection 에 존재하는 값들을 하나의 값으로 만듬 scala> val nums = 1 to 5 //1.to(5) nums: Range.Inclusive = Range(1, 2, 3, 4, 5) scala> val fact = nums.reduce((acc,num)=>acc*num) fact: Int = 120 (Int,Int)=> Int
  • 128. reduce 1 2 3 4
  • 129. reduce 11 2 2 3 4 1*2 2
  • 130. reduce 11 2 2 3 3 4 1*2 2 2 * 3 6
  • 131. reduce 11 2 2 3 3 4 4 1*2 2 2 * 3 6 6 * 4 24
  • 132. reduce 11 2 2 3 3 4 45 1*2 2 2 * 3 6 6 * 4 24 24 * 5 120
  • 134. Functional Style: map reduce val people :Array[Person] = ...
  • 135. Functional Style: map reduce val people :Array[Person] = ... val sum = people.map(_.age).reduce(_ + _)
  • 136. Functional Style: map reduce val people :Array[Person] = ... val sum = people.map(_.age).reduce(_ + _) val avg = sum / people.length
  • 137. Functional Style: map reduce val people :Array[Person] = ... val sum = people.map(_.age).reduce(_ + _) val avg = sum / people.length scala> val people = Array(Person("Charles", 50),
  • 138. Functional Style: map reduce val people :Array[Person] = ... val sum = people.map(_.age).reduce(_ + _) val avg = sum / people.length scala> val people = Array(Person("Charles", 50), | Person("G.Ne", 60), Person("Jane", 59)) people: Array[Person] = Array(Person(Charles,50), Person(G.Ne,60), Person(Jane,59))
  • 139. Functional Style: map reduce val people :Array[Person] = ... val sum = people.map(_.age).reduce(_ + _) val avg = sum / people.length scala> val people = Array(Person("Charles", 50), | Person("G.Ne", 60), Person("Jane", 59)) people: Array[Person] = Array(Person(Charles,50), Person(G.Ne,60), Person(Jane,59)) scala> val ages = people.map(p => p.age)
  • 140. Functional Style: map reduce val people :Array[Person] = ... val sum = people.map(_.age).reduce(_ + _) val avg = sum / people.length scala> val people = Array(Person("Charles", 50), | Person("G.Ne", 60), Person("Jane", 59)) people: Array[Person] = Array(Person(Charles,50), Person(G.Ne,60), Person(Jane,59)) scala> val ages = people.map(p => p.age) ages: Array[Int] = Array(50, 60, 59)
  • 141. Functional Style: map reduce val people :Array[Person] = ... val sum = people.map(_.age).reduce(_ + _) val avg = sum / people.length scala> val people = Array(Person("Charles", 50), | Person("G.Ne", 60), Person("Jane", 59)) people: Array[Person] = Array(Person(Charles,50), Person(G.Ne,60), Person(Jane,59)) scala> val ages = people.map(p => p.age) ages: Array[Int] = Array(50, 60, 59) scala> ages.reduce((acc, age) => acc + age)
  • 142. Functional Style: map reduce val people :Array[Person] = ... val sum = people.map(_.age).reduce(_ + _) val avg = sum / people.length scala> val people = Array(Person("Charles", 50), | Person("G.Ne", 60), Person("Jane", 59)) people: Array[Person] = Array(Person(Charles,50), Person(G.Ne,60), Person(Jane,59)) scala> val ages = people.map(p => p.age) ages: Array[Int] = Array(50, 60, 59) scala> ages.reduce((acc, age) => acc + age) res7: Int = 169
  • 143. Functional Style: map reduce val people :Array[Person] = ... val sum = people.map(_.age).reduce(_ + _) val avg = sum / people.length scala> val people = Array(Person("Charles", 50), | Person("G.Ne", 60), Person("Jane", 59)) people: Array[Person] = Array(Person(Charles,50), Person(G.Ne,60), Person(Jane,59)) scala> val ages = people.map(p => p.age) 50 + 60 = 110 ages: Array[Int] = Array(50, 60, 59) 110 + 59 = 169 scala> ages.reduce((acc, age) => acc + age) res7: Int = 169
  • 144. Functional style Functional is ... Just a pattern and NOT a syntax. ✓ Java이냐 Scala 이냐 관계 없이 Functional 하게 코드를 작성 할 수 있음 ✓ Functional Java: => http://functionaljava.org/ => http://code.google.com/p/guava-libraries/ Not only for academic languages ✓ Java를 제외한 Ruby, Python, Javascript 같은 대부분의 언어들은 functional style 을 위한 다양한 도구를 지원함
  • 147. match/case val new = old match { case 패턴1 => 값1 case 패턴2 => 값2 case _ => 기본값 }
  • 148. Pattern matching Matching on values val times = 1 val numStr = times match { case 1 => "one" case 2 => "two" case _ => "some other number" }
  • 149. Pattern matching Matching with guards val times = 1 val numStr = times match { case i if i == 1 => "one" case i if i == 2 => "two" case _ => "some other number" }
  • 150. Pattern matching Matching on type def bigger(o: Any): Any = { o match { case i: Int if i < 0 => i - 1 case i: Int => i + 1 case d: Double if d < 0.0 => d - 0.1 case d: Double => d + 0.1 case text: String => text + "s" } }
  • 151. Pattern matching Matching on class member class Calculator(val brand: String, val model: String) def calcType(calc: Calculator) = calc match { case c if c.brand == "hp" && c.model == "20B" => "financial" case c if c.brand == "hp" && c.model == "48G" => "scientific" case c if c.brand == "hp" && c.model == "30B" => "business" case _ => "unknown" }
  • 152. case class case class Calculator(brand: String, model: String)
  • 153. case class case class Calculator(brand: String, model: String) accessor, equals(==), hashCode(##), toString, copy, pattern matching, factory function
  • 155. case class scala> val a = Calculator("hp", "20B")
  • 156. case class scala> val a = Calculator("hp", "20B") a: Calculator = Calculator(hp,20B)
  • 157. case class scala> val a = Calculator("hp", "20B") a: Calculator = Calculator(hp,20B) scala> a ##
  • 158. case class scala> val a = Calculator("hp", "20B") a: Calculator = Calculator(hp,20B) scala> a ## res58: Int = 1619269961
  • 159. case class scala> val a = Calculator("hp", "20B") a: Calculator = Calculator(hp,20B) scala> a ## res58: Int = 1619269961 scala> a toString
  • 160. case class scala> val a = Calculator("hp", "20B") a: Calculator = Calculator(hp,20B) scala> a ## res58: Int = 1619269961 scala> a toString res59: String = Calculator(hp,20B)
  • 161. case class scala> val a = Calculator("hp", "20B") a: Calculator = Calculator(hp,20B) scala> a ## res58: Int = 1619269961 scala> a toString res59: String = Calculator(hp,20B) scala> a.copy(model = "48G")
  • 162. case class scala> val a = Calculator("hp", "20B") a: Calculator = Calculator(hp,20B) scala> a ## res58: Int = 1619269961 scala> a toString res59: String = Calculator(hp,20B) scala> a.copy(model = "48G") res60: Calculator = Calculator(hp,48G)
  • 163. case class scala> val a = Calculator("hp", "20B") a: Calculator = Calculator(hp,20B) scala> a ## res58: Int = 1619269961 scala> a toString res59: String = Calculator(hp,20B) scala> a.copy(model = "48G") res60: Calculator = Calculator(hp,48G) scala> val b = Calculator("hp", "20B")
  • 164. case class scala> val a = Calculator("hp", "20B") a: Calculator = Calculator(hp,20B) scala> a ## res58: Int = 1619269961 scala> a toString res59: String = Calculator(hp,20B) scala> a.copy(model = "48G") res60: Calculator = Calculator(hp,48G) scala> val b = Calculator("hp", "20B") b: Calculator = Calculator(hp,20B)
  • 165. case class scala> val a = Calculator("hp", "20B") a: Calculator = Calculator(hp,20B) scala> a ## res58: Int = 1619269961 scala> a toString res59: String = Calculator(hp,20B) scala> a.copy(model = "48G") res60: Calculator = Calculator(hp,48G) scala> val b = Calculator("hp", "20B") b: Calculator = Calculator(hp,20B) scala> a == b
  • 166. case class scala> val a = Calculator("hp", "20B") a: Calculator = Calculator(hp,20B) scala> a ## res58: Int = 1619269961 scala> a toString res59: String = Calculator(hp,20B) scala> a.copy(model = "48G") res60: Calculator = Calculator(hp,48G) scala> val b = Calculator("hp", "20B") b: Calculator = Calculator(hp,20B) scala> a == b res61: Boolean = true
  • 168. Pattern Matching: case class def calcType(calc: Calculator) = calc match {
  • 169. Pattern Matching: case class def calcType(calc: Calculator) = calc match { case Calculator("hp", "20B") => "financial"
  • 170. Pattern Matching: case class def calcType(calc: Calculator) = calc match { case Calculator("hp", "20B") => "financial" case Calculator("hp", "48G") => "scientific"
  • 171. Pattern Matching: case class def calcType(calc: Calculator) = calc match { case Calculator("hp", "20B") => "financial" case Calculator("hp", "48G") => "scientific" case Calculator("hp", "30B") => "business"
  • 172. Pattern Matching: case class def calcType(calc: Calculator) = calc match { case Calculator("hp", "20B") => "financial" case Calculator("hp", "48G") => "scientific" case Calculator("hp", "30B") => "business" case Calculator(b, m) =>
  • 173. Pattern Matching: case class def calcType(calc: Calculator) = calc match { case Calculator("hp", "20B") => "financial" case Calculator("hp", "48G") => "scientific" case Calculator("hp", "30B") => "business" case Calculator(b, m) => "Calculator: %s %s is of unknown type".format(b, m)
  • 174. Pattern Matching: case class def calcType(calc: Calculator) = calc match { case Calculator("hp", "20B") => "financial" case Calculator("hp", "48G") => "scientific" case Calculator("hp", "30B") => "business" case Calculator(b, m) => "Calculator: %s %s is of unknown type".format(b, m) }
  • 175. Pattern Matching: case class def calcType(calc: Calculator) = calc match { case Calculator("hp", "20B") => "financial" case Calculator("hp", "48G") => "scientific" case Calculator("hp", "30B") => "business" case Calculator(b, m) => "Calculator: %s %s is of unknown type".format(b, m) } scala> calcType(Calculator("hp", "20B"))
  • 176. Pattern Matching: case class def calcType(calc: Calculator) = calc match { case Calculator("hp", "20B") => "financial" case Calculator("hp", "48G") => "scientific" case Calculator("hp", "30B") => "business" case Calculator(b, m) => "Calculator: %s %s is of unknown type".format(b, m) } scala> calcType(Calculator("hp", "20B")) res62: java.lang.String = financial
  • 177. Pattern Matching: case class def calcType(calc: Calculator) = calc match { case Calculator("hp", "20B") => "financial" case Calculator("hp", "48G") => "scientific" case Calculator("hp", "30B") => "business" case Calculator(b, m) => "Calculator: %s %s is of unknown type".format(b, m) } scala> calcType(Calculator("hp", "20B")) res62: java.lang.String = financial scala> calcType(Calculator("hp", "48G"))
  • 178. Pattern Matching: case class def calcType(calc: Calculator) = calc match { case Calculator("hp", "20B") => "financial" case Calculator("hp", "48G") => "scientific" case Calculator("hp", "30B") => "business" case Calculator(b, m) => "Calculator: %s %s is of unknown type".format(b, m) } scala> calcType(Calculator("hp", "20B")) res62: java.lang.String = financial scala> calcType(Calculator("hp", "48G")) res63: java.lang.String = scientific
  • 179. Pattern Matching: case class def calcType(calc: Calculator) = calc match { case Calculator("hp", "20B") => "financial" case Calculator("hp", "48G") => "scientific" case Calculator("hp", "30B") => "business" case Calculator(b, m) => "Calculator: %s %s is of unknown type".format(b, m) } scala> calcType(Calculator("hp", "20B")) res62: java.lang.String = financial scala> calcType(Calculator("hp", "48G")) res63: java.lang.String = scientific scala> calcType(Calculator("kth", "h3"))
  • 180. Pattern Matching: case class def calcType(calc: Calculator) = calc match { case Calculator("hp", "20B") => "financial" case Calculator("hp", "48G") => "scientific" case Calculator("hp", "30B") => "business" case Calculator(b, m) => "Calculator: %s %s is of unknown type".format(b, m) } scala> calcType(Calculator("hp", "20B")) res62: java.lang.String = financial scala> calcType(Calculator("hp", "48G")) res63: java.lang.String = scientific scala> calcType(Calculator("kth", "h3")) res64: java.lang.String = Calculator: kth h3 is of unknown type
  • 182. Pattern Matching: case class scala> val calcs = List(Calculator("hp", "20B"),
  • 183. Pattern Matching: case class scala> val calcs = List(Calculator("hp", "20B"), | Calculator("hp", "48G"), Calculator("hp", "30B"),
  • 184. Pattern Matching: case class scala> val calcs = List(Calculator("hp", "20B"), | Calculator("hp", "48G"), Calculator("hp", "30B"), | Calculator("kth", "h3"))
  • 185. Pattern Matching: case class scala> val calcs = List(Calculator("hp", "20B"), | Calculator("hp", "48G"), Calculator("hp", "30B"), | Calculator("kth", "h3")) calcs: List[Calculator] = List(Calculator(hp,20B), Calculator(hp,48G), Calculator(hp,30B), Calculator(kth,h3))
  • 186. Pattern Matching: case class scala> val calcs = List(Calculator("hp", "20B"), | Calculator("hp", "48G"), Calculator("hp", "30B"), | Calculator("kth", "h3")) calcs: List[Calculator] = List(Calculator(hp,20B), Calculator(hp,48G), Calculator(hp,30B), Calculator(kth,h3)) scala> calcs.map(calcType).foreach(println)
  • 187. Pattern Matching: case class scala> val calcs = List(Calculator("hp", "20B"), | Calculator("hp", "48G"), Calculator("hp", "30B"), | Calculator("kth", "h3")) calcs: List[Calculator] = List(Calculator(hp,20B), Calculator(hp,48G), Calculator(hp,30B), Calculator(kth,h3)) scala> calcs.map(calcType).foreach(println) financial
  • 188. Pattern Matching: case class scala> val calcs = List(Calculator("hp", "20B"), | Calculator("hp", "48G"), Calculator("hp", "30B"), | Calculator("kth", "h3")) calcs: List[Calculator] = List(Calculator(hp,20B), Calculator(hp,48G), Calculator(hp,30B), Calculator(kth,h3)) scala> calcs.map(calcType).foreach(println) financial scientific
  • 189. Pattern Matching: case class scala> val calcs = List(Calculator("hp", "20B"), | Calculator("hp", "48G"), Calculator("hp", "30B"), | Calculator("kth", "h3")) calcs: List[Calculator] = List(Calculator(hp,20B), Calculator(hp,48G), Calculator(hp,30B), Calculator(kth,h3)) scala> calcs.map(calcType).foreach(println) financial scientific business
  • 190. Pattern Matching: case class scala> val calcs = List(Calculator("hp", "20B"), | Calculator("hp", "48G"), Calculator("hp", "30B"), | Calculator("kth", "h3")) calcs: List[Calculator] = List(Calculator(hp,20B), Calculator(hp,48G), Calculator(hp,30B), Calculator(kth,h3)) scala> calcs.map(calcType).foreach(println) financial scientific business Calculator: kth h3 is of unknown type
  • 192. Pattern Matching: case class Example: Activity Stream
  • 193. Pattern Matching: case class Example: Activity Stream Facebook timeline
  • 194. Pattern Matching: case class Example: Activity Stream Facebook timeline SNS 사용자들의 활동 내역을 추상화
  • 195. Pattern Matching: case class Example: Activity Stream Facebook timeline SNS 사용자들의 활동 내역을 추상화 이번 예제에서는 write/like 만 고려
  • 196. Pattern Matching: case class Example: Activity Stream Facebook timeline SNS 사용자들의 활동 내역을 추상화 이번 예제에서는 write/like 만 고려
  • 197. Pattern Matching: case class Example: Activity Stream Facebook timeline SNS 사용자들의 활동 내역을 추상화 이번 예제에서는 write/like 만 고려 “Someone likes my post”
  • 198. Example: Activity Stream Activity = S(주어) + V(동사) + O(목적어)
  • 199. Example: Activity Stream Activity = S(주어) + V(동사) + O(목적어) case class Activity( sub: Noun, verb: String, obj: Noun )
  • 201. Example: Activity Stream Person and Post trait Noun
  • 202. Example: Activity Stream Person and Post trait Noun case class Person(name: String, age: Int) extends Noun {
  • 203. Example: Activity Stream Person and Post trait Noun case class Person(name: String, age: Int) extends Noun { def followers: List[Person] = ...
  • 204. Example: Activity Stream Person and Post trait Noun case class Person(name: String, age: Int) extends Noun { def followers: List[Person] = ... }
  • 205. Example: Activity Stream Person and Post trait Noun case class Person(name: String, age: Int) extends Noun { def followers: List[Person] = ... }
  • 206. Example: Activity Stream Person and Post trait Noun case class Person(name: String, age: Int) extends Noun { def followers: List[Person] = ... } case class Post(author: Person, text: String) extends Noun
  • 208. Example: Activity Stream Activity val jane = Person("Jane", 59)
  • 209. Example: Activity Stream Activity val jane = Person("Jane", 59) val charles = Person("Charles", 50)
  • 210. Example: Activity Stream Activity val jane = Person("Jane", 59) val charles = Person("Charles", 50) val post = Post(jane, "hello, world")
  • 211. Example: Activity Stream Activity val jane = Person("Jane", 59) val charles = Person("Charles", 50) val post = Post(jane, "hello, world") val a1 = Activity(jane, "write", post)
  • 212. Example: Activity Stream Activity val jane = Person("Jane", 59) val charles = Person("Charles", 50) val post = Post(jane, "hello, world") val a1 = Activity(jane, "write", post) val a2 = Activity(charles, "like", post)
  • 214. Example: Activity Stream Push or Email def sendPush(to: Person, msg: String)
  • 215. Example: Activity Stream Push or Email def sendPush(to: Person, msg: String) def sendEmail(to: Person, msg: String)
  • 217. Example: Activity Stream Notification def sendNoti(a: Activity) = {
  • 218. Example: Activity Stream Notification def sendNoti(a: Activity) = { a match {
  • 219. Example: Activity Stream Notification def sendNoti(a: Activity) = { a match { case Activity(someone: Person, "like", Post(author, _)) =>
  • 220. Example: Activity Stream Notification def sendNoti(a: Activity) = { a match { case Activity(someone: Person, "like", Post(author, _)) => sendPush(
  • 221. Example: Activity Stream Notification def sendNoti(a: Activity) = { a match { case Activity(someone: Person, "like", Post(author, _)) => sendPush( author,
  • 222. Example: Activity Stream Notification def sendNoti(a: Activity) = { a match { case Activity(someone: Person, "like", Post(author, _)) => sendPush( author, "%s likes your post".format(someone.name))
  • 223. Example: Activity Stream Notification def sendNoti(a: Activity) = { a match { case Activity(someone: Person, "like", Post(author, _)) => sendPush( author, "%s likes your post".format(someone.name)) case Activity(someone: Person, "write", _) =>
  • 224. Example: Activity Stream Notification def sendNoti(a: Activity) = { a match { case Activity(someone: Person, "like", Post(author, _)) => sendPush( author, "%s likes your post".format(someone.name)) case Activity(someone: Person, "write", _) => someone.followers.foreach(
  • 225. Example: Activity Stream Notification def sendNoti(a: Activity) = { a match { case Activity(someone: Person, "like", Post(author, _)) => sendPush( author, "%s likes your post".format(someone.name)) case Activity(someone: Person, "write", _) => someone.followers.foreach( p =>
  • 226. Example: Activity Stream Notification def sendNoti(a: Activity) = { a match { case Activity(someone: Person, "like", Post(author, _)) => sendPush( author, "%s likes your post".format(someone.name)) case Activity(someone: Person, "write", _) => someone.followers.foreach( p => sendEmail(
  • 227. Example: Activity Stream Notification def sendNoti(a: Activity) = { a match { case Activity(someone: Person, "like", Post(author, _)) => sendPush( author, "%s likes your post".format(someone.name)) case Activity(someone: Person, "write", _) => someone.followers.foreach( p => sendEmail( p, "%s write new post".format(someone.name)))
  • 228. Example: Activity Stream Notification def sendNoti(a: Activity) = { a match { case Activity(someone: Person, "like", Post(author, _)) => sendPush( author, "%s likes your post".format(someone.name)) case Activity(someone: Person, "write", _) => someone.followers.foreach( p => sendEmail( p, "%s write new post".format(someone.name))) }
  • 229. Example: Activity Stream Notification def sendNoti(a: Activity) = { a match { case Activity(someone: Person, "like", Post(author, _)) => sendPush( author, "%s likes your post".format(someone.name)) case Activity(someone: Person, "write", _) => someone.followers.foreach( p => sendEmail( p, "%s write new post".format(someone.name))) } }
  • 231. 좀 더 우아하게 ! object Activities { trait Activity trait Noun case class write(sub: Noun, obj: Noun) extends Activity case class like(sub: Noun, obj: Noun) extends Activity case class Sub(n: Noun) { def like(obj: Noun) = Activities.like(n, obj) def write(obj: Noun) = Activities.write(n, obj) } implicit def nounToSub(n: Noun) = Sub(n) case class Person(name: String, age: Int) extends Noun { def followers: List[Person] = Nil } case class Post(author: Person, text: String) extends Noun }
  • 233. 좀 더 우아하게! val jane = Person("Jane", 59)
  • 234. 좀 더 우아하게! val jane = Person("Jane", 59) val charles = Person("Charles", 50)
  • 235. 좀 더 우아하게! val jane = Person("Jane", 59) val charles = Person("Charles", 50) val post = Post(jane, "hello, world")
  • 236. 좀 더 우아하게! val jane = Person("Jane", 59) val charles = Person("Charles", 50) val post = Post(jane, "hello, world") val a1 = jane write post
  • 237. 좀 더 우아하게! val jane = Person("Jane", 59) val charles = Person("Charles", 50) val post = Post(jane, "hello, world") val a1 = jane write post val a2 = charles like post
  • 238. 좀 더 우아하게! val jane = Person("Jane", 59) val charles = Person("Charles", 50) val post = Post(jane, "hello, world") val a1 = jane write post val a2 = charles like post def sendNoti(a: Activity) {
  • 239. 좀 더 우아하게! val jane = Person("Jane", 59) val charles = Person("Charles", 50) val post = Post(jane, "hello, world") val a1 = jane write post val a2 = charles like post def sendNoti(a: Activity) { a match {
  • 240. 좀 더 우아하게! val jane = Person("Jane", 59) val charles = Person("Charles", 50) val post = Post(jane, "hello, world") val a1 = jane write post val a2 = charles like post def sendNoti(a: Activity) { a match { case someone write post => ...
  • 241. 좀 더 우아하게! val jane = Person("Jane", 59) val charles = Person("Charles", 50) val post = Post(jane, "hello, world") val a1 = jane write post val a2 = charles like post def sendNoti(a: Activity) { a match { case someone write post => ... case Person(name, age) like Post(author, text) => ...
  • 242. 좀 더 우아하게! val jane = Person("Jane", 59) val charles = Person("Charles", 50) val post = Post(jane, "hello, world") val a1 = jane write post val a2 = charles like post def sendNoti(a: Activity) { a match { case someone write post => ... case Person(name, age) like Post(author, text) => ... }
  • 243. 좀 더 우아하게! val jane = Person("Jane", 59) val charles = Person("Charles", 50) val post = Post(jane, "hello, world") val a1 = jane write post val a2 = charles like post def sendNoti(a: Activity) { a match { case someone write post => ... case Person(name, age) like Post(author, text) => ... } }
  • 246. Pattern Matching More usage val Person(name, age) = Person(“tao”,35)
  • 247. Pattern Matching More usage val Person(name, age) = Person(“tao”,35) “for” expression
  • 248. Pattern Matching More usage val Person(name, age) = Person(“tao”,35) “for” expression Collections
  • 249. Pattern Matching More usage val Person(name, age) = Person(“tao”,35) “for” expression Collections Extractors
  • 250. Pattern Matching More usage val Person(name, age) = Person(“tao”,35) “for” expression Collections Extractors XML
  • 252. Horizontal Scale The Multi-core Era ✓ Moore Law => 반도체 집적 회로의 성능은 18개월 마다 2배로 증간한다 => 최근에는 클럭수가 아닌 코어의 증가로 이루어짐 The Big-data Era ✓ 마구 쏟아지는 엄청난 데이터를 처리해야함 병렬/동시/분산 처리가 중요해짐 ✓ 하지만, 동시성 문제는 언제나 어렵다
  • 253. 왜?
  • 254. Horizontal Scale Root Cause 공유된 변경 가능한 상태 shared mutable state 동기화 synchronization ✓ monitor & lock 예측 불가능한 상황을 피하기 위해서는 ✓ 변경 가능한 상태 mutable state 를 만들지 말아야 함 ✓ 즉, functional style 로 코드를 작성해야함
  • 255. “ 프로그램들은 버그로 가득차 Thread를 사용하는 대부분의 있다 - Havoc Pennington @ Dreamforce 2011 ”
  • 259. Actor model Actor Model 동시성 문제를 위한 더 단순한 고수준의 추상화 모델
  • 260. Actor model Actor Model 동시성 문제를 위한 더 단순한 고수준의 추상화 모델 ✓ Actors are objects which encapsulate state and behavior
  • 261. Actor model Actor Model 동시성 문제를 위한 더 단순한 고수준의 추상화 모델 ✓ Actors are objects which encapsulate state and behavior Erlang 이라는 언어를 통해 널리 알려짐
  • 262. Actor model Actor Model 동시성 문제를 위한 더 단순한 고수준의 추상화 모델 ✓ Actors are objects which encapsulate state and behavior Erlang 이라는 언어를 통해 널리 알려짐 Message passing, no shared memory
  • 263. Actor model Actor Model 동시성 문제를 위한 더 단순한 고수준의 추상화 모델 ✓ Actors are objects which encapsulate state and behavior Erlang 이라는 언어를 통해 널리 알려짐 Message passing, no shared memory Event loop
  • 264. Worker vs Actor Worker Queue Worker take lock Shared Job Memory Worker #3 put Worker
  • 265. Worker vs Actor Actor #1 mailbox message messages Actor #2 To: Actor#1 Actor #3 Actor #4
  • 267. Bruce: “그 때(루비를 만들었을 당시)로 돌아간다 면, 어떤 기능에 변화를 주고 싶으세요?” Matz: “Thread를 없애고, Actor 나 또는 좀 더 진 보된 형태의 동시성 기능을 추가했을거에요” Interview with Yukihiro Matsumoto (the creator of Ruby) from the book, “Seven Languages in Seven Weeks” ”
  • 270. Scala Actor Akka Scala로 작성된 Actor model 구현
  • 271. Scala Actor Akka Scala로 작성된 Actor model 구현 TypeSafe Stack with Play! Framework
  • 272. Scala Actor Akka Scala로 작성된 Actor model 구현 TypeSafe Stack with Play! Framework 곧 Scala에 built-in 될 예정
  • 273. Scala Actor Akka Scala로 작성된 Actor model 구현 TypeSafe Stack with Play! Framework 곧 Scala에 built-in 될 예정 ✓ 기존 Scala 자체 구현은 deprecate 될 예정
  • 274. Scala Actor Akka Scala로 작성된 Actor model 구현 TypeSafe Stack with Play! Framework 곧 Scala에 built-in 될 예정 ✓ 기존 Scala 자체 구현은 deprecate 될 예정 자바를 위한 별도 API 제공
  • 275. Scala Actor Akka Scala로 작성된 Actor model 구현 TypeSafe Stack with Play! Framework 곧 Scala에 built-in 될 예정 ✓ 기존 Scala 자체 구현은 deprecate 될 예정 자바를 위한 별도 API 제공 Asynchronous/non-blocking
  • 276. Scala Actor Akka Scala로 작성된 Actor model 구현 TypeSafe Stack with Play! Framework 곧 Scala에 built-in 될 예정 ✓ 기존 Scala 자체 구현은 deprecate 될 예정 자바를 위한 별도 API 제공 Asynchronous/non-blocking 격리된 변경 가능 상태 Isolated mutable state
  • 277. Akka Actor import akka.actor.Actor import akka.actor.Props import akka.event.Logging class MyActor extends Actor { val log = Logging(context.system, this) def receive = { case "test" log.info("received test") case _ log.info("received unknown message") } }
  • 278. Akka Actor import akka.actor.Actor import akka.actor.Props import akka.event.Logging class MyActor extends Actor { val log = Logging(context.system, this) def receive = { case "test" log.info("received test") case _ log.info("received unknown message") } }
  • 279. Akka
  • 281. Akka Creating actor val system = ActorSystem("MySystem") val myActor = system.actorOf(Props[MyActor], name = "myactor")
  • 282. Akka Creating actor val system = ActorSystem("MySystem") val myActor = system.actorOf(Props[MyActor], name = "myactor") Sending a message
  • 283. Akka Creating actor val system = ActorSystem("MySystem") val myActor = system.actorOf(Props[MyActor], name = "myactor") Sending a message myActor ! "test" myActor.tell("test")
  • 284. Akka Creating actor val system = ActorSystem("MySystem") val myActor = system.actorOf(Props[MyActor], name = "myactor") Sending a message myActor ! "test" myActor.tell("test") Tell: Fire and Forget
  • 285. Akka
  • 287. Akka Replying def receive = { case "ping" sender ! "pong" ...
  • 288. Akka Replying def receive = { case "ping" sender ! "pong" ... Asking
  • 289. Akka Replying def receive = { case "ping" sender ! "pong" ... Asking val future1 = pingpongActor ? "ping" val future2 = pingpongActor.ask("ping")
  • 292. Example: ActivityStream class NotiActor extends Actor { def sendPush(to: Person, msg: String) {
  • 293. Example: ActivityStream class NotiActor extends Actor { def sendPush(to: Person, msg: String) { println("Send Push [To: %s][Msg: %s]".format(to, msg))
  • 294. Example: ActivityStream class NotiActor extends Actor { def sendPush(to: Person, msg: String) { println("Send Push [To: %s][Msg: %s]".format(to, msg)) }
  • 295. Example: ActivityStream class NotiActor extends Actor { def sendPush(to: Person, msg: String) { println("Send Push [To: %s][Msg: %s]".format(to, msg)) } def sendEmail(to: Person, msg: String) {
  • 296. Example: ActivityStream class NotiActor extends Actor { def sendPush(to: Person, msg: String) { println("Send Push [To: %s][Msg: %s]".format(to, msg)) } def sendEmail(to: Person, msg: String) { println("Send Email [To: %s][Msg: %s]".format(to, msg))
  • 297. Example: ActivityStream class NotiActor extends Actor { def sendPush(to: Person, msg: String) { println("Send Push [To: %s][Msg: %s]".format(to, msg)) } def sendEmail(to: Person, msg: String) { println("Send Email [To: %s][Msg: %s]".format(to, msg)) }
  • 298. Example: ActivityStream class NotiActor extends Actor { def sendPush(to: Person, msg: String) { println("Send Push [To: %s][Msg: %s]".format(to, msg)) } def sendEmail(to: Person, msg: String) { println("Send Email [To: %s][Msg: %s]".format(to, msg)) } def receive = {
  • 299. Example: ActivityStream class NotiActor extends Actor { def sendPush(to: Person, msg: String) { println("Send Push [To: %s][Msg: %s]".format(to, msg)) } def sendEmail(to: Person, msg: String) { println("Send Email [To: %s][Msg: %s]".format(to, msg)) } def receive = { case Person(name, _) like Post(author, _) =>
  • 300. Example: ActivityStream class NotiActor extends Actor { def sendPush(to: Person, msg: String) { println("Send Push [To: %s][Msg: %s]".format(to, msg)) } def sendEmail(to: Person, msg: String) { println("Send Email [To: %s][Msg: %s]".format(to, msg)) } def receive = { case Person(name, _) like Post(author, _) => sendPush(author, "%s likes your post".format(name))
  • 301. Example: ActivityStream class NotiActor extends Actor { def sendPush(to: Person, msg: String) { println("Send Push [To: %s][Msg: %s]".format(to, msg)) } def sendEmail(to: Person, msg: String) { println("Send Email [To: %s][Msg: %s]".format(to, msg)) } def receive = { case Person(name, _) like Post(author, _) => sendPush(author, "%s likes your post".format(name)) case (someone@Person(name, _)) write _ =>
  • 302. Example: ActivityStream class NotiActor extends Actor { def sendPush(to: Person, msg: String) { println("Send Push [To: %s][Msg: %s]".format(to, msg)) } def sendEmail(to: Person, msg: String) { println("Send Email [To: %s][Msg: %s]".format(to, msg)) } def receive = { case Person(name, _) like Post(author, _) => sendPush(author, "%s likes your post".format(name)) case (someone@Person(name, _)) write _ => someone.followers.foreach{
  • 303. Example: ActivityStream class NotiActor extends Actor { def sendPush(to: Person, msg: String) { println("Send Push [To: %s][Msg: %s]".format(to, msg)) } def sendEmail(to: Person, msg: String) { println("Send Email [To: %s][Msg: %s]".format(to, msg)) } def receive = { case Person(name, _) like Post(author, _) => sendPush(author, "%s likes your post".format(name)) case (someone@Person(name, _)) write _ => someone.followers.foreach{ p =>
  • 304. Example: ActivityStream class NotiActor extends Actor { def sendPush(to: Person, msg: String) { println("Send Push [To: %s][Msg: %s]".format(to, msg)) } def sendEmail(to: Person, msg: String) { println("Send Email [To: %s][Msg: %s]".format(to, msg)) } def receive = { case Person(name, _) like Post(author, _) => sendPush(author, "%s likes your post".format(name)) case (someone@Person(name, _)) write _ => someone.followers.foreach{ p => sendEmail(p,
  • 305. Example: ActivityStream class NotiActor extends Actor { def sendPush(to: Person, msg: String) { println("Send Push [To: %s][Msg: %s]".format(to, msg)) } def sendEmail(to: Person, msg: String) { println("Send Email [To: %s][Msg: %s]".format(to, msg)) } def receive = { case Person(name, _) like Post(author, _) => sendPush(author, "%s likes your post".format(name)) case (someone@Person(name, _)) write _ => someone.followers.foreach{ p => sendEmail(p, "Your friend(%s) write new post".format(name))
  • 306. Example: ActivityStream class NotiActor extends Actor { def sendPush(to: Person, msg: String) { println("Send Push [To: %s][Msg: %s]".format(to, msg)) } def sendEmail(to: Person, msg: String) { println("Send Email [To: %s][Msg: %s]".format(to, msg)) } def receive = { case Person(name, _) like Post(author, _) => sendPush(author, "%s likes your post".format(name)) case (someone@Person(name, _)) write _ => someone.followers.foreach{ p => sendEmail(p, "Your friend(%s) write new post".format(name)) }
  • 307. Example: ActivityStream class NotiActor extends Actor { def sendPush(to: Person, msg: String) { println("Send Push [To: %s][Msg: %s]".format(to, msg)) } def sendEmail(to: Person, msg: String) { println("Send Email [To: %s][Msg: %s]".format(to, msg)) } def receive = { case Person(name, _) like Post(author, _) => sendPush(author, "%s likes your post".format(name)) case (someone@Person(name, _)) write _ => someone.followers.foreach{ p => sendEmail(p, "Your friend(%s) write new post".format(name)) } }
  • 308. Example: ActivityStream class NotiActor extends Actor { def sendPush(to: Person, msg: String) { println("Send Push [To: %s][Msg: %s]".format(to, msg)) } def sendEmail(to: Person, msg: String) { println("Send Email [To: %s][Msg: %s]".format(to, msg)) } def receive = { case Person(name, _) like Post(author, _) => sendPush(author, "%s likes your post".format(name)) case (someone@Person(name, _)) write _ => someone.followers.foreach{ p => sendEmail(p, "Your friend(%s) write new post".format(name)) } } }
  • 310. Example: ActivityStream Sending activities val jane = Person("Jane", 59)
  • 311. Example: ActivityStream Sending activities val jane = Person("Jane", 59) val charles = Person("Charles", 50)
  • 312. Example: ActivityStream Sending activities val jane = Person("Jane", 59) val charles = Person("Charles", 50) val post = Post(jane, "hello, world")
  • 313. Example: ActivityStream Sending activities val jane = Person("Jane", 59) val charles = Person("Charles", 50) val post = Post(jane, "hello, world") val system = ActorSystem("ActivityStream")
  • 314. Example: ActivityStream Sending activities val jane = Person("Jane", 59) val charles = Person("Charles", 50) val post = Post(jane, "hello, world") val system = ActorSystem("ActivityStream") val notiActor = system.actorOf(
  • 315. Example: ActivityStream Sending activities val jane = Person("Jane", 59) val charles = Person("Charles", 50) val post = Post(jane, "hello, world") val system = ActorSystem("ActivityStream") val notiActor = system.actorOf( Props[NotiActor], "notification")
  • 316. Example: ActivityStream Sending activities val jane = Person("Jane", 59) val charles = Person("Charles", 50) val post = Post(jane, "hello, world") val system = ActorSystem("ActivityStream") val notiActor = system.actorOf( Props[NotiActor], "notification") notiActor ! (jane write post)
  • 317. Example: ActivityStream Sending activities val jane = Person("Jane", 59) val charles = Person("Charles", 50) val post = Post(jane, "hello, world") val system = ActorSystem("ActivityStream") val notiActor = system.actorOf( Props[NotiActor], "notification") notiActor ! (jane write post) notiActor ! (charles like post)
  • 319. Example: ActivityStream Scale Up (Concurrency) val notiActor = system.actorOf( Props[NotiActor].withRouter(RoundRobinRouter(5)) "notication")
  • 320. Example: ActivityStream Scale Up (Concurrency) val notiActor = system.actorOf( Props[NotiActor].withRouter(RoundRobinRouter(5)) "notication") val notiActor = system.actorOf( Props[NotiActor].withRouter(SmallestMailboxRouter(5)) "notication")
  • 322. Example: ActivityStream Scale Out (Remoting) val notiActor = context.actorFor( "akka://activity@192.168.10.2:2552/user/notification")
  • 323. Example: ActivityStream Scale Out (Remoting) val notiActor = context.actorFor( "akka://activity@192.168.10.2:2552/user/notification") val notiActor = context.actorFor( "cluster://acitivties/notification")
  • 324. Example: ActivityStream Scale Out (Remoting) val notiActor = context.actorFor( "akka://activity@192.168.10.2:2552/user/notification") val notiActor = context.actorFor( "cluster://acitivties/notification") Location Transparency coming soon !
  • 325. Example: ActivityStream Scale Out (Remoting) val notiActor = context.actorFor( "akka://activity@192.168.10.2:2552/user/notification") val notiActor = context.actorFor( "cluster://acitivties/notification") ? Location Transparency coming soon !
  • 326. Akka More Usage Event Bus Scheduler Fault Tolerance STM (Software Transactional Memory) FSM (Finite State Machine) Asynchronous IO Extensions for ZeroMQ, Camel, ...
  • 327. Scala?
  • 328. 더 강력한 표현력 더 강력한 동시성 처리 기존 JVM 기반 환경 재사 용
  • 329. 다른 언어는 같은 문제를 다른 방법으로 해결합니다
  • 330. 참고문헌과 더 읽을 거리들 Programming in Scala, 2nd edition ✓ http://www.artima.com/shop/programming_in_scala_2ed http://www.scala-lang.org/ http://doc.akka.io/docs/akka/2.0.3/ http://en.wikipedia.org/wiki/Scala http://en.wikipedia.org/wiki/Functional_programming http://en.wikipedia.org/wiki/Actor_model http://twitter.github.com/scala_school/ 꽃보다 Scala(long version) ✓ https://docs.google.com/document/pub? id=1kSNKKKwM8rjGhn9Gnw-6Q0VCImpwSRZ7_QzwNwXgMxM http://blog.typesafe.com/scala-on-heroku Seven Languages in Seven Weeks ✓ http://www.amazon.co.uk/Seven-Languages-Weeks-Programming-Programmers/dp/193435659X
  • 331. 참고문헌과 더 읽을 거리들 Functional Programming Principles in Scala https:// www.coursera.org/ course/progfun by Martin Odersky, the creator of Scala
  • 332. Q&A

Hinweis der Redaktion

  1. \n
  2. \n
  3. \n
  4. \n
  5. \n
  6. \n
  7. \n
  8. \n
  9. \n
  10. \n
  11. \n
  12. \n
  13. \n
  14. \n
  15. \n
  16. \n
  17. \n
  18. \n
  19. \n
  20. \n
  21. \n
  22. \n
  23. \n
  24. \n
  25. \n
  26. \n
  27. \n
  28. \n
  29. \n
  30. \n
  31. \n
  32. \n
  33. \n
  34. \n
  35. \n
  36. \n
  37. \n
  38. \n
  39. \n
  40. \n
  41. \n
  42. \n
  43. \n
  44. \n
  45. \n
  46. \n
  47. \n
  48. \n
  49. \n
  50. \n
  51. \n
  52. \n
  53. \n
  54. \n
  55. \n
  56. \n
  57. \n
  58. \n
  59. \n
  60. \n
  61. \n
  62. \n
  63. \n
  64. \n
  65. \n
  66. \n
  67. \n
  68. \n
  69. \n
  70. \n
  71. \n
  72. \n
  73. \n
  74. \n
  75. \n
  76. \n
  77. \n
  78. \n
  79. \n
  80. \n
  81. \n
  82. \n
  83. \n
  84. \n
  85. \n
  86. \n
  87. \n
  88. \n
  89. \n
  90. \n
  91. \n
  92. \n
  93. \n
  94. \n
  95. \n
  96. \n
  97. \n
  98. \n
  99. \n
  100. \n
  101. \n
  102. \n
  103. \n
  104. \n
  105. \n
  106. \n
  107. \n
  108. \n
  109. \n
  110. \n
  111. \n
  112. \n
  113. \n
  114. \n
  115. \n
  116. \n
  117. \n
  118. \n
  119. \n
  120. \n
  121. \n
  122. \n
  123. \n
  124. \n
  125. \n
  126. \n
  127. \n
  128. \n
  129. \n
  130. \n
  131. \n
  132. \n
  133. \n
  134. \n
  135. \n
  136. \n
  137. \n
  138. \n
  139. \n
  140. \n
  141. \n
  142. \n
  143. \n
  144. \n
  145. \n
  146. \n
  147. \n
  148. \n
  149. \n
  150. \n
  151. \n
  152. \n
  153. \n
  154. \n
  155. \n
  156. \n
  157. \n
  158. \n
  159. \n
  160. \n
  161. \n
  162. \n
  163. \n
  164. \n
  165. \n
  166. \n
  167. \n
  168. \n
  169. \n
  170. \n
  171. \n
  172. \n
  173. \n
  174. \n
  175. \n
  176. \n
  177. \n
  178. \n
  179. \n
  180. \n
  181. \n
  182. \n
  183. \n
  184. \n
  185. \n
  186. \n
  187. \n
  188. \n
  189. \n
  190. \n
  191. \n
  192. \n
  193. \n
  194. \n
  195. \n
  196. \n
  197. \n
  198. \n
  199. \n
  200. \n
  201. \n
  202. \n
  203. \n
  204. \n
  205. \n
  206. \n
  207. \n
  208. \n
  209. \n
  210. \n
  211. \n
  212. \n
  213. \n
  214. \n
  215. \n
  216. \n
  217. \n
  218. \n
  219. \n
  220. \n
  221. \n
  222. \n
  223. \n
  224. \n
  225. \n
  226. \n
  227. \n
  228. \n
  229. \n
  230. \n
  231. \n
  232. \n
  233. \n
  234. \n
  235. \n
  236. \n
  237. \n
  238. \n
  239. \n
  240. \n
  241. \n
  242. \n
  243. \n
  244. \n
  245. \n
  246. \n
  247. \n
  248. \n
  249. \n
  250. \n
  251. \n
  252. \n
  253. \n
  254. \n
  255. \n
  256. \n
  257. \n
  258. \n
  259. \n
  260. \n
  261. \n
  262. \n
  263. \n
  264. \n
  265. \n
  266. \n
  267. \n
  268. \n
  269. \n
  270. \n
  271. \n
  272. \n
  273. \n
  274. \n
  275. \n
  276. \n
  277. \n
  278. \n
  279. \n
  280. \n
  281. \n
  282. \n
  283. \n
  284. \n
  285. \n
  286. \n
  287. \n
  288. \n
  289. \n
  290. \n
  291. \n
  292. \n
  293. \n
  294. \n
  295. \n
  296. \n
  297. \n
  298. \n
  299. \n
  300. \n
  301. \n
  302. \n
  303. \n
  304. \n
  305. \n
  306. \n
  307. \n
  308. \n
  309. \n
  310. \n
  311. \n
  312. \n
  313. \n
  314. \n
  315. \n
  316. \n
  317. \n
  318. \n
  319. \n
  320. \n
  321. \n
  322. \n
  323. \n
  324. \n
  325. \n
  326. \n
  327. \n
  328. \n
  329. \n
  330. \n
  331. \n
  332. \n
  333. \n
  334. \n
  335. \n
  336. \n
  337. \n
  338. \n
  339. \n
  340. \n
  341. \n
  342. \n
  343. \n
  344. \n
  345. \n
  346. \n
  347. \n
  348. \n
  349. \n
  350. \n
  351. \n