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)
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();
}
}
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/
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...
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;
}
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
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
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 을 위한 다양한 도구를 지원함
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"
}
153. case class
case class Calculator(brand: String, model: String)
accessor, equals(==), hashCode(##), toString,
copy, pattern matching, factory function
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
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
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
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)
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) => ...
}
}
252. Horizontal Scale
The Multi-core Era
✓ Moore Law
=> 반도체 집적 회로의 성능은 18개월 마다 2배로 증간한다
=> 최근에는 클럭수가 아닌 코어의 증가로 이루어짐
The Big-data Era
✓ 마구 쏟아지는 엄청난 데이터를 처리해야함
병렬/동시/분산 처리가 중요해짐
✓ 하지만, 동시성 문제는 언제나 어렵다
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”
”
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")
}
}
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
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)