이 시리즈는 "스칼라로 배우는 함수형 프로그래밍"을 TypeScript로 실습한 내용을 정리하고 있습니다.
Stream은 List와 비슷하지만 자료 생성자가 엄격한 값이 아닌 명시적인 thunk를 받는다. 값을 지연평가하는 능력 덕분에 유용한 쓰임이 생긴다.
TypeScript는 Scala와 다르게 lazy 키워드등이 없기 때문에 보조적인 함수를 만들었다. 이 구현에 대해서는 여기를 참고했다.
https://github.com/JsonKim/fpinscala-with-typescript/commit/83a584027f1effbf67ffd4eee97102ea485cb8bb
관심사의 분리(separation of concerns)는 함수형 프로그래밍의 주된 주제 중 하나이다. 계산의 서술(description)을 계산의 실제 실행과 분리하는 것이 권장된다.
Stream은 나태성을 통해서 표현식의 서술을 그 표현식의 평가와 분리 할 수 있다. 필요한 것 보다 '더 큰' 표현식을 서술하되 그 표현식의 일부만 평가할 수 있는 능력이 갖춰진다.
https://github.com/JsonKim/fpinscala-with-typescript/commit/ec4fe5a4750c7aa047685fd9ff2316e1459d6689
점진전(incremental) 구현들은 결과 전체를 생성하지 않고 다른 어떤 계산이 결과 Stream의 요소를 참조하는 시점이 되어서야 그 Stream을 생성하는 계산이 실제로 진행된다. 이러한 성질 덕분에 중간 결과를 완전히 인스턴스화 하지 않고도 함수들을 연이어 호출할 수 있다.
이는 마치 특수 목적의 루프를 이용해서 변환 논리를 엇갈려 수행하는(interleave)것과 동일하다. 때문에 Stream을 map, filter같은 고차 함수를 이용해서 논리를 결합할 수 있는 '일급 루프(first-class loop)'라고 부르기도 한다.
List에서는 일찍 탈출 할 수 없어 필요 이상으로 처리를 해야했던 구현들도 Stream에서는 laziness 특성으로 그런 걱정 없이 기존의 조합기(combinator)들을 독창적인 방식으로 재사용하기 쉬워진다.
또한 스트림을 변환할 때 현재 요소를 저장하고 변환하는데 필요한 만큼의 메모리만 있으면 되기 때문에 프로그램이 요구하는 전체적인 메모리 사용량을 줄일 수 있다.