밑 dropWhile2 메소드 안에 구현 함수를 정의하고 여기에 tailrec을 다는건 잘 되는데
완전히 같은 로직을 메소드 dropWhile1처럼 메소드로 끌어올리고 tailrec 달면 tail call 없다고 워닝나옴
obj.func(args)랑 func(obj, args) (위의 예에서는 args를 캡쳐해 func(obj)지만) 사이에 꼬리재귀 최적화하는데 있어서 어떤 차이가 있는거임?
밑 dropWhile2 메소드 안에 구현 함수를 정의하고 여기에 tailrec을 다는건 잘 되는데
완전히 같은 로직을 메소드 dropWhile1처럼 메소드로 끌어올리고 tailrec 달면 tail call 없다고 워닝나옴
obj.func(args)랑 func(obj, args) (위의 예에서는 args를 캡쳐해 func(obj)지만) 사이에 꼬리재귀 최적화하는데 있어서 어떤 차이가 있는거임?
tail 의 dropWhile 함수 호출이 끝나지 않았으니까 tail을 스택에서 제거할 수 없잖아
반면에 2번째꺼는 한번 함수가 끝나면 스택프레임에 남아있는건 더 이상 사용하지 않으니 다 비울 수 있잖아
그런 논리면 2번째의 impl도 impl의 호출이 끝나기 전에 다시 안에서 impl을 호출하니까 스택을 못비우잖아 이런거를 루프로 변환해서 해결해주는게 꼬리재귀 최적화고
110.11/ drop1과 drop2의 비교가 아니라 drop1과 drop2 안의 impl을 비교해야지
스택을 왜 못비워? drop1 이 호출될 때 tail을 못비우는거랑, drop2 는 함수를 호출할 때 이미 스택을 비울 수 있는 상태인데?
=tailrec이 dropWhile2에 붙었는지 그 안 impl에 붙었는지 다시 보도록 넌 지금 글 주제 자체 이해를 못하고 있어
밑에 것도 tailrec이 drop2 자체에 붙으면 워닝남
110 유동아 꼬리재귀가 뭔지 그리고 이에대한 최적화를 어케하는지부터 공부좀 해
검색해보니 젯브레인 유트랙에 이에 대한 불평들 있네
https://youtrack.jetbrains.com/issue/KT-15341
open이 아닌 final 메소드에 대해서는 tailrec 적용못할 이유가 없는데 아무튼 안돼서 본문 아래 경우처럼 쓸데없는 보일러플레이트 작성해야한다고 함
상속구조 때문에 의도와 다른 메서드가 호출될까봐 막은거구나.. 그런데 오버라이딩이 어차피 안되는 경우까지 필요이상으로 막아버린거고..
지금 final이라고 나중에도 final일지 모른다는 극보수 컨셉 ㄷㄷ