Do it! 코틀린 프로그래밍 03 함수와 함수형 프로그래밍

03 함수와 함수형 프로그래밍

01 함수 선언하고 호출하기


반환하지 않는다 = Unit

함수 매개변수는 val로 선언되기 때문에 바꿀 수 없다!

default 매개변수 지원!

함수 오버로딩이 필요가 없어짐!

fun sum(a: Int, b = 0) { ... }

named 인자 지원!

sum(a = 1, b = 2)

가변 인자

fun foo(vararg numbers: Int) { ... }

02 함수형 프로그래밍


함수형 프로그래밍이란?

  • 순수함수를 작성해서 프로그램의 사이드이펙트를 줄이는 기법
  • 람다식과 고차함수를 사용한다.

순수 함수의 조건

  • 같은 인자에 대해 항상 같은 값을 반환한다.
  • 함수 외부의 어떤 상태도 바꾸지 않는다.

함수형 프로그래밍에서 함수는 일급함수다.

  • 일급 객체는 함수의 인자로 전달할 수 있다.
  • 일급 객체는 함수의 반환값에 사용할 수 있다.
  • 일급 객체는 변수에 담을 수 있다.

고차함수란?

  • 다른 함수를 인자로 사용할 수 있다.
  • 함수를 결과값으로 반환할 수 있다.

여기까지 정리해보기

함수형 프로그래밍순수함수를 사용해 사이드이펙트를 최소화 하는 기법이고, 순수함수를 사용하려면 일급함수고차함수 개념을 지원해야 한다. 이 개념을 사용하기 쉽게 해주는 요소 중 하나가 람다식이다.

03 고차 함수와 람다식


람다식의 선언과 정의

val multi: (Int, Int) -> Int = {x: Int, y: Int -> x * y}

함수를 람다식처럼 인자로 넘기려면 ::을 붙인다.

fun sum(a: Int, b: Int) = a + b

...

foo(2, 3, ::sum)
// 또는 람다로 감싸도 됨. foo(2, 3) {a, b -> sum(a, b)}

람다식에서 사용하지 않는 매겨변수는 _로 이름짓기

람다식에서는 return을 명시하지 않아도 함수바디의 마지막 표현식의 결과가 반환된다.

람다인자가 끝에 있을 때 소괄호 뒤에 따로 빼면 생기는 장점

  • 마지막 인자가 람다식이면 소괄호 밖으로 뺄 수 있는데, 그 장점은 람다식이 길 때 닫는 소괄호를 신경쓰지 않아도 되는 것!
  • 실제로는 람다를 인자로 넘기는 것이지만 하위코드를 블록으로 감싸는 표현으로 바뀜!

04 고차 함수와 람다식의 사례 알아보기


콜백 함수로 사용

05 코틀린의 다양한 함수 알아보기


익명함수 vs 람다식

val multiAnony = func(x Int, y: Int) = x * y
val multiLambda = {x: Int, y: Int -> x * y}
  • 람다식은 return이나 break, continue 같은 제어문을 사용하기가 어렵기 때문이다.
  • 람다식에서 return을 사용하려면 라벨 표기법을 사용해야 함.

인라인 함수!

  • 코드 자체가 복사되어 들어가기 때문에 스택메모리가 사용되지 않아 메모리 관리에 효율적이다.
  • 람다식을 매개변수로 가지고 있는 함수에서만 동작한다

주의

매개변수인 람다식도 같이 복사되기 때문에 람다식이 긴 경우엔 성능을 위해 람다식 매개변수 앞에 noinline 키워드를 붙여준다.

인라인 함수에서의 비지역 반환

인라인 함수의 매개변수로 쓰인 람다식에서 return을 사용하면, 인라인 함수와 매개변수 람다까지 복사해서 코드로 들어가기 때문에 인라인 함수를 호출한 caller 함수까지 종료되고 반환된다. 이걸 비지역 반환이라고 부른다.

확장함수 지원!

fun 확장대상.함수이름(매개변수, ...): 반환형 {
	... 
	return 값
}

주의: 확장함수보다 멤버메소드가 호출우선순위에 있다.

중위 함수 지원!

  • 멤버 메소드 또는 확장 함수여야 한다.

  • 하나의 매개변수만 가져야 한다.

  • infix 키워드를 사용해서 정의한다.

    infix fun Int.multiply(x: Int): Int = this * x

    print(3 multiply 4) // 12

꼬리재귀함수로 구현해서 스택오버플로우를 예방하자!

  • 인자로 들어갈 때 이미 계산되도록 구현하기
  • 함수 선언부에 tailrec 키워드를 달아주기

06 함수와 변수의 범위


지역 함수 지원!