sicp.io
4.2.2 · 지연 평가 인터프리터

메모이즈된 thunk는 요구된 작업을 최대 한 번 수행한다.

compound procedure의 피연산자는 지연하고 primitive 피연산자와 술어는 강제하며 첫 actual-value 요청 뒤 thunk를 evaluated-thunk로 바꿉니다.

생각해 볼 질문

평가기는 인자 작업을 미루면서도 같은 식을 여러 번 참조할 때 되풀이 계산하지 않도록 어떻게 만들까요?

  • 피연산자 식과 호출 환경을 함께 지연하기
  • 적용 방법을 결정하기 전에 연산자 강제하기
  • primitive 인자와 if 술어를 실제 값으로 강제하기
  • compound procedure에는 지연된 인자 전달하기
  • thunk 태그와 payload를 바꾸어 결과 메모이즈하기
  • 사용하지 않은 식과 되풀이한 식과 선택되지 않은 식 구분하기

apply-lazy는 호스트 primitive와 표현된 compound procedure를 구분합니다. primitive는 실제 인자 값이 필요하므로 host apply 전에 피연산자를 강제합니다. compound procedure는 원래 피연산자 식과 호출 환경을 담은 thunk 레코드를 받습니다. 변수 조회는 그 레코드를 반환하고 actual-value가 강제 여부를 결정합니다.

force-it은 새 thunk를 한 번 평가한 뒤 같은 가변 레코드를 evaluated-thunk로 바꾸고 결과를 저장하며 식과 환경을 버립니다. 사용하지 않은 인자는 probe를 실행하지 않고 x를 두 번 써도 probe는 한 번뿐입니다. 선택되지 않은 if 갈래도 평가되지 않습니다. 이 수업의 call-by-need 모형은 나열한 형식의 지연 평가 과정을 직접 실행합니다.

SICP 코드UTF-8 7,892 / 1,048,576바이트
예제
결과
출력
진단
실행 추적0 / 0 개 이벤트
    실행은 브라우저 안에서 이루어지며 프로그램 결과와 실행 추적을 보여줍니다.
    예상 결과

    평가기는 ((unused 1 0) (duplicated 20 1) (branch safe 0))을 반환합니다.

    실행 추적에서 볼 점

    compound 적용이 list-of-delayed-args로 들어가는 지점을 따라가고 첫 조회가 thunk를 force-it으로 보내는 곳을 찾으세요. 레코드가 evaluated-thunk로 바뀌고 둘째 조회가 저장한 값을 돌려주는지 확인하세요. if에서는 술어와 선택한 consequent만 평가되는지 보세요.

    직접 해보기

    프로그램을 수정하고 결과를 비교해 보세요.

    ((lambda (x) (+ x (+ x x))) (probe 4))를 추가하고 값과 probe 횟수를 예상하세요. 그 다음 force-it의 thunk 변경을 제거하고 비교하세요.

    힌트 보기

    메모이즈하면 x 조회 횟수와 관계없이 probe는 한 번입니다. 변경하지 않으면 매 조회가 저장한 식을 다시 평가합니다.

    이 수업 완료하기

    이 장의 총 23개 수업 중 0개 완료0%