반응형

Julia의 함수에 대해 다룹니다.

 

함수, void function,  Optional positional arguments, Keyword arguments



2023. 11. 16 최초작성




다음 사이트를 참고하고 ChatGPT의 도움을 받았습니다. 

https://techytok.com/lesson-functions/ 



Julia 개발 환경 구축은 다음 포스트를 참고하세요. 

 

Visual Studio Code 사용한 Julia 개발 환경만들기(Windows / Ubuntu / Macbook M1)

https://webnautes.tistory.com/2216 



Julia 강좌를 진행하고 있습니다.

 

Julia 강좌 1 - 변수와 데이터 타입

https://webnautes.tistory.com/2218 

 

Julia 강좌 2 - 함수, void function,  Optional positional arguments, Keyword arguments

https://webnautes.tistory.com/2220 

 

Julia 강좌 3 - 배열, 튜플, 딕셔너리

https://webnautes.tistory.com/2229 

 

Julia 강좌 4 - 제어문 if ... else, for, break, continue, while, enumerate

https://webnautes.tistory.com/2235 

 

Julia 강좌 5 - 브로드캐스팅(broadcasting)

https://webnautes.tistory.com/2240

 

Julia 강좌 6 - 변수 유효 범위( Variable Scope ) : 전역(global), 로컬(local)

https://webnautes.tistory.com/2247

 

Julia 강좌 7 - 모듈(module)

https://webnautes.tistory.com/2253 

 

Julia 강좌 8 - 타입(type)

https://webnautes.tistory.com/2260

 

Julia 강좌 9 - 패키지(package)

https://webnautes.tistory.com/2268 

함수(function)

 

함수는 블랙박스처럼 입력을 넣으면 출력을 내놓은 상자처럼 생각할 수 있습니다. 상자의 내부는 공개일 수도 있고 비공개일 수도 있습니다.

 

줄리아에서 함수는 매우 중심적인 개념으로 많은 부분이 함수를 통해 표현됩니다.  몇가지 예를 들어보겠습니다.

 

수학적 연산자 (+, -, *, /)는 내부적으로는 함수입니다.   좀 더 구체적으로 설명하면 두 숫자를 더하는 연산인 a + b는 실제로 +(a, b)라는 함수 호출로 볼 수 있습니다. + 연산자가 두 개의 인자 사이에 위치하기 때문에 중위 형식(infix form)으로 작성된 함수입니다. 이것은 줄리아가 함수를 매우 중심적인 개념으로 취급하며, 프로그래밍의 많은 부분을 함수를 통해 표현한다는 것을 나타냅니다.

 

함수를 변수에 대입한 후, 변수를 함수처럼 호출하고 결과값을 받을 수 있습니다. 아래 코드에서는 이런 식으로 동작하는구나만 알아두세요.

# 두 숫자를 더하는 간단한 함수를 정의합니다.
add(x, y) = x + y

# 'add' 함수를 변수 my_function에 대입합니다.
my_function = add

# 변수 my_function을 사용하여 두 숫자를 더할 수 있습니다.
result = my_function(10, 5# add(10, 5)와 똑같이 동작합니다.

println(result)  # 15가 출력됩니다. 



줄리아에서 함수는 다음처럼 정의하고 호출합니다.

 

# function 키워드 다음에 함수 이름을 적고 괄호안에 전달받은 인자의 이름을 적습니다.
function plus_two(x)


    # 들여쓰기를 하지 않아도 코드가 동작하지만 가독성을 위해 해주는 것이 좋습니다. 보통 빈칸 4개로 하며 탭은 사용하지 않는 것이 좋습니다.
    x = x + 2

    # return 키워드를 사용하여 함수에서 반환되는 변수나 값을 지정합니다.
    return x

# 함수의 끝에는 end 키워드를 사용해야 합니다.
end


# 함수이름 다음에 오는 괄호안에 함수에 전달할 인자를 적어주고 함수에서 반환받은 값을 저장할 변수를 지정해줍니다.
ret = plus_two(1)


println(ret)

 



함수를 한줄로 정의할 수도 있습니다. 한 줄 함수(one-liner function)라고 부릅니다.

 

plus_two(x) = x + 2

ret = plus_two(1)
println(ret)



다음처럼 Python의 람다(lambda) 함수와 유사한 익명 함수(anonymous functions)로 정의할 수도 있습니다. 하지만 아주 간단한 경우가 아니라면 익명 함수를 사용하지 않는 것이 좋습니다.

 

plus_two = x -> x+2

ret = plus_two(1)
println(ret)



return 문을 생략하고 변수나 값만 적을 수 있습니다.

 

function plus_two(x)

    x = x + 2

    # return x
    x
end



ret = plus_two(1)

println(ret)




void 함수(void function)

 

void 함수는 값을 반환하지 않는 함수입니다.  say_hi 함수는 값을 반환하지 않기 때문에 return 문을 안적어도 됩니다. 

 

function say_hi()
    println("Hi")
end

say_hi()



다른 언어에서처럼  return 문만 적어줄 수도 있습니다. 

 

function say_hi()
    println("Hi")

    return
end

say_hi()



줄리아에서는 함수에서 아무것도 반환하지 않는 경우 관습적으로 nothing을 리턴합니다.  nothing은 Nothing 데이터 타입의 싱글톤 객체입니다.  값을 리턴할때처럼 함수끝에 return 문 없이 nothing만 적어도 되고 return nothing이라고 적어도 됩니다. 

 

return nothing을 사용하는 경우

 

function say_hi()
    println("Hi")
 
    return nothing
end

say_hi()



nothing을 사용하는 경우

 

function say_hi()
    println("Hi")
 
    nothing
end

say_hi()




선택적 위치 아규먼트(Optional positional arguments)

 

선택적 위치 아규먼트는 함수를 호출할 때 생략할 수 있으며, 생략했다면 함수 정의에서 지정된 기본값을 사용합니다.

아규먼트에 기본값이 없는 경우는 항상 값을 지정해야 하는  필수 아규먼트입니다.

 

예를 들어 지구에서 측정한 '몸무게(kg)'를 다른 행성에서 측정한 몸무게로 변환하는 함수를 작성해 보겠습니다.



다음 예제에서 파라미터 g의 값을 지정하지 않고 파라미터 weightOnEarth의 값으로 60을 지정하면 파라미터 g는 기본값으로 주어진 9.81을 사용하게 됩니다. 

 

function myWeight(weightOnEarth, g=9.81)

    # $변수명으로 변수의 값을 출력하도록 할 수 있습니다.
    println("g = $g")

    return weightOnEarth*g/9.81
end


# 파라미터 g를 위한 값을 추가하지 않았습니다. 
ret = myWeight(60)
println("weight = $ret ")



실행결과 지구에서의 중력 가속도 9.81과 몸무게 60이 출력됩니다.

 



파리미터 g의 값으로 화성에서의 중력 가속도 3.72를 입력하면 기본값인 9.81 대신에 사용됩니다. 

https://en.wikipedia.org/wiki/Gravity_of_Mars 

 

function myWeight(weightOnEarth, g=9.81)

    println("g = $g")

    return weightOnEarth*g/9.81
end

# 파라미터 g를 위한 값으로 3.72를 추가합니다.
ret = myWeight(60, 3.72)

formatted_ret = round(ret, digits=2) # 소수점 두번째 자리까지 반올림합니다.
println("weight = $formatted_ret ")



실행결과 화성에서의 중력 가속도와 몸무게가 출력됩니다.



선택적 위치 아규먼트는 사용시 순서를 지켜야 합니다.  파라미터 g의 이름을 지정하더라도 weightOnEarth 아규먼트 앞으로 위치를 옮길 수 없습니다. 

 

파라미터 g 이름을 지정해서 위치를 변경해보면 에러가 발생합니다.

 

function myWeight(weightOnEarth, g=9.81)

    println("g = $g")

    return weightOnEarth*g/9.81
end

# 파라미터 g 이름을 지정해서 위치를 변경해봅니다.
ret = myWeight(g=3.72, 60)

formatted_ret = round(ret, digits=2)
println("weight = $formatted_ret ")





고정된 위치가 없는 아규먼트를 사용하라면 키워드 아규먼트를 사용해야 합니다. 



키워드 아규먼트(Keyword arguments)

선택적 위치 아규먼트의 갯수가 많아진다면 순서를 기억하여 사용하는 것이 번거로울 수 있습니다.  이런 경우에  키워드 아규먼트가 유용합니다.

 

키워드 아규먼트는 함수를 호출할 때 아규먼트의 이름을 명시적으로 지정해야 합니다. 키워드 아규먼트도 기본값을 가질 수 있으며, 이 경우 호출 시에 그 값을 생략할 수 있습니다. 하지만 기본값이 없는 키워드 아규먼트는 함수 호출 시 반드시 값을 지정해야 합니다.

 

아래 예제코드에서 a와 b는 선택적 위치 아규먼트이고, c와 d는 키워드 아규먼트입니다. 세미콜론으로 선택적 위치 아규먼트와 키워드 아규먼트를  구분합니다. 

 

function my_long_function(a, b=2; c, d=3)
    return a + b + c + d
end


# 선택적 위치 아규먼트 b와 키워드 아규먼트 d는 기본값이 있기 때문에 생략이 가능합니다.
ret = my_long_function(1, c=3)
println(ret)

# 선택적 위치 아규먼트 a와 b는 순서가 정해져 있어서 a가 1, b가 2를 값으로 갖습니다. 
ret = my_long_function(1, 2, c=3)
println(ret)


# 키워드 아규먼트는 위치를 바꿀 수 있습니다. 키워드 아규먼트 d의 위치를 변경해봅니다.
ret = my_long_function(1, 2, c=3, d=5)
println(ret)

ret = my_long_function(1, 2, d=5, c=3)
println(ret)

ret = my_long_function(1, d=5, 2, c=3)
println(ret)

ret = my_long_function(d=5, 1, 2, c=3)
println(ret)



기본값이 있는 키워드 아규먼트 d는 생략해도 되지만 기본값이 없는 키워드 아규먼트 c는 생략하면 에러가 발생합니다.

 

function my_long_function(a, b=2; c, d=3)
    return a + b + c + d
end

# 기본값이 없는 키워드 아규먼트 c를 생략해봅니다.
ret = my_long_function(d=5, 1, 2)
println(ret)

 





Performance tip

 

고성능이 필요한 경우(예: 여러 번 호출해야 하는 함수를 작성할 때) 위치 인수(positional arguments)를 사용하는 것이 좋습니다.




반응형

문제 발생시 지나치지 마시고 댓글 남겨주시면 가능한 빨리 답장드립니다.

도움이 되셨다면 토스아이디로 후원해주세요.
https://toss.me/momo2024


제가 쓴 책도 한번 검토해보세요 ^^

+ Recent posts