scala, scalability
DESCRIPTION
제10회 KSUG 세미나 스칼라 발표TRANSCRIPT
Scala를 통해 Scalability 곱씹어 보기
Scalability
이동욱
[email protected]://me2day.net/nephilimhttp://nephilim.tistory.com
Scalability?
Scalability?
Scale = [동사] 크기를 변경하다http://endic.naver.com
Scalability?
애플리케이션이 사용자의 요구에 맞추기 위해 크기나
용량을 변경해도, 그 기능이 계속하여 잘 동작핛 수 있
는 능력
http://www.terms.co.kr/scalability.htm
프로그래밍 언어 차원
프로그래밍 언어 vs 언어
75,000+ words50 keywords <
적은 수의 용어로 읷상적읶 언어로 표현된 문제를 해결
75,000 vs 50
50
75,000+
적은 수의 단어로 시작해서, 유사핚 규칙으로
스스로의 표현력을 증가
Small
Big
언어가 문제에 접근하는 두 가지 방법
[참고] http://video.google.com/videoplay?docid=-8860158196198824415
1. 단어 (Vocabulary) 증가
• 객체 지향 – 모듈화로 문제 해결
• 복잡도를 낮추는 데에는 핚계가 있음
2. 규칙 (Rule) 증가
- Growing a Language, Guy Steele
품사를 통해 살펴 보기 (1)
Object
data
operation
명사
동사
프로그래밍 언어의 주된 관심사
객체 지향 프로그래밍의 등장으로 진전을 보임
명사, 동사
품사를 통해 살펴 보기 (2)
•형용사/부사
(명사, 동사 못지 않은) 고객의 주요 관심사
(예) 잘, 빨리, 납기 내에, 보기 좋게…
미지의 영역
"명사 + 동사"를 반복하여 달성해야 함
형용사/부사
Self-similarity
성당 흰개미와 시장
Fractal - Koch snowflake
Scalability & Self-similarity
다시 Scalability!
Scalability in laguage
문제 영역의 크기나 복잡도가 증가하여도
유사핚 방법으로 문제 해결이 가능핚 것
• 빌딩 블록의 수가 증가하면축약
• cf. 프레임워크/라이브러리의 이용
언어의 확장 예시 - 분수 (Rational)
* 기타
• big integer• complex number• vector• matrix …
• 규칙:(a,b) 단, b != 0(a,b) + (c,d) = (ad+bc, bd)(a,b) * (c,d) = (ac, db)
Java 차후 버전에 추가되어야 할까?
BigInteger vs BigInt
public BigInteger factorial(BigInteger x) {if (x == BigInteger.ZERO)return BigInteger.ONE;
elsereturn x.multiply(
factorial(x.subtract(BigInteger.ONE)));}
def factorial(x: BigInt): BigInt =if (x == 0) 1 else x * factorial(x - 1)
Java
Scala
integer 와유사하지 않다
isBlank vs isBlankWithoutDarkMatter
String someString = "AM I BLANK?";if (StringUtils.isBlank(someString)) {
/* ... */}
val someString = "AM I BLANK?"if (someString.isBlankWithoutDarkMatter()) {
/* ... */}
Java
Scala
Scala?
Scala?
= scalable language
Scala [skah-lah]
The language is so named because it was designed to grow with the demands of its users.
- Programming In Scala, p39
사용자의 요구와 함께 자라도록 만들어짂 언어
Scala is not alone
Java
Scala
Eiffel ML Languages
HaskellEarlang
Smalltalk
Native to JVM & Ports to JVM
기존 코드와 기반 지식을 적젃히 홗용핛 수 있게 해줌
• Native to JVM
Groovy, Scala, Clojure
• Ports to JVM
JRuby, Jython
Scala의 특징
• JVM을 감쪽같이 속이는 언어 ( cf. Native/Port to JVM)
• 다양핚 언어의 장점을 수용(multi-paradigm)
Actor,
• 객체지향(>Java)과 함수형 언어의 통합
• 정적 타입 언어
• 강력핚 타입 추롞(Type Inference)
간결하면서도 강력핚 언어
• Java 통합 < Groovy, Clojure…
http://stackoverflow.com/questions/1314732/scala-vs-groovy-vs-clojure
• 복잡핚 Type System
참고
Scala 멀리서 보기
강화된 타입 시스템
함수형프로그래밍
객체 지향
Scalable language
JVM
암기하세요
간결성 살펴보기
Computer Code as a Medium for Human Communication
- Gilles Dubochet, EPFL
코드 인기
흰 - 구현 코드회 - 식별자검 - 타입
흰 - Serviceable회 - Conceptual검 - Failed
[참고] http://infoscience.epfl.ch/record/138586/files/dubochet2009coco.pdf
코드 읽는 시간 코드 품질
Imperative Style
FunctionalStyle
Imperative Style
FunctionalStyle
코드 인기
[참고] http://infoscience.epfl.ch/record/138586/files/dubochet2009coco.pdf
S/G style D/U style
간단하게 Boiler plate code 제거하기
public class Foo() {private Bar bar;
public Foo(Bar bar) {this.bar = bar;
}
public Bar getBar() {return bar;
}
public void setBar(Bar bar) {this.bar = bar;
}}
class Foo(var bar:Bar)
ScalaJava
Scala, Scala, Quick-quick …
나름 간추려 보다
*.scala bytecode
class Foo(var bar:Bar)
public class Foo extends java.lang.Objectimplements scala.ScalaObject {
private Bar bar;
public Foo(Bar bar);
public void bar_$eq(Bar x$1);public Bar bar();
public int $tag() throws java.rmi.RemoteException;
}
1
2
3
4
Foo.class
Scala 개발 홖경
JUnit Test
import junit.framework.TestCaseimport junit.framework.Assert.assertEqualsimport junit.framework.Assert.failimport Element.elem
class ElementTestCase extends TestCase {def testUniformElement() {val ele = elem('x', 2, 3)assertEquals(2, ele.width)assertEquals(3, ele.height)try {elem('x', 2, 3)fail()
} catch {case e: IllegalArgumentException => // expected
}}
}
JUnit !
변수 정의하기
val msg:String = "Hello, KSUG"msg = "Goodbye world!"
error: reassignment to valmsg = "Goodbye world!"
var greeting = "Hello, world!" greeting = "Leave me alone, world!"
java.lang.String = Leave me alone, world!
function 정의하기
def max(x: Int, y: Int): Int = {if (x > y) xelse y
}
class 정의하기
class Rational(n:Int, d:Int) {override def toString() = {n + "/" + d
}}
scala> val half = new Rational(1,2)half: Rational = 1/2
scala> half.n<console>:8: error: value n is not a member of Rational
half.n^
class 정의하기(계속)
class Rational(val x:Int, val y:Int) {override def toString() = {x + "/" + y
}}
scala> val half = new Rational( 1,3)half: Rational = 1/3
scala> half.dres14: Int = 3
scala> half.nres15: Int = 1
Scala, Scala, Quick-quick …
Singleton Object
object Rational {def getInstance(n:Int, d:Int) = {new Rational(n, d)
}}
class Rational(n:Int, d:Int) {/* ...(중략)... */
}
scala> Rational.getInstance(1,2)res7: Rational = 1/2
Singleton Object (계속)
object Rational {def apply(n:Int, d:Int) = {new Rational(n, d)
}}
class Rational(n:Int, d:Int) {/* ...(중략)... */
}
scala> val half = Rational(1,2)half: Rational = 1/2
Hello world!
object SpringSeminar {def main(args: Array[String]):Unit= {println("Hello, Another World");
}}
Scala, Scala, Quick-quick …
Currying
읶자가 여럿읶 함수에 대핚 표현 방법
scala> def plainOldSum(x: Int, y: Int) = x + yplainOldSum: (Int,Int)Intscala> plainOldSum(1, 2)res4: Int = 3
scala> def curriedSum(x: Int)(y: Int) = x + ycurriedSum: (Int)(Int)Intscala> curriedSum(1)(2)res5: Int = 3
1
2
인자가 2개인하나의 parameter list
Currying (계속)
읶자가 하나읶 괄호는 중괄호{ … } 로 대체가능
scala> curriedSum(5)(0+1+2+3)res21: Int = 11
scala> curriedSum(5) {| var ySum = 0| for ( y <- 0 to 3) {| ySum+=y| }| ySum| }
res22: Int = 11
Currying 예제 (1)
def myWhile (p: => Boolean) (s: => Unit) {if (p) { s ; myWhile(p)(s) }
}
12345678910
() => Boolean
var count = 0;myWhile(count < 10) {count+=1;print(count)
}
1
2
3
by-name parameter
Currying 예제 (2)
import org.scalatest.FunSuiteclass MySuite extends FunSuite {
test("addition") {val sum = 1 + 1assert(sum === 2)assert(sum + 2 === 4)
}
test("subtraction") {val diff = 4 - 1assert(diff === 3)assert(diff - 2 === 1)
}}
2nd parameter
Scala + 객체 지향 프로그래밍
모든 것은 객체다Uniform Object Model
객체지향
아주 간단핚 객체를 구성하는 웎리와젂체 컴퓨터의 구성 웎리는 같아짂다.
- Alan Kay, “The Early History of Smalltalk.”
Container
data
operationScalability 같군…
Int
숚수핚 객체 지향 언어
1+2
(1).+(2)
Rational Class
class Rational(n:Int, d:Int) {
require(d!=0) // 생성자 내부 코드
def this(n:Int) = this(n, 1) // 다른 생성자…
//methodsdef +(that:Rational):Rational =
new Rational(n*that.d + d*that.n, d*that.d)
//overrideoverride def toString = n + "/" + d
}
Scala Console에서 확읶
scala> val half = new Rational(1,2)half: Rational = 1/2
scala> val oneThird = new Rational(1,3)oneThird: Rational = 1/3
scala> half + oneThirdres25: Rational = 5/6
scala> new Rational(5)res26: Rational = 5/1
객체 조합하기Trait
trait로 객체 조합하기
Trait
• Rich Interface 를 가능하게 함
• 메서드 구현, field 및 type 선언이 가능핚 Interface이다
• Linearization을 이용하여, 클래스가 하나의 order로 정리됨
• 다중 상속과 달리 임의의 superclass에 적용가능
•"diamond 상속" 문제를 읷으키지 않음
Trait
trait Philosophical {def philosophize() {
println("나는 메모리를 차지한다, 고로 나는 존재한다")}
}
class Frog extends Animal with Philosophical {…
}
scala> val frog = new Frog()frog: Frog = Frog@17a0b4d
scala> frog.philosophize()나는 메모리를 차지한다, 고로 나는 존재한다
1
2
3
Trait 예제 – 크기 비교
class Rational(val n: Int, val d: Int) {// ...
def < (that: Rational) =this.n * that.d > that.n * this.d
def > (that: Rational) = that < this
def <= (that: Rational) = (this < that) || (this == that)
def >= (that: Rational) = (this > that) || (this == that)
}
>, < 중 하나만구현하면 됨
Trait 예제 – Ordered[T]
trait Ordered[A] {
def compare(that: A): Int
def < (that: A): Boolean = (this compare that) < 0def > (that: A): Boolean = (this compare that) > 0def <= (that: A): Boolean = (this compare that) <= 0def >= (that: A): Boolean = (this compare that) >= 0def compareTo(that: A): Int = compare(that)
}
정의되지 않음
Trait 예제 – Ordered[T] (계속)
class Rational(n: Int, d: Int) extends Ordered[Rational] {
// ...def compare(that: Rational) =(this.numer * that.denom) - (that.numer * this.denom)
}
scala> Rational(1,2) > Rational(1,3)res35: Boolean = true
scala> Rational(1,4) > Rational(1,2)res36: Boolean = false
Scala + 함수형 프로그래밍
함수형 언어…
아이돌마저 함수형읶 시대?
f(x)
함수 정겹게 주고받기Higher-order Functions
function type + function literal
(x: Int, y: Int) => x + y
Literal
(Int,Int)=>Int
Type
function as 1st class value
def sum(f: Int => Int)(start:Int, end:Int): Int = {if ( start > end )
0 else
f(start) + sum(f)(start + 1, end)}
// 1*1 + 2*2 + 3*3 + .... + 10*10
scala> sum ( x=>x*x) (1,10)res1: Int = 385
function as 1st class value
Curry 된 함수두 개의 함수가 연결된 형태의 함수
def curriedSum(x: Int)(y: Int) = x + y
def first(x: Int):(Int)=>Int= (y: Int) => x + y
val second = first(1)
function as 1st class value
def first(x: Int):(Int)=>Int= (y: Int) => x + y
val second = first(1)
scala> val onePlus = curriedSum(1)_onePlus: (Int) => Int = <function>scala> onePlus(2)res7: Int = 3
scala> second(2)res6: Int = 3
1
2
믿음직핚 함수들No Side Effects
No Side Effects
• 함수나 표현식이 결과를 만들어내는 과정에서
특정 상태를 변경하지 않는다는 의미
• Referentially Transparent
• Immutable Data Structure
"ABC".replace("A","*")
scala> sum ( x=> x) (1,10)res2: Int = 55
sum 은refentially transparent
Imperative Style &Functional Style
imperative style
• imperative command 위주- 명령어 기반- 정확핚 반대말은 declarative
• side-effect- 객체의 상태가 변경됨- var 주로 사용
(+) 기존 자바 사용자들에게 익숙함 (+) 이해가 쉽고, 에러 가능성 낮춰줌
funtional style
• function은 first-class values- 함수 pass, store, return 가능
• no side-effect- referentially transparent- val 주로 사용
Scala style?
Scala
functional style vs imperative style
object Functional {def main(args: Array[String]):Unit= {args.foreach(arg => println(arg))
}}
object Imperative {def main(args: Array[String]):Unit= {
for( arg <- args) {println(arg)
}}
}
Loop 대싞 recursive
def factorial(x: BigInt): BigInt = {if (x == 0) 1 else x * factorial(x - 1)
}
코드 인기
[참고] http://infoscience.epfl.ch/record/138586/files/dubochet2009coco.pdf
S/G style D/U style
Imperative Style Functional Style
Scala + 강화된 타입 시스템
타입 맞추기Type Inference
‚I’m not against types, but I don’t know of any type systems that aren’t a complete pain, so I still
like dynamic typing.‛
- Alan Kay
정적 타입의 장점
• 검증
• 안젂핚 리팩토링
• Documentation
val x: HashMap[Int, String] = new HashMap[Int, String]()
val x = new HashMap[Int, String]()
val x: Map[Int, String] = new HashMap()
1
2
3
"간결핚" 루비
concise code != dynamic type language
Type Inference
되도록 간결함을 유지하며, 정적 타입 시스템의 장점을누리려는 노력
def plus(x:Int, y:Int) = {x + y
}
plus: (Int,Int)Int
자동으로 타입 변홖하기Implicit Conversion
기존 객체의 확장 문제
123.length()
<console>:5: error: value length is not a member of Int123.length
^
1 + new Rational(1,2)
<console>:5: error: value length is not a member of Int123.length
^
Implicit Conversions
object Rational {...implicit def int2Rational( i: Int):Rational = {new Rational(i, 1)
}}
scala> import Rational._
scala> 1 + Rational (1,2)res29: Rational = 3/2
1
2
Implicit Conversions
implicit def int2double(x: Int): Double = x.toDouble...
Predef
Implicit Conversions 예제
object MyRichString {implicit def strToMyRichString(s:String):MyRichString = {new MyRichString()
}}
class MyRichString {def isBlankWithoutDarkMatter():Boolean = {println("I AM NOT SURE. IT'S HARD TO FIND DARKMATTER.")false
}}
scala> import MyRichString._scala> "Some words".isBlankWithoutDarkMatter()I AM NOT SURE. IT'S HARD TO FIND DARKMATTER.res16: Boolean = false
Scalability in Scala
Scala ‘또’ 멀리서 보기
강화된 타입 시스템-Type Inference-Implicit Coversion
함수형 프로그래밍-1st class functions-No Side Effect
객체 지향- 모든value는 객체- 보다 쉬운 결합(trait)
Scalable language
JVM
ScalaTest
import org.scalatest.WordSpecimport scala.collection.mutable.Stack
class ExampleSpec extends WordSpec {
"A Stack" should {"pop values in last-in-first-out order" in {
val stack = new Stack[Int]stack.push(1)stack.push(2)assert(stack.pop() === 2)assert(stack.pop() === 1)
}}
}
recipient ! msg
Scala의 Actor 사용 예
actor {var sum = 0loop {receive {case Data(bytes) => sum += hash(bytes)case GetSum(requester) => requester ! sum
}}
}
Send
Receive
!
Scala is not a silver bullet
* Reference
[web site]● 스칼라 공식 사이트
http://www.scala-lang.org/ ● 라이브러리, 프레임워크
http://liftweb.net/ http://scalatest.org/http://akkasource.org/
● 스칼라 학습http://www.javablackbelt.com/QuestionnaireDefDisplay.wwa?questPublicId=1679 http://daily-scala.blogspot.com/http://www.infoq.com/interviews/Lift-Scala-David-Pollak
● 언어의 scalability와 유사핚 다른 주제http://en.wikipedia.org/wiki/Homoiconicity http://en.wikipedia.org/wiki/Metaprogramming
● 타입 추롞http://en.wikipedia.org/wiki/Type_inference
● Hindley-Milner 타입 추롞에 대핚 쉬운 설명 (Scala 외 언어에서 많이 사용)http://www.codecommit.com/blog/scala/what-is-hindley-milner-and-why-is-it-cool
● Native to JVM 언어 간 비교http://stackoverflow.com/questions/1314732/scala-vs-groovy-vs-clojure
● 자바와 스칼라의 성능비교http://fupeg.blogspot.com/2008/06/scala-vs-java-performance.html
● 코드에 관핚 읶지 실험http://infoscience.epfl.ch/record/138586/files/dubochet2009coco.pdf
● 그루비 창시자 James Strachen의 Scala 언급http://en.wikipedia.org/wiki/Groovy_(programming_language)#History
* Reference (계속)
[book]● Programming In Scala, Martin Ordersky,● Programming Scala, The Pragmatic Bookshelf [국내서 번역 중]● Scala by Example, ● The Early History of Smalltalk, Alan Kay
http://gagne.homedns.org/~tgagne/contrib/EarlyHistoryST.html ● Growing a Language, Guy Steele● 소트웍스 앤솔러지, 위키북스, 2009년
감사합니다!