Hello

함수형 프로그래밍, 객체지향프로그래밍, 람다식, 일급 객체, 고차 함수, 함수 참조

by 볼빵빵오춘기

Kotlin은 객체 지향 프로그래밍(OOP)함수형 프로그래밍(FP)동시에 지원하는 다중 패러다임 언어.

 

함수형 프로그래밍(Functional Programming, FP)

  • 순수 함수(Pure Function, 값이 예측이 가능한 함수를 의미)를 사용하여 부작용 없는 코드 작성을 지향한다.
  • 함수 자체를 값처럼 사용할 수 있다.(=일급 객체)
  • 함수는 변수에 할당되거나, 다른 함수의 인자로 전달되거나, 반환값으로 사용될 수 있다.

 

핵심 개념

람다식

  • 이름이 없는 익명 함수이다.
  • {x, y -> x + y} 형태로 사용한다.

 

일급 객체

  • 함수를 값처럼 다룰 수 있다.
  • 변수에 할당하거나 인자로 전달 가능하다.

 

고차 함수

  • 함수를 인자로 받거나 함수를 반환하는 함수이다.

 

함수 참조(::)

  • 기존 함수 이름을 그대로 전달할 수 있도록 한다. ex) ::plus

 

예제 코드

일반 함수와 고차 함수

fun sum(x: Int, y: Int): Int = x + y
fun mul(x: Int, y: Int): Int = x * y

fun main() {
    val result1 = sum(2, 5)
    val result2 = mul(sum(10, 5), 5) // 고차 함수

    println("result1: $result1, result2: $result2") // 7, 75
}
// sum(10, 5)의 결과가 15, 이 값을 다시 mul(15, 5)로 전달 → 고차 함수 사용의 예.

 

반환값으로 함수 사용하기

fun add(x: Int, y: Int): Int = remaind(x, y)
fun remaind(x: Int, y: Int): Int = x % y

fun funcFunc(): Int = add(2, 5)

fun main() {
    println("결과: ${funcFunc()}") // 2 % 5 = 2
}
// 함수가 또 다른 함수를 반환하거나 호출하는 구조 → 고차 함수

 

람다식 사용하기

fun main() {
    val multi = { x: Int, y: Int -> x * y }
    println("결과: ${multi(100, 200)}") // 20000
}
// multi는 함수처럼 사용할 수 있는 람다 변수

 

람다식 생략 가능한 부분

val result: (Int, Int) -> Int = { x, y -> x * y }
val greet = { println("Hi~") }
val square = { x: Int -> x * x }

greet()
println("제곱: ${square(5)}")
// 람다는 타입 추론이 가능할 때 일부 생략 가능. 단, 모든 생략은 불가

 

람다식을 매개변수로 받는 고차 함수

fun hihtOrder(sum: (Int, Int) -> Int, a: Int, b: Int): Int {
    return sum(a, b) + a + b
}

fun main() {
    val result = hihtOrder({ x, y -> x + y }, 10, 20)
    println("result: $result") // 30 + 10 + 20 = 60
}

 

인자/반환값 없는 람다식

val out = { println("대한민국 만세!") }
val new = out

fun main() {
    out() // 대한민국 만세!
    new() // 대한민국 만세!
}
// 람다식은 인자나 반환값이 없어도 선언 가능. 이때 Unit 리턴 타입을 가짐.

 

값에 의한 호출(Call by Value)

fun callByValue(b: Boolean): Boolean {
    println("callByValue()")
    return b
}

val lambda: () -> Boolean = {
    println("lambda() 호출됨")
    true
}

fun main() {
    val result = callByValue(lambda()) // lambda 먼저 실행
    println("result: $result")
}

 

이름에 의한 호출(Call by Name)

fun callByName(b: () -> Boolean): Boolean {
    println("callByName()")
    return b()
}

val otherLambda: () -> Boolean = {
    println("otherLambda 호출됨")
    true
}

fun main() {
    val result = callByName(otherLambda)
    println("result: $result")
}

 

함수 참조(::) 사용하기

fun plus(x: Int, y: Int): Int = x + y
fun text(x: String, y: String): String = "Hello! $x $y"

fun hello(body: (String, String) -> String) {
    println(body("Jinny1", "Jun1"))
}

fun funcParam(x: Int, y: Int, z: (Int, Int) -> Int): Int {
    return z(x, y)
}

fun main() {
    val result1 = funcParam(3, 2, { x, y -> x + y })
    val result2 = funcParam(3, 2, ::plus)
    println("result1: $result1") // 5
    println("result2: $result2") // 5

    hello(::text) // Hello! Jinny1 Jun1
}

 

블로그의 정보

Hello 춘기's world

볼빵빵오춘기

활동하기