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)를 사용하는 것이 좋습니다.
'Julia > Julia 강좌' 카테고리의 다른 글
Julia 강좌 6 - 변수 유효 범위( Variable Scope ) : 전역(global), 로컬(local) (4) | 2023.12.22 |
---|---|
Julia 강좌 1 - 변수와 데이터 타입 (1) | 2023.12.15 |
Julia 강좌 5 - 브로드캐스팅(broadcasting) (0) | 2023.12.11 |
Julia 강좌 3 - 배열, 튜플, 딕셔너리 (0) | 2023.12.10 |
Julia 강좌 4 - 제어문 if ... else, for, break, continue, while, enumerate (1) | 2023.12.07 |
시간날때마다 틈틈이 이것저것 해보며 블로그에 글을 남깁니다.
블로그의 문서는 종종 최신 버전으로 업데이트됩니다.
여유 시간이 날때 진행하는 거라 언제 진행될지는 알 수 없습니다.
영화,책, 생각등을 올리는 블로그도 운영하고 있습니다.
https://freewriting2024.tistory.com
제가 쓴 책도 한번 검토해보세요 ^^
그렇게 천천히 걸으면서도 그렇게 빨리 앞으로 나갈 수 있다는 건.
포스팅이 좋았다면 "좋아요❤️" 또는 "구독👍🏻" 해주세요!