본문 바로가기

코틀린

이펙티브 코틀린 - 음..?

반응형

이펙티브 코틀린 책을 읽기 시작했는데, 읽다보니 사소하게 틀린 부분들이 눈에 계속 걸린다.

 

책에 에라토스테네의 체 알고리즘을 이용해서 변수 스코프에 대한 설명을 하는 부분이 있는데,

변수 스코프가 잘못지정된 케이스를 설명하면서 아래 코드를 사용하였다.

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 }
    }
}

fun main() {
    println(primes.take(10).toList())
    //[2, 3, 5, 6, 7, 8, 9, 10, 11, 12]
}

그리고 왜 잘못된지에 대한 설명으로

"prime 이 2로 설정되어 있을 때 필터링된 4를 제외하면, drop만 동작하므로 그냥 연속된 숫자가 나와 버립니다."

라 적어놓았다. ( 원서도 똑같았다. )

 

책에서 크게 중요하지않은 코드에 대한 짧은 코멘트이지만 아무리 봐도 이해가 되지 않았다.

 

위의 while 문을 풀어보면 다음과 같다.

시작 전

numbers.first() 
=> 결과 2

1번째 반복

numbers.drop(1).filter { it % 2 != 0 }
       .first() 
=> 2가 drop & 3이 filter 를 통과
=> 결과 3

2번째 반복

numbers.drop(1).filter { it % 3 != 0 }
       .drop(1).filter { it % 3 != 0 }
       .first() 
=> 2가 drop & 3이 filter 에 걸림 & 4가 filter 를 통과
=> 4가 drop & 5가 filter 를 통과
=> 결과 5
       
3번째 반복

numbers.drop(1).filter { it % 5 != 0 }
       .drop(1).filter { it % 5 != 0 }
       .drop(1).filter { it % 5 != 0 }
       .first() 
=> 2가 drop & 3이 filter 를 통과
=> 3이 drop & 4가 filter 를 통과
=> 4가 drop & 5가 filter 에 걸림 & 6이 filter 를 통과
=> 결과 6

~~

 

1번째 반복을 보면 prime 이 2일때는 4에 대해서 filter 함수를 돌 생각도 없고, 애초에 4는 생성되지도 않았다.

4는 prime이 3인 2번째 반복에 가서야 생성되고 filter 함수통과 후 다음 drop 에 의해 사라진다.

 

제대로 된 설명은

"prime 이 3로 설정되었을때 drop 되어버린 4를 제외하면, filter는 큰의미를 가지지 못한 체 drop 만 동작하므로 그냥 연속된 숫자가 나와 버립니다." 정도의 설명이 정확할 것이다.

 

개발서적이라고 무조건 맞는건 아닌거 같다.

반응형