10. Multiple dispatch (한글)
Multiple dispatch¶
참고문헌¶
https://github.com/JuliaComputing/JuliaBoxTutorials/tree/master/introductory-tutorials/intro-to-julia (github : JuliaComputing/JuliaBoxTutorials/introductory-tutorials/intro-to-julia/)
Topics:
함께보기¶
- http://deepstat.tistory.com/45 (01. Getting started)(in English)
- http://deepstat.tistory.com/46 (01. Getting started(한글))
- http://deepstat.tistory.com/47 (02. Strings)(in English)
- http://deepstat.tistory.com/48 (02. Strings(한글))
- http://deepstat.tistory.com/49 (03. Data structures)(in English)
- http://deepstat.tistory.com/50 (03. Data structures(한글))
- http://deepstat.tistory.com/51 (04. Loops)(in English)
- http://deepstat.tistory.com/52 (04. Loops(한글))
- http://deepstat.tistory.com/53 (05. Conditionals)(in English)
- http://deepstat.tistory.com/54 (05. Conditionals(한글))
- http://deepstat.tistory.com/55 (06. Functions)(in English)
- http://deepstat.tistory.com/56 (06. Functions(한글))
- http://deepstat.tistory.com/57 (07. Packages)(in English)
- http://deepstat.tistory.com/58 (07. Packages(한글))
- http://deepstat.tistory.com/59 (08. Plotting)(in English)
- http://deepstat.tistory.com/60 (08. Plotting(한글))
- http://deepstat.tistory.com/61 (09. Julia is fast)(in English)
- http://deepstat.tistory.com/62 (09. Julia is fast(한글))
- http://deepstat.tistory.com/63 (10. Multiple dispatch)(in English)
f(x) = x^2
그러면 Julia는아래와 같이 input이 그럴듯한지 아닌지 스스로 판단하게 된다.
f(10)
f([1, 2, 3])
foo(x::String, y::String) = println("x랑 y 둘 다 string이다!")
보이다시피, input 다음에 콜론을 2개 써서 x와 y의 type을 String으로 제한시켰다.
이제 foo는 String에만 작동하고 다른 input에는 작동하지 않는다.
foo("hello", "hi!")
foo(3, 4)
foo 함수가 integer(Int)에도 작동하게 하기 위해서, ::Int 를 사용해서 다음과 같이 foo를 정의할 수 있다.
foo(x::Int, y::Int) = println("x랑 y 둘 다 integer다!")
foo(3, 4)
이제 foo는 integer에도 작동한다. 그러나, 여전히 x와 y가 String일 때도 작동함을 아래를 통해 볼 수 있다.
foo("hello", "hi!")
이게 multiple dispatch의 핵심이다. 아래와 같이 선언했을 때,
foo(x::Int, y::Int) = println("My inputs x and y are both integers!")
아래 코드는 위의 코드를 덮어쓰기 하거나 대체하지 않는다.
foo(y::String, y::String)
대신에, foo라고 불리는 generic function에 method를 추가로 더했을 뿐이다.
generic function은 특정 연산에 대한 추상적인 개념이다.
예를 들어, generic function + 은 덧셈에 대한 개념이다.
method는 특정 argument type에 대한 generic function의 구현이다.
예를 들어, +에는 실수, 정수, 행렬 등등을 수용하는 여러 method가 있다.
methods를 이용해서 foo에 얼마나 많은 method가 있는지 볼 수 있다.
methods(foo)
참고 : 더하는 데는 얼마나 많은 방법이 있을까?
methods(+)
그래서 이제 foo는 integer와 string에 대해서 사용할 수 있다. 특정 input에 foo를 사용하면, Julia는 어떤 타입의 input인지 추론하고, 적절한 method를 빠르게 전달한다. 이것이 multiple dispatch다.
Multiple dispatch는 우리 코드를 일반적이고 빠르게 만든다. 우리 코드는 일반적이고 유연해질 수 있는데, 왜냐하면 특정 구현(specific implementations)으로 코드를 쓰는 것이 아니라 덧셈과 곱셈 같은 추상 연산(abstract operations)으로 코드를 쓸 수 있기 때문이다. 동시에, 빨리 실행되는데, 그 이유는 관련된 타입에 있어서 효율적인 method를 불러낼 수 있기 때문이다.
generic function을 불러낼 때, 어떤 method가 전달되는지 보기 위해서는, @which macro를 사용한다.
@which foo(3, 4)
더하기에도 @which를 사용해보자.
@which 3.0 + 3.0
함수 foo에 다른 method를 더 적용시킬 수 있다. Int나 Float64 등등 숫자로 생각되는 모든 object를 포함하는 추상적인 type인 number를 사용하는 method를 추가하자.
foo(x::Number, y::Number) = println("x랑 y 둘 다 number이다!")
This method for foo will work on, for example, floating point numbers:
foo(3.0, 4.0)
또한 이전에 한 적이 있는, any type을 input으로 받는 duck-typed method를 foo에 추가할 수 있다.
foo(x, y) = println("나는 any type을 input으로 넣어도 실행된다!")
지금까지 foo에 적용한 method를 감안할 때,이 method는 non-numbers를 foo의 input으로 넣을 때 마다 적용될 것이다.
v = rand(3)
foo(v, v)
연습문제
10.1¶
함수 foo를 확장하자. Bool type 하나를 input으로 넣을 때, "foo with one boolean!" 이라는 문구가 출력되는 method를 추가하자.
foo(x::Bool) = println("boolean 한 개로 실행됐다!")
methods(foo)
foo(true)
@which foo(true)
@assert foo(true) == "boolean 한 개로 실행됐다!"