Post

지연 평가 Sequence의 원리

1
2
3
4
5
6
7
8
9
10
11
12
fun main() {
    val primes: Sequence<Int> = sequence {
        var numbers = generateSequence(2) { it + 1 } // <- 최초 1 번만 실행
        while (true) {  // <- 이후 item 요청에 대해서는 계속 이 안에서 돈다.
            val prime = numbers.first()
            yield(prime)
            numbers = numbers.drop(1).filter { it % prime != 0 }
        }
    }
    println(primes.take(10).toList())
}

  • sequence는 filter(Predicate)를 가지고 있음!
  • 등록한 모든 Predicate 들을 기억해 두었다가 다음번 item 반환 요청이 오면 filter들을 모두 적용해서 결과를 산출한다.

  • $prime=2인 predicate는 2의 배수 탈락 filter
  • $prime=3인 predicate는 3의 배수 탈락 filter

mutable 변수의 Capture로 인한 문제

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
fun main() {
    val primes: Sequence<Int> = sequence {
        var numbers = generateSequence(2) { it + 1 }
        var prime: Int
        while (true) {
            prime = numbers.first()
            yield(prime)
            numbers = numbers.drop(1).filter { it % prime != 0 }
            /* 위 람다에서 var prime을 capture하여 참조하므로 
            capture 시점의 prime 값이 아니라 실행 시점의 prime이 적용된다 */
        }
    }
    println(primes.take(10).toList())
}

  • mutable 변수의 단점이란, 해당 변수 사용하고 있는 로직 변경 어려움, 추적 어려움, 이 처럼 예상치 못한 문제 발생 할 수 있음.
This post is licensed under CC BY 4.0 by the author.