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로 인한 문제

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 변수의 단점이란, 해당 변수 사용하고 있는 로직 변경 어려움, 추적 어려움, 이 처럼 예상치 못한 문제 발생 할 수 있음.