SICP 연습문제 2.23 친절한 풀이
문제
for-each 프로시저는, map처럼 프로시저와 리스트를 하나씩 인자로 받지만, 결과 값으로 리스트를 내놓는 게 아니라, 리스트의 원소마다 (왼쪽에서 오른쪽으로) 프로시저를 적용한 결과만 내놓는다. 원소마다 프로시저를 적용했을 때 얻은 값은 아예 쓰지 않는다. 그러므로 리스트의 원소를 차례대로 화면에 찍는 등 똑같은 명령을 처리해야 하는 프로시저를 짜는 데 쓴다. 아래는 그 보기다.
(for-each (lambda (x) (newline) (display x)) |
(위에 나타내진 않았지만) for-each 프로시저의 결과 값은 (참처럼) 뭐가 되어도 상관없다. 그러니, for-each 프로시저를 정의해 보라.
문제로 부터 얻은 것
반환값이 없는 함수를 구현할 때 사용할 수 있는 여러가지 테크닉을 배울 수 있었습니다.
문제풀이
스킴 커뮤니티에 가보시면 정말 다양한 솔루션들이 있습니다. 좋아보이는 것 몇가지를 소개해 드리려고 합니다.
우선 제가 문제를 읽자마자 무지성으로 만들어본 코드입니다. if문의 else절에는 하나의 프로시저만 실행 가능하기 때문에, 새로운 프로시저 proc-and-next를 정의해서 proc를 실행하고 다음으로 실행할 리스트를 넘겨줬습니다.
(define (for-each proc items) |
다음으로 살펴볼 프로시저는 and를 이용한 프로시저입니다. and를 이용하면, 하나의 프로시저밖에 들어갈 수 없는 if문의 else절에 여러 프로시저를 넣을 수 있다는 것을 알았습니다. for-each는 애초에 반환값이 없기 때문에 이런 구현이 가능합니다.
(define (for-each proc items) |
다음으로 살펴볼 프로시저는 iter를 사용한 프로시저입니다. 특이한 점은 iter의 인자인 evaluate는 기존의 iter와는 달리 값을 전달하기 위한 목적이 아니라 프로시저를 실행하는 목적으로 쓰인다는 것입니다. 이 또한 반환값이 없기 때문에 구현할 수 있는 것입니다.
(define (for-each proc items) |
다음으로 살펴볼 프로시저는 연습문제 2.21에서 사용한 map 프로시저를 이용한 프로시저입니다. map과 for-each의 차이점은 단순히 반환값이 있냐 없냐이기 때문에 이런식으로 구현이 가능한 것입니다. 천재적입니다.
(define (for-each proc items) |
여러 천재들의 정답을 보자 하니 제 코드가 초라해지는 하루였습니다. 읽어주셔서 감사합니다.