[Julia] 06. Functions

햄도·2020년 12월 3일
0

Julia tutorial

목록 보기
4/8

Functions

  1. How to declare a function
  2. Duck-typing in Julia
  3. Mutating vs. non-mutating functions
  4. Some higher order functions

How to declare a function

기본적인 함수 선언

function sayhi(name)
    println("Hi $name, it's great to see you!")
end

sayhi (generic function with 1 method)

sayhi("hamdoe")

Hi hamdoe, it's great to see you!

한 줄로 함수를 선언하는것도 가능하다.

sayhi2(name) = println("Hi $name, it's great to see you!")

sayhi2 (generic function with 1 method)

sayhi2("hamdoe")

Hi hamdoe, it's great to see you!

->를 이용해 익명함수를 선언할 수 있다.

sayhi3 = name -> println("Hi $name, it's great to see you!")

#1 (generic function with 1 method)

sayhi3("hamdoe")

Hi hamdoe, it's great to see you!

Duck-typing in Julia

python을 접해봤다면 익숙할 개념인 Duck-typing은 객체의 변수, 메소드의 집합이 객체의 타입을 결정하는 것이다. julia는 duck-typing을 지원하고, julia의 함수들은 input에 따라 적절한 동작을 한다.

sayhi(348237)

Hi 348237, it's great to see you!

A = rand(3,3)

3×3 Array{Float64,2}:

0.572848 0.444698 0.223024

0.797806 0.941378 0.261529

0.852831 0.53351 0.832097

function f(x)
    x^2
end

f (generic function with 1 method)

f(A)

3×3 Array{Float64,2}:

0.87314 0.792359 0.429638

1.4311 1.3805> 0.641745

1.62382 1.32542 1.02212

f("말이 돼 이게?")

"말이 돼 이게?말이 돼 이게?"

벡터에 대한 ^2 연산은 정의되어있지 않기때문에 작동하지 않는다.

v = rand(3)

3-element Array{Float64,1}:

0.2118291138477053

0.3660039136837909

0.17135122483937515

f(v)

MethodError: no method matching ^(::Array{Float64,1}, ::Int64)

Closest candidates are:

^(!Matched::BigFloat, ::Union{Int16, Int32, Int64, Int8}) at mpfr.jl:587

^(!Matched::BigFloat, ::Integer) at mpfr.jl:599

^(!Matched::Regex, ::Integer) at regex.jl:729

...



Stacktrace:

[1] macro expansion at ./none:0 [inlined]

[2] literal_pow at ./none:0 [inlined]

[3] f(::Array{Float64,1}) at ./In[12]:2

[4] top-level scope at In[17]:1

Mutating vs. non-mutating functions

관습적으로, !가 붙는 함수들은 인자의 내용을 바꾸고, 아닌 함수들은 인자의 내용을 바꾸지 않는다.

v = [3, 5, 2]

3-element Array{Int64,1}:

3

5

2

sort(v)

3-element Array{Int64,1}:

2

3

5

v

3-element Array{Int64,1}:

3

5

2

v2 = sort!(v)

3-element Array{Int64,1}:

2

3

5

v

3-element Array{Int64,1}:

2

3

5

v2

3-element Array{Int64,1}:

2

3

5

v2[1] = 2313

2313

v2

3-element Array{Int64,1}:

2313

3

5

v

3-element Array{Int64,1}:

2313

3

5

Some higher order functions

map

  • function을 input으로 받는 higher-order function 중 하나
  • input으로 function을 같이 들어온 자료구조의 모든 원소에 적용한다.
map(f, [1,2,3])

3-element Array{Int64,1}:

1

4

9

익명함수로도 같은 일을 할 수 있다.

map(x -> x^3, [1,2,3])

3-element Array{Int64,1}:

1

8

27

broadcast

  • 다른 higher-order function
  • map의 generalization, 더 많은 일을 할 수 있다.
broadcast(f, [1,2,3])

3-element Array{Int64,1}:

1

4

9

broadcast의 syntactic sugar도 존재한다. '.'을 이용해 broadcast를 축약해서 나타낼 수 있다.

# syntactic sugar
f.([1,2,3])

3-element Array{Int64,1}:

1

4

9

A = [i + 3*j for j in 0:2, i in 1:3]

3×3 Array{Int64,2}:

1 2 3

4 5 6

7 8 9

f(A)는 행렬 자체를 제곱하고, f.(A)는 행렬의 각 원소를 제곱한다.

f(A)

3×3 Array{Int64,2}:

30 36 42

66 81 96

102 126 150

B = f.(A)

3×3 Array{Int64,2}:

1 4 9

16 25 36

49 64 81

아래와 같은 표기가 더 직관적이라고 하는데 나는 아직 생소하다.. 누가 이렇게 코딩해놓으면 열받을것같다.

A .+ 2 .* f.(A) ./ A

3×3 Array{Float64,2}:

3.0 6.0 9.0

12.0 15.0 18.0

21.0 24.0 27.0

Exercises

# 6.1
function add_one(x)
> x + 1
end

add_one (generic function with 1 method)

add_one(11)

12

# 6.2
A = [i + j for j in 0:2, i in 1:3]
A1 = A .+ 1

3×3 Array{Int64,2}:

2 3 4

3 4 5

4 5 6

A1

3×3 Array{Float64,2}:

1.55776 1.86469 1.05732

1.69706 1.19733 1.23513

1.45602 1.90503 1.97056

# 6.3
A2 = A1 .+ 1

3×3 Array{Int64,2}:

3 4 5

4 5 6

5 6 7

profile
developer hamdoe

0개의 댓글