Your SlideShare is downloading. ×
[H3 2012] 꽃보다 Scala
Upcoming SlideShare
Loading in...5
×

Thanks for flagging this SlideShare!

Oops! An error has occurred.

×

Introducing the official SlideShare app

Stunning, full-screen experience for iPhone and Android

Text the download link to your phone

Standard text messaging rates apply

[H3 2012] 꽃보다 Scala

4,374
views

Published on

H3 2012 발표자료 …

H3 2012 발표자료
꽃보다 Scala
-KTH 김상범

Published in: Technology

0 Comments
49 Likes
Statistics
Notes
  • Be the first to comment

No Downloads
Views
Total Views
4,374
On Slideshare
0
From Embeds
0
Number of Embeds
9
Actions
Shares
0
Downloads
219
Comments
0
Likes
49
Embeds 0
No embeds

Report content
Flagged as inappropriate Flag as inappropriate
Flag as inappropriate

Select your reason for flagging this presentation as inappropriate.

Cancel
No notes for slide
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • Transcript

    • 1. 꽃보다Scala !김상범 | @taokim
    • 2. “만약, 2003년경에 누군가 나에게 Programming in Scala 라는 책을 보여줬다면 나는 절대로 Groovy를 만들지 않았을 것이다 ” James Strachan, the creator of Groovy
    • 3. TOC1. Scala?2. Functional Style3. Pattern Matching4. Horizontal Scale
    • 4. Scala?
    • 5. Scala?object HelloWorld { def main(args:Array[String]){ println("Hello, world!") }}
    • 6. Scala?
    • 7. Scala?Quick Scala Facts
    • 8. Scala? Quick Scala FactsJVM/.NET 에서 구동되는 범용 multi-paradigm 언어
    • 9. Scala? Quick Scala FactsJVM/.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)
    • 16. Scala?
    • 17. Scala?Quick Scala Facts
    • 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/POJOclass 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(); }}
    • 29. Scala?
    • 30. Scala?Great interoperability with Java
    • 31. Scala?Great interoperability with JavaScala는 자바와 소스 코드 레벨에서만 다름
    • 32. Scala?Great interoperability with JavaScala는 자바와 소스 코드 레벨에서만 다름컴파일되면 “.class” 파일이 나옴
    • 33. Scala?Great interoperability with JavaScala는 자바와 소스 코드 레벨에서만 다름컴파일되면 “.class” 파일이 나옴Scala코드에서 Java클래스를 그대로 import 해서 사용
    • 34. Scala?Great interoperability with JavaScala는 자바와 소스 코드 레벨에서만 다름컴파일되면 “.class” 파일이 나옴Scala코드에서 Java클래스를 그대로 import 해서 사용한 프로젝트에서 Java와 Scala 파일을 섞어서 사용 가능
    • 35. Scala?Great interoperability with JavaScala는 자바와 소스 코드 레벨에서만 다름컴파일되면 “.class” 파일이 나옴Scala코드에서 Java클래스를 그대로 import 해서 사용한 프로젝트에서 Java와 Scala 파일을 섞어서 사용 가능Java 가 지원되는 어떤 환경/클라우드에도 배포 가능
    • 36. Scala?Great interoperability with JavaScala는 자바와 소스 코드 레벨에서만 다름컴파일되면 “.class” 파일이 나옴Scala코드에서 Java클래스를 그대로 import 해서 사용한 프로젝트에서 Java와 Scala 파일을 섞어서 사용 가능Java 가 지원되는 어떤 환경/클라우드에도 배포 가능그리고 Android ~
    • 37. Great interoperability with Javaimport 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))
    • 38. Popularity and Use Grow Commercial Adoptions Twitter✓ 메시지 패싱 시스템을 Ruby에서 Scala 기반으로 변경✓ Finagle, Gizzard, Kestrel, ... Linked-in✓ 소셜 그래프 서비스 (380-400M transaction/day)✓ Apache Kafka Foursquare✓ 웹을 포함한 모든 서비스가 Scala로 작성됨 Tumblr✓ 분산 시스템을 위해 Finagle 선택
    • 39. 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/
    • 40. Scala Job trends출처: http://www.indeed.com/jobtrends/scala.html
    • 41. 근데,어렵진 않나요?...
    • 42. LISP, Haskell, Erlang, Clojure 등의 함수형 언어에 익숙하다면 쉽습니다
    • 43. Ruby, Python, Javascript 등의 언어에 익숙하다면 어렵진 않을 겁니다 :)
    • 44. 자바만주로 해오셨다면...
    • 45. 불지옥을 보시게될지도 모릅니다 ...
    • 46. 불지옥을 보시게될지도 모릅니다 ...
    • 47. Problems of Java
    • 48. Problems of Java자바코드 == 대하소설
    • 49. Problems of Java 자바코드 == 대하소설✓ 제한된 vocabulary
    • 50. Problems of Java 자바코드 == 대하소설✓ 제한된 vocabulary✓ 수 많은 third party 라이브러리 필수
    • 51. Problems of Java 자바코드 == 대하소설✓ 제한된 vocabulary✓ 수 많은 third party 라이브러리 필수✓ 너무 적은 언어의 기능/개념
    • 52. Problems of Java 자바코드 == 대하소설✓ 제한된 vocabulary✓ 수 많은 third party 라이브러리 필수✓ 너무 적은 언어의 기능/개념✓ Need more syntactic sugars!
    • 53. Problems of Java 자바코드 == 대하소설✓ 제한된 vocabulary✓ 수 많은 third party 라이브러리 필수✓ 너무 적은 언어의 기능/개념✓ Need more syntactic sugars!
    • 54. Problems of Java 자바코드 == 대하소설✓ 제한된 vocabulary✓ 수 많은 third party 라이브러리 필수✓ 너무 적은 언어의 기능/개념✓ Need more syntactic sugars! 이미 legacy, 너무 느린 발전 속도
    • 55. Problems of Java 자바코드 == 대하소설✓ 제한된 vocabulary✓ 수 많은 third party 라이브러리 필수✓ 너무 적은 언어의 기능/개념✓ Need more syntactic sugars! 이미 legacy, 너무 느린 발전 속도 Oracle...
    • 56. Functional Style think f(x)!
    • 57. f(x)?
    • 58. f(x)?
    • 59. g(f(x))
    • 60. Imperative vsFunctional
    • 61. 명령형? Imperative style 우리에게 익숙한 그것 :)✓ C, C++, Java, ... 컴퓨터에게 절차적으로 명령을 내리는 방식✓ “x 와 y 를 더하고, 결과를 z에 담고, z를 화면에 출력” Advantages✓ 본질적으로 컴퓨터는 명령을 받고 수행하는 기계✓ 많은 프로그래밍 언어가 명령형이며, 수많은 개발자가 이 방식에 익숙함
    • 62. 함수형?
    • 63. 함수형?Functional style
    • 64. 함수형? Functional style값의 변환 transformation 을 강조
    • 65. 함수형? Functional style 값의 변환 transformation 을 강조✓ 값을 입력 받고 새로운 값을 리턴함
    • 66. 함수형? Functional style 값의 변환 transformation 을 강조✓ 값을 입력 받고 새로운 값을 리턴함 변경 불가능한 상태 immutable state 를 강조
    • 67. 함수형? Functional style 값의 변환 transformation 을 강조✓ 값을 입력 받고 새로운 값을 리턴함 변경 불가능한 상태 immutable state 를 강조✓ referentially transparent (e.g., java.lang.String)
    • 68. 함수형? Functional style 값의 변환 transformation 을 강조✓ 값을 입력 받고 새로운 값을 리턴함 변경 불가능한 상태 immutable state 를 강조✓ referentially transparent (e.g., java.lang.String) 부수 효과 없음 no side-effects 을 강조
    • 69. 함수형? Functional style 값의 변환 transformation 을 강조✓ 값을 입력 받고 새로운 값을 리턴함 변경 불가능한 상태 immutable state 를 강조✓ referentially transparent (e.g., java.lang.String) 부수 효과 없음 no side-effects 을 강조✓ 언제 계산 evaluation 을 하던, 같은 값을 리턴
    • 70. 함수형?
    • 71. 함수형?Functional style
    • 72. 함수형? Functional style최상위 개념으로서의 함수 first-class function
    • 73. 함수형? Functional style 최상위 개념으로서의 함수 first-class function✓ “function everywhere”
    • 74. 함수형? Functional style 최상위 개념으로서의 함수 first-class function✓ “function everywhere” Advantages
    • 75. 함수형? Functional style 최상위 개념으로서의 함수 first-class function✓ “function everywhere” Advantages✓ 본질적으로 병렬화가 가능하며 thread-safe 함
    • 76. 함수형? Functional style 최상위 개념으로서의 함수 first-class function✓ “function everywhere” Advantages✓ 본질적으로 병렬화가 가능하며 thread-safe 함✓ Lazy evaluation 과 같은 최적화가 용이
    • 77. 함수형? Functional style 최상위 개념으로서의 함수 first-class function✓ “function everywhere” Advantages✓ 본질적으로 병렬화가 가능하며 thread-safe 함✓ Lazy evaluation 과 같은 최적화가 용이✓ 함수를 연계하여, 코드를 좀 더 유연한 형태의 일반화 용이
    • 78. 명령형 vs 함수형명령형 Imperative 함수형 Functional 명령 command 함수 function 문장 sentence 표현식 expression 변수 variable 값 value변경가능 mutable 변경불가 immutable 루프 loop 재귀 recursion
    • 79. 명령형 vs 함수형 Scala?Scala 는 양쪽 스타일 모두를 지원문제의 영역 domain 에 맞는 방식을 선택일반적으로는 명령형보다 함수형을 권장
    • 80. 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); }}
    • 81. 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;}
    • 82. Functional Style(Java) Functional Enables Compositionpublic static List<Integer> addTwoToAll(List<Integer> items) { return addOneToAll(addOneToAll(items));}
    • 83. Function in Scala
    • 84. Function in Mathf(x) = x + 1
    • 85. Function in Scaladef f(x:Int):Int = x+1
    • 86. Function in Scala함수 인자 타입 def f(x:Int):Int = x+1
    • 87. Function in Scala 함수의 계산 결 과 타입 (리턴타입)함수 인자 타입 def f(x:Int):Int = x+1
    • 88. Function in Scala
    • 89. Function in Scaladef f(x:Int) = x + 1
    • 90. Function in Scaladef f(x:Int) = x + 1def g(x:Int) = x * x
    • 91. Function in Scaladef f(x:Int) = x + 1def g(x:Int) = x * xdef h(x:String, y:Int) = x + y
    • 92. Function in Scaladef f(x:Int) = x + 1def g(x:Int) = x * xdef h(x:String, y:Int) = x + y
    • 93. Function in Scaladef f(x:Int) = x + 1def g(x:Int) = x * xdef h(x:String, y:Int) = x + y => 추론 가능한 타입 선언 생략 가능
    • 94. Function in Scaladef f(x:Int) = x + 1def g(x:Int) = x * xdef h(x:String, y:Int) = x + y => 추론 가능한 타입 선언 생략 가능 => 첫 등장시에만 타입 선언
    • 95. Function call in Scalah("result:", f(g(3)))
    • 96. Anonymous function(λ expression) in Scala (x:Int) => x + 1(x:Int,y:Int) => x < y
    • 97. Anonymous functionval people: List[Person]val minors = people.filter((p:Person) => p.age < 20)
    • 98. Anonymous function : short formval people: List[Person]val minors = people.filter(p => p.age < 20)
    • 99. Anonymous function : placeholderval people: List[Person]val minors = people.filter(_.age < 20)
    • 100. addOneToAll in Scala Imperativedef addOneToAll(items: collection.mutable.ListBuffer[Int])= { var i = 0 while (i < items.length) { items.update(i, items(i) + 1) i += 1 }} Functionaldef addOneToAll(items: List[Int]) = items map (_ + 1)
    • 101. Functional Style with Collection
    • 102. Functional Style with Collectioncollection.map(f(x))
    • 103. Functional Style with Collection collection.map(f(x))모든 collection 에 존재
    • 104. Functional Style with Collection collection.map(f(x))모든 collection 에 존재함수 f 를 전달 받아 collection 의 각 item 에 f 를 적용
    • 105. Functional Style with Collection collection.map(f(x))모든 collection 에 존재함수 f 를 전달 받아 collection 의 각 item 에 f 를 적용f 의 결과를 같은 사이즈의 같은 collection 에 담아 리턴
    • 106. Functional Style with Collection collection.map(f(x)) 모든 collection 에 존재 함수 f 를 전달 받아 collection 의 각 item 에 f 를 적용 f 의 결과를 같은 사이즈의 같은 collection 에 담아 리턴scala> val strs = List("aaa", "bb", "c")
    • 107. 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)
    • 108. 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)
    • 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)scala> val ints = strs.map(str => str.length)ints: List[Int] = List(3, 2, 1)
    • 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)ints: List[Int] = List(3, 2, 1) String => Int
    • 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) String => Int
    • 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
    • 117. Functional Style with Collectioncollection.reduce(f(x,y))
    • 118. Functional Style with Collectioncollection.reduce(f(x,y))모든 collection 에 존재
    • 119. Functional Style with Collectioncollection.reduce(f(x,y))모든 collection 에 존재collection 에 존재하는 값들을 하나의 값으로 만듬
    • 120. Functional Style with Collection collection.reduce(f(x,y)) 모든 collection 에 존재 collection 에 존재하는 값들을 하나의 값으로 만듬scala> val nums = 1 to 5 //1.to(5)
    • 121. 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)
    • 122. 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)
    • 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)scala> val fact = nums.reduce((acc,num)=>acc*num)fact: Int = 120
    • 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)fact: Int = 120 (Int,Int)=> Int
    • 125. reduce돌돌돌~ 말아 보아요~
    • 126. reduce1 2 3 4
    • 127. reduce11 2 2 3 4 1*2 2
    • 128. reduce11 2 2 3 3 4 1*2 2 2 * 3 6
    • 129. reduce11 2 2 3 3 4 4 1*2 2 2 * 3 6 6 * 4 24
    • 130. reduce11 2 2 3 3 4 45 1*2 2 2 * 3 6 6 * 4 24 24 * 5 120
    • 131. Functional Style: map reduce
    • 132. Functional Style: map reduceval people :Array[Person] = ...
    • 133. Functional Style: map reduceval people :Array[Person] = ...val sum = people.map(_.age).reduce(_ + _)
    • 134. Functional Style: map reduceval people :Array[Person] = ...val sum = people.map(_.age).reduce(_ + _)val avg = sum / people.length
    • 135. Functional Style: map reduceval people :Array[Person] = ...val sum = people.map(_.age).reduce(_ + _)val avg = sum / people.length scala> val people = Array(Person("Charles", 50),
    • 136. Functional Style: map reduceval 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))
    • 137. Functional Style: map reduceval 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)
    • 138. Functional Style: map reduceval 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)
    • 139. Functional Style: map reduceval 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)
    • 140. Functional Style: map reduceval 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
    • 141. Functional Style: map reduceval 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
    • 142. 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 을 위한 다양한 도구를 지원함
    • 143. Pattern Matching
    • 144. match/case
    • 145. match/caseval new = old match { case 패턴1 => 값1 case 패턴2 => 값2 case _ => 기본값}
    • 146. Pattern matching Matching on valuesval times = 1val numStr = times match { case 1 => "one" case 2 => "two" case _ => "some other number"}
    • 147. Pattern matching Matching with guardsval times = 1val numStr = times match { case i if i == 1 => "one" case i if i == 2 => "two" case _ => "some other number"}
    • 148. Pattern matching Matching on typedef 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" }}
    • 149. Pattern matching Matching on class memberclass 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"}
    • 150. case classcase class Calculator(brand: String, model: String)
    • 151. case classcase class Calculator(brand: String, model: String) accessor, equals(==), hashCode(##), toString, copy, pattern matching, factory function
    • 152. case class
    • 153. case classscala> val a = Calculator("hp", "20B")
    • 154. case classscala> val a = Calculator("hp", "20B")a: Calculator = Calculator(hp,20B)
    • 155. case classscala> val a = Calculator("hp", "20B")a: Calculator = Calculator(hp,20B)scala> a ##
    • 156. case classscala> val a = Calculator("hp", "20B")a: Calculator = Calculator(hp,20B)scala> a ##res58: Int = 1619269961
    • 157. case classscala> val a = Calculator("hp", "20B")a: Calculator = Calculator(hp,20B)scala> a ##res58: Int = 1619269961scala> a toString
    • 158. case classscala> val a = Calculator("hp", "20B")a: Calculator = Calculator(hp,20B)scala> a ##res58: Int = 1619269961scala> a toStringres59: String = Calculator(hp,20B)
    • 159. case classscala> val a = Calculator("hp", "20B")a: Calculator = Calculator(hp,20B)scala> a ##res58: Int = 1619269961scala> a toStringres59: String = Calculator(hp,20B)scala> a.copy(model = "48G")
    • 160. case classscala> val a = Calculator("hp", "20B")a: Calculator = Calculator(hp,20B)scala> a ##res58: Int = 1619269961scala> a toStringres59: String = Calculator(hp,20B)scala> a.copy(model = "48G")res60: Calculator = Calculator(hp,48G)
    • 161. case classscala> val a = Calculator("hp", "20B")a: Calculator = Calculator(hp,20B)scala> a ##res58: Int = 1619269961scala> a toStringres59: String = Calculator(hp,20B)scala> a.copy(model = "48G")res60: Calculator = Calculator(hp,48G)scala> val b = Calculator("hp", "20B")
    • 162. case classscala> val a = Calculator("hp", "20B")a: Calculator = Calculator(hp,20B)scala> a ##res58: Int = 1619269961scala> a toStringres59: 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)
    • 163. case classscala> val a = Calculator("hp", "20B")a: Calculator = Calculator(hp,20B)scala> a ##res58: Int = 1619269961scala> a toStringres59: 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
    • 164. case classscala> val a = Calculator("hp", "20B")a: Calculator = Calculator(hp,20B)scala> a ##res58: Int = 1619269961scala> a toStringres59: 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 == bres61: Boolean = true
    • 165. Pattern Matching: case class
    • 166. Pattern Matching: case classdef calcType(calc: Calculator) = calc match {
    • 167. Pattern Matching: case classdef calcType(calc: Calculator) = calc match { case Calculator("hp", "20B") => "financial"
    • 168. Pattern Matching: case classdef calcType(calc: Calculator) = calc match { case Calculator("hp", "20B") => "financial" case Calculator("hp", "48G") => "scientific"
    • 169. Pattern Matching: case classdef calcType(calc: Calculator) = calc match { case Calculator("hp", "20B") => "financial" case Calculator("hp", "48G") => "scientific" case Calculator("hp", "30B") => "business"
    • 170. Pattern Matching: case classdef calcType(calc: Calculator) = calc match { case Calculator("hp", "20B") => "financial" case Calculator("hp", "48G") => "scientific" case Calculator("hp", "30B") => "business" case Calculator(b, m) =>
    • 171. Pattern Matching: case classdef 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)
    • 172. Pattern Matching: case classdef 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)}
    • 173. Pattern Matching: case classdef 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"))
    • 174. Pattern Matching: case classdef 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
    • 175. Pattern Matching: case classdef 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 = financialscala> calcType(Calculator("hp", "48G"))
    • 176. Pattern Matching: case classdef 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 = financialscala> calcType(Calculator("hp", "48G"))res63: java.lang.String = scientific
    • 177. Pattern Matching: case classdef 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 = financialscala> calcType(Calculator("hp", "48G"))res63: java.lang.String = scientificscala> calcType(Calculator("kth", "h3"))
    • 178. Pattern Matching: case classdef 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 = financialscala> calcType(Calculator("hp", "48G"))res63: java.lang.String = scientificscala> calcType(Calculator("kth", "h3"))res64: java.lang.String = Calculator: kth h3 is of unknown type
    • 179. Pattern Matching: case class
    • 180. Pattern Matching: case classscala> val calcs = List(Calculator("hp", "20B"),
    • 181. Pattern Matching: case classscala> val calcs = List(Calculator("hp", "20B"), | Calculator("hp", "48G"), Calculator("hp", "30B"),
    • 182. Pattern Matching: case classscala> val calcs = List(Calculator("hp", "20B"), | Calculator("hp", "48G"), Calculator("hp", "30B"), | Calculator("kth", "h3"))
    • 183. Pattern Matching: case classscala> 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))
    • 184. Pattern Matching: case classscala> 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)
    • 185. Pattern Matching: case classscala> 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
    • 186. Pattern Matching: case classscala> 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)financialscientific
    • 187. Pattern Matching: case classscala> 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)financialscientificbusiness
    • 188. Pattern Matching: case classscala> 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)financialscientificbusinessCalculator: kth h3 is of unknown type
    • 189. Pattern Matching: case class
    • 190. Pattern Matching: case classExample: Activity Stream
    • 191. Pattern Matching: case class Example: Activity StreamFacebook timeline
    • 192. Pattern Matching: case class Example: Activity StreamFacebook timelineSNS 사용자들의 활동 내역을 추상화
    • 193. Pattern Matching: case class Example: Activity StreamFacebook timelineSNS 사용자들의 활동 내역을 추상화이번 예제에서는 write/like 만 고려
    • 194. Pattern Matching: case class Example: Activity StreamFacebook timelineSNS 사용자들의 활동 내역을 추상화이번 예제에서는 write/like 만 고려
    • 195. Pattern Matching: case class Example: Activity StreamFacebook timelineSNS 사용자들의 활동 내역을 추상화이번 예제에서는 write/like 만 고려 “Someone likes my post”
    • 196. Example: Activity StreamActivity = S(주어) + V(동사) + O(목적어)
    • 197. Example: Activity Stream Activity = S(주어) + V(동사) + O(목적어)case class Activity( sub: Noun, verb: String, obj: Noun)
    • 198. Example: Activity StreamPerson and Post
    • 199. Example: Activity Stream Person and Posttrait Noun
    • 200. Example: Activity Stream Person and Posttrait Nouncase class Person(name: String, age: Int) extends Noun {
    • 201. Example: Activity Stream Person and Posttrait Nouncase class Person(name: String, age: Int) extends Noun { def followers: List[Person] = ...
    • 202. Example: Activity Stream Person and Posttrait Nouncase class Person(name: String, age: Int) extends Noun { def followers: List[Person] = ...}
    • 203. Example: Activity Stream Person and Posttrait Nouncase class Person(name: String, age: Int) extends Noun { def followers: List[Person] = ...}
    • 204. Example: Activity Stream Person and Posttrait Nouncase class Person(name: String, age: Int) extends Noun { def followers: List[Person] = ...}case class Post(author: Person, text: String) extends Noun
    • 205. Example: Activity StreamActivity
    • 206. Example: Activity Stream Activityval jane = Person("Jane", 59)
    • 207. Example: Activity Stream Activityval jane = Person("Jane", 59)val charles = Person("Charles", 50)
    • 208. Example: Activity Stream Activityval jane = Person("Jane", 59)val charles = Person("Charles", 50)val post = Post(jane, "hello, world")
    • 209. Example: Activity Stream Activityval jane = Person("Jane", 59)val charles = Person("Charles", 50)val post = Post(jane, "hello, world")val a1 = Activity(jane, "write", post)
    • 210. Example: Activity Stream Activityval 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)
    • 211. Example: Activity StreamPush or Email
    • 212. Example: Activity Stream Push or Emaildef sendPush(to: Person, msg: String)
    • 213. Example: Activity Stream Push or Emaildef sendPush(to: Person, msg: String)def sendEmail(to: Person, msg: String)
    • 214. Example: Activity StreamNotification
    • 215. Example: Activity Stream Notificationdef sendNoti(a: Activity) = {
    • 216. Example: Activity Stream Notificationdef sendNoti(a: Activity) = { a match {
    • 217. Example: Activity Stream Notificationdef sendNoti(a: Activity) = { a match { case Activity(someone: Person, "like", Post(author, _)) =>
    • 218. Example: Activity Stream Notificationdef sendNoti(a: Activity) = { a match { case Activity(someone: Person, "like", Post(author, _)) => sendPush(
    • 219. Example: Activity Stream Notificationdef sendNoti(a: Activity) = { a match { case Activity(someone: Person, "like", Post(author, _)) => sendPush( author,
    • 220. Example: Activity Stream Notificationdef sendNoti(a: Activity) = { a match { case Activity(someone: Person, "like", Post(author, _)) => sendPush( author, "%s likes your post".format(someone.name))
    • 221. Example: Activity Stream Notificationdef 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", _) =>
    • 222. Example: Activity Stream Notificationdef 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(
    • 223. Example: Activity Stream Notificationdef 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 =>
    • 224. Example: Activity Stream Notificationdef 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(
    • 225. Example: Activity Stream Notificationdef 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)))
    • 226. Example: Activity Stream Notificationdef 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))) }
    • 227. Example: Activity Stream Notificationdef 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. 조금 더 우아하게!
    • 229. 좀 더 우아하게 !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}
    • 230. 좀 더 우아하게!
    • 231. 좀 더 우아하게!val jane = Person("Jane", 59)
    • 232. 좀 더 우아하게!val jane = Person("Jane", 59)val charles = Person("Charles", 50)
    • 233. 좀 더 우아하게!val jane = Person("Jane", 59)val charles = Person("Charles", 50)val post = Post(jane, "hello, world")
    • 234. 좀 더 우아하게!val jane = Person("Jane", 59)val charles = Person("Charles", 50)val post = Post(jane, "hello, world")val a1 = jane write post
    • 235. 좀 더 우아하게!val jane = Person("Jane", 59)val charles = Person("Charles", 50)val post = Post(jane, "hello, world")val a1 = jane write postval a2 = charles like post
    • 236. 좀 더 우아하게!val jane = Person("Jane", 59)val charles = Person("Charles", 50)val post = Post(jane, "hello, world")val a1 = jane write postval a2 = charles like postdef sendNoti(a: Activity) {
    • 237. 좀 더 우아하게!val jane = Person("Jane", 59)val charles = Person("Charles", 50)val post = Post(jane, "hello, world")val a1 = jane write postval a2 = charles like postdef sendNoti(a: Activity) { a match {
    • 238. 좀 더 우아하게!val jane = Person("Jane", 59)val charles = Person("Charles", 50)val post = Post(jane, "hello, world")val a1 = jane write postval a2 = charles like postdef sendNoti(a: Activity) { a match { case someone write post => ...
    • 239. 좀 더 우아하게!val jane = Person("Jane", 59)val charles = Person("Charles", 50)val post = Post(jane, "hello, world")val a1 = jane write postval a2 = charles like postdef sendNoti(a: Activity) { a match { case someone write post => ... case Person(name, age) like Post(author, text) => ...
    • 240. 좀 더 우아하게!val jane = Person("Jane", 59)val charles = Person("Charles", 50)val post = Post(jane, "hello, world")val a1 = jane write postval a2 = charles like postdef sendNoti(a: Activity) { a match { case someone write post => ... case Person(name, age) like Post(author, text) => ... }
    • 241. 좀 더 우아하게!val jane = Person("Jane", 59)val charles = Person("Charles", 50)val post = Post(jane, "hello, world")val a1 = jane write postval a2 = charles like postdef sendNoti(a: Activity) { a match { case someone write post => ... case Person(name, age) like Post(author, text) => ... }}
    • 242. Pattern Matching
    • 243. Pattern MatchingMore usage
    • 244. Pattern Matching More usageval Person(name, age) = Person(“tao”,35)
    • 245. Pattern Matching More usageval Person(name, age) = Person(“tao”,35)“for” expression
    • 246. Pattern Matching More usageval Person(name, age) = Person(“tao”,35)“for” expressionCollections
    • 247. Pattern Matching More usageval Person(name, age) = Person(“tao”,35)“for” expressionCollectionsExtractors
    • 248. Pattern Matching More usageval Person(name, age) = Person(“tao”,35)“for” expressionCollectionsExtractorsXML
    • 249. Horizontal Scale
    • 250. Horizontal Scale The Multi-core Era✓ Moore Law => 반도체 집적 회로의 성능은 18개월 마다 2배로 증간한다 => 최근에는 클럭수가 아닌 코어의 증가로 이루어짐 The Big-data Era✓ 마구 쏟아지는 엄청난 데이터를 처리해야함 병렬/동시/분산 처리가 중요해짐✓ 하지만, 동시성 문제는 언제나 어렵다
    • 251. 왜?
    • 252. Horizontal Scale Root Cause 공유된 변경 가능한 상태 shared mutable state 동기화 synchronization✓ monitor & lock 예측 불가능한 상황을 피하기 위해서는✓ 변경 가능한 상태 mutable state 를 만들지 말아야 함✓ 즉, functional style 로 코드를 작성해야함
    • 253. “ 프로그램들은 버그로 가득차Thread를 사용하는 대부분의 있다 - Havoc Pennington @ Dreamforce 2011 ”
    • 254. Thread-lessconcurrencyActor model
    • 255. Actor model
    • 256. Actor modelActor Model
    • 257. Actor model Actor Model동시성 문제를 위한 더 단순한 고수준의 추상화 모델
    • 258. Actor model Actor Model 동시성 문제를 위한 더 단순한 고수준의 추상화 모델✓ Actors are objects which encapsulate state and behavior
    • 259. Actor model Actor Model 동시성 문제를 위한 더 단순한 고수준의 추상화 모델✓ Actors are objects which encapsulate state and behavior Erlang 이라는 언어를 통해 널리 알려짐
    • 260. Actor model Actor Model 동시성 문제를 위한 더 단순한 고수준의 추상화 모델✓ Actors are objects which encapsulate state and behavior Erlang 이라는 언어를 통해 널리 알려짐 Message passing, no shared memory
    • 261. Actor model Actor Model 동시성 문제를 위한 더 단순한 고수준의 추상화 모델✓ Actors are objects which encapsulate state and behavior Erlang 이라는 언어를 통해 널리 알려짐 Message passing, no shared memory Event loop
    • 262. Worker vs Actor WorkerQueue Worker take lock Shared Job Memory Worker #3 put Worker
    • 263. Worker vs Actor Actor #1 mailbox messagemessages Actor #2 To: Actor#1 Actor #3 Actor #4
    • 264. Scala Actor
    • 265. “ Bruce: “그 때(루비를 만들었을 당시)로 돌아간다 면, 어떤 기능에 변화를 주고 싶으세요?” Matz: “Thread를 없애고, Actor 나 또는 좀 더 진 보된 형태의 동시성 기능을 추가했을거에요” Interview with Yukihiro Matsumoto (the creator of Ruby) from the book, “Seven Languages in Seven Weeks” ”
    • 266. Scala Actor
    • 267. Scala ActorAkka
    • 268. Scala Actor AkkaScala로 작성된 Actor model 구현
    • 269. Scala Actor AkkaScala로 작성된 Actor model 구현TypeSafe Stack with Play! Framework
    • 270. Scala Actor AkkaScala로 작성된 Actor model 구현TypeSafe Stack with Play! Framework곧 Scala에 built-in 될 예정
    • 271. Scala Actor Akka Scala로 작성된 Actor model 구현 TypeSafe Stack with Play! Framework 곧 Scala에 built-in 될 예정✓ 기존 Scala 자체 구현은 deprecate 될 예정
    • 272. Scala Actor Akka Scala로 작성된 Actor model 구현 TypeSafe Stack with Play! Framework 곧 Scala에 built-in 될 예정✓ 기존 Scala 자체 구현은 deprecate 될 예정 자바를 위한 별도 API 제공
    • 273. Scala Actor Akka Scala로 작성된 Actor model 구현 TypeSafe Stack with Play! Framework 곧 Scala에 built-in 될 예정✓ 기존 Scala 자체 구현은 deprecate 될 예정 자바를 위한 별도 API 제공 Asynchronous/non-blocking
    • 274. Scala Actor Akka Scala로 작성된 Actor model 구현 TypeSafe Stack with Play! Framework 곧 Scala에 built-in 될 예정✓ 기존 Scala 자체 구현은 deprecate 될 예정 자바를 위한 별도 API 제공 Asynchronous/non-blocking 격리된 변경 가능 상태 Isolated mutable state
    • 275. Akka Actorimport akka.actor.Actorimport akka.actor.Propsimport akka.event.Loggingclass MyActor extends Actor { val log = Logging(context.system, this) def receive = { case "test" log.info("received test") case _ log.info("received unknown message") }}
    • 276. Akka Actorimport akka.actor.Actorimport akka.actor.Propsimport akka.event.Loggingclass MyActor extends Actor { val log = Logging(context.system, this) def receive = { case "test" log.info("received test") case _ log.info("received unknown message") }}
    • 277. Akka
    • 278. AkkaCreating actor
    • 279. Akka Creating actorval system = ActorSystem("MySystem")val myActor = system.actorOf(Props[MyActor], name = "myactor")
    • 280. Akka Creating actorval system = ActorSystem("MySystem")val myActor = system.actorOf(Props[MyActor], name = "myactor") Sending a message
    • 281. Akka Creating actorval system = ActorSystem("MySystem")val myActor = system.actorOf(Props[MyActor], name = "myactor") Sending a messagemyActor ! "test"myActor.tell("test")
    • 282. Akka Creating actorval system = ActorSystem("MySystem")val myActor = system.actorOf(Props[MyActor], name = "myactor") Sending a messagemyActor ! "test"myActor.tell("test") Tell: Fire and Forget
    • 283. Akka
    • 284. AkkaReplying
    • 285. Akka Replyingdef receive = { case "ping" sender ! "pong" ...
    • 286. Akka Replyingdef receive = { case "ping" sender ! "pong" ... Asking
    • 287. Akka Replyingdef receive = { case "ping" sender ! "pong" ... Askingval future1 = pingpongActor ? "ping"val future2 = pingpongActor.ask("ping")
    • 288. Example: ActivityStream
    • 289. Example: ActivityStreamclass NotiActor extends Actor {
    • 290. Example: ActivityStreamclass NotiActor extends Actor { def sendPush(to: Person, msg: String) {
    • 291. Example: ActivityStreamclass NotiActor extends Actor { def sendPush(to: Person, msg: String) { println("Send Push [To: %s][Msg: %s]".format(to, msg))
    • 292. Example: ActivityStreamclass NotiActor extends Actor { def sendPush(to: Person, msg: String) { println("Send Push [To: %s][Msg: %s]".format(to, msg)) }
    • 293. Example: ActivityStreamclass 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) {
    • 294. Example: ActivityStreamclass 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))
    • 295. Example: ActivityStreamclass 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)) }
    • 296. Example: ActivityStreamclass 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 = {
    • 297. Example: ActivityStreamclass 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, _) =>
    • 298. Example: ActivityStreamclass 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))
    • 299. Example: ActivityStreamclass 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 _ =>
    • 300. Example: ActivityStreamclass 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{
    • 301. Example: ActivityStreamclass 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 =>
    • 302. Example: ActivityStreamclass 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,
    • 303. Example: ActivityStreamclass 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))
    • 304. Example: ActivityStreamclass 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)) }
    • 305. Example: ActivityStreamclass 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: ActivityStreamclass 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: ActivityStreamSending activities
    • 308. Example: ActivityStream Sending activitiesval jane = Person("Jane", 59)
    • 309. Example: ActivityStream Sending activitiesval jane = Person("Jane", 59)val charles = Person("Charles", 50)
    • 310. Example: ActivityStream Sending activitiesval jane = Person("Jane", 59)val charles = Person("Charles", 50)val post = Post(jane, "hello, world")
    • 311. Example: ActivityStream Sending activitiesval jane = Person("Jane", 59)val charles = Person("Charles", 50)val post = Post(jane, "hello, world")val system = ActorSystem("ActivityStream")
    • 312. Example: ActivityStream Sending activitiesval jane = Person("Jane", 59)val charles = Person("Charles", 50)val post = Post(jane, "hello, world")val system = ActorSystem("ActivityStream")val notiActor = system.actorOf(
    • 313. Example: ActivityStream Sending activitiesval 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")
    • 314. Example: ActivityStream Sending activitiesval 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)
    • 315. Example: ActivityStream Sending activitiesval 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)
    • 316. Example: ActivityStreamScale Up (Concurrency)
    • 317. Example: ActivityStream Scale Up (Concurrency)val notiActor = system.actorOf( Props[NotiActor].withRouter(RoundRobinRouter(5)) "notication")
    • 318. 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")
    • 319. Example: ActivityStreamScale Out (Remoting)
    • 320. Example: ActivityStream Scale Out (Remoting)val notiActor = context.actorFor( "akka://activity@192.168.10.2:2552/user/notification")
    • 321. 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")
    • 322. 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 !
    • 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") ? Location Transparency coming soon !
    • 324. Akka More UsageEvent BusSchedulerFault ToleranceSTM (Software Transactional Memory)FSM (Finite State Machine)Asynchronous IOExtensions for ZeroMQ, Camel, ...
    • 325. Scala?
    • 326. 더 강력한 표현력더 강력한 동시성 처리기존 JVM 기반 환경 재사 용
    • 327. 다른 언어는같은 문제를다른 방법으로해결합니다
    • 328. 참고문헌과 더 읽을 거리들 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
    • 329. 참고문헌과 더 읽을 거리들 Functional ProgrammingPrinciples in Scala https://www.coursera.org/ course/progfun by Martin Odersky, the creator of Scala
    • 330. Q&A