(Lispex)sicp.io
1.12 · 값으로 반환되는 프로시저

프로시저는 다음 프로시저를 만들어 돌려줄 수 있다.

합성과 반복과 평균 감쇠는 동작을 데이터처럼 다룹니다. 한 프로시저가 다른 프로시저를 받아 나중에 이름 붙이고 전달하고 적용할 수 있는 새 변환을 반환합니다.

생각해 볼 질문

프로시저 호출의 결과가 또 다른 프로시저라면 어떤 새로운 구성이 가능해질까요?

  • lambda 식을 다른 프로시저가 반환하는 프로시저 값으로 읽기
  • 변환을 만드는 시점과 그 변환을 적용하는 시점 구분하기
  • 소스에서 적용 순서가 드러나도록 프로시저 합성하기
  • 동작 본문을 복사하지 않고 반복되는 변환 만들기
  • 평균 감쇠를 프로시저를 만드는 변환으로 이해하기

compose는 프로시저 값 두 개를 받고 새로운 프로시저를 반환합니다. compose를 호출하는 순간에는 아직 어떤 수도 제곱하거나 증가시키지 않습니다. f와 g를 기억하는 변환을 만들 뿐입니다. 나중에 x를 주어 적용하면 g를 먼저 실행하고 그 결과에 f를 적용합니다. repeated도 같은 생각을 재귀적으로 사용하여 횟수가 0이면 항등 변환을, 더 큰 횟수에서는 합성을 하나 더 얹은 변환을 돌려줍니다.

average-damp도 프로시저를 반환합니다. 반환된 변환은 원래 f를 x에 적용한 값과 x의 평균을 계산합니다. 제곱근 변환 y ↦ 16/y에 추측값 2를 넣으면 5가 되고 고정점인 4를 넣으면 그대로 4가 됩니다. 프로시저 생성자는 재사용할 방법을 가지고 있고, 전달된 f가 실제로 바꿀 동작을 결정합니다.

리스펙스 · SICP 코드SICP에 필요한 Scheme 호환 문법을 리스펙스 SICP 프로필로 실행합니다.
(begin
  (define (compose f g)
    (lambda (x) (f (g x))))
  (define (repeated f count)
    (if (= count 0)
        (lambda (x) x)
        (compose f (repeated f (- count 1)))))
  (define (increment x) (+ x 1))
  (define (square x) (* x x))
  (list ((compose square increment) 6)
        ((compose increment square) 6)
        ((repeated increment 5) 10)))
리스펙스 학습용 런타임리스펙스 SICP 프로필 1.0.0
리스펙스 SICP 런타임 불러오는 중
리스펙스 · SICP 코드UTF-8 356 / 1,048,576바이트
예제
결과
출력
진단
보이는 실행 흐름0 / 0 개의 실행 이벤트
    이 브라우저 결과는 리스펙스 바우치나 권한이 아닙니다.wasm —
    예상 관찰

    합성 프로그램은 (49 37 15)를 반환합니다. 평균 감쇠 프로그램은 (5 4 21)을 반환합니다.

    실행 흐름에서 볼 점

    반환할 프로시저를 만드는 호출과 그 프로시저를 나중에 적용하는 호출을 나누어 보세요. 합성 예제에서는 증가한 뒤 제곱하는 경우와 제곱한 뒤 증가하는 경우를 비교합니다. 평균 감쇠 예제에서는 평균을 만들기 전에 포획한 f가 호출되는 곳을 찾으세요. 실행 흐름은 이 유한한 적용을 보여 줄 뿐 두 변환의 일반적인 동등성을 증명하지는 않습니다.

    직접 해보기

    힌트를 보기 전에 프로그램을 바꿔 보세요.

    compose만 사용해 twice를 정의하고 ((twice increment) 10)과 ((twice square) 3)을 함께 반환하세요. 실행하기 전에 두 값을 예상해 보세요.

    힌트 하나 보기

    twice는 f를 자기 자신과 합성한 것과 같은 프로시저를 반환해야 합니다. 예상값은 12와 81입니다.