결과를 남기고 프로세스를 다시 그려 보세요.
작은 프로그램 열한 개로 제1장의 열두 가지 생각을 다시 연결합니다. 먼저 예상하고 실행한 뒤 마지막 값 뒤에 숨은 프로세스를 설명하세요.
프로그램이 무엇을 반환하는지, 프로세스가 어떻게 자라거나 줄어드는지, 프로시저 값이 나중에 사용할 동작을 언제 만드는지 함께 설명할 수 있나요?
- 조합식 읽기
- 프로시저 환경 설명하기
- 재귀와 반복 프로세스 비교하기
- 프로시저 값을 인자로 전달하기
- 프로시저를 반환하고 합성해 새 변환 만들기
- 문제를 줄이며 불변식 유지하기
- 수치 추측값 반복 개선하기
- 유한 연분수 누적하기
- 고정점 변환 되풀이하기
- 빠르게 지수 줄이기
- 모듈러 합동의 결론 범위 제한하기
- 트리 재귀 호출 성장과 반복 단계 비교하기
팩토리얼 두 프로세스는 같은 값을 반환하지만 하나는 완전한 상태를 넘기고 다른 하나는 작은 호출이 돌아올 때까지 곱셈을 남겨 둡니다.
고차 합에서는 term과 next를 프로시저 값으로 받아 매 단계에 적용합니다. 반환되는 프로시저 예제에서는 compose와 repeated가 먼저 변환을 만들고 나중에 그 변환을 적용합니다. 합성 순서를 바꾸면 같은 두 프로시저를 사용해도 결과가 달라집니다.
유클리드 알고리즘은 같은 최대공약수를 보존하며 문제를 줄입니다. 제곱근과 연분수와 고정점은 각기 다른 형태의 완전한 다음 상태를 넘깁니다.
빠른 거듭제곱과 모듈러 거듭제곱에서는 어떤 양이 보존되는지 확인하세요. 마지막 피보나치 예제에서는 같은 값 뒤에 반복되는 호출이 얼마나 많은지 직접 셉니다.
(letrec ((factorial
(lambda (n product)
(if (= n 0)
product
(factorial (- n 1) (* n product))))))
(factorial 8 1))- 출력
- —
- 값
- —
- 진단
- —
팩토리얼 두 프로그램은 40320을 반환합니다. 고차 합은 55를 반환하고 반환되는 프로시저의 합성 예제는 (49 37 15)를 반환합니다. 나머지 프로그램은 대응하는 제1장 수업의 결과를 반환하며 피보나치 계측 프로그램은 (21 67 8)을 반환합니다.
호출과 곱셈, term과 next 적용, 반환할 프로시저를 만드는 호출과 나중 적용하는 호출, remainder 순서쌍, 개선된 추측값, 누적된 연분수 꼬리, 고정점 추측값, 지수 전이, 모듈러 remainder, 되풀이되는 fib 호출을 비교하세요.
프로세스를 생각하는 질문 열한 개
프로시저 정의는 표현식을 어떻게 재사용할 수 있는 방법으로 만들까요?
답 프로시저를 적용하면 새 환경에서 각 매개변수가 인수 값에 묶입니다. 그 환경에서 본문을 평가하므로 3과 4를 넣은 sum-of-squares는 25를 반환합니다.
재귀적 프로세스와 반복적 프로세스는 무엇이 다를까요?
답 두 정의 모두 자기 자신을 호출하므로 재귀 프로시저입니다. 하지만 두 번째 정의만 고정된 개수의 상태 변수로 요약할 수 있는 반복적 프로세스를 만듭니다.
하나의 프로시저로 여러 종류의 합을 어떻게 나타낼 수 있을까요?
답 이 분리는 중요한 설계 습관의 시작입니다. 바뀌지 않는 프로세스에는 한 번 이름을 붙이고 달라지는 결정은 인수로 넘깁니다.
a와 b를 b와 나머지로 바꿔도 최대공약수가 유지되는 이유는 무엇일까요?
답 각 호출은 (a, b)를 (b, remainder(a, b))로 바꿉니다. 두 번째 값이 0이 되면 첫 번째 값이 보존된 최대공약수입니다. 재귀 호출 뒤로 미뤄 둔 계산은 없습니다.
한 번의 개선 규칙이 어떻게 점점 더 정확한 수치 프로세스를 만들까요?
답 이 프로그램들은 숨은 오차 한도 대신 개선 횟수를 고정합니다. 1.0에서 여섯 번 개선하면 √2에 대한 결정적인 관찰을 얻으며 명시적인 이력에서는 추측값 사이의 차이가 빠르게 줄어드는 모습을 볼 수 있습니다.
평가 순서는 유한 연분수 값을 바꾸지 않으면서 프로세스의 모양을 어떻게 바꿀까요?
답 반복 버전은 k번 항에서 시작하며 0.0을 이미 계산한 꼬리로 둡니다. 호출마다 result를 완성된 연분수 층 하나로 바꾸고 1번 항을 향해 갑니다. 두 예제는 분자와 분모 열 개가 모두 1.0이므로 황금비의 역수에 대한 같은 유한 근삿값을 반환합니다.
변환을 적용해도 바뀌지 않는 값을 찾는다는 말은 무엇을 뜻할까요?
답 fixed-point는 관찰할 수 없는 오차 한도 안에 정지 결정을 숨기지 않습니다. 변환과 현재 추측값과 남은 횟수가 프로세스의 완전한 상태입니다. 이력을 만드는 버전은 같은 값 전달을 기록해 번갈아 나타나는 추측값을 그대로 보여 줍니다.
계산하는 거듭제곱을 바꾸지 않으면서 지수를 어떻게 빠르게 줄일까요?
답 exponent가 0이 되면 남은 거듭제곱은 1이고 product에 답이 모두 들어 있으므로 프로세스가 멈춥니다. 이력 프로그램은 모든 호출의 전체 상태를 기록해 짝수 전이와 홀수 전이를 직접 확인하게 합니다.
모듈러 합동 하나로 후보 수에 관해 무엇을 알 수 있고 무엇은 알 수 없을까요?
답 passes-base-2?는 2의 candidate승과 2가 candidate를 모듈러스로 한 합동인지 점검합니다. 17은 통과하고 15는 실패합니다. 3과 11과 17을 곱한 합성수 561도 통과합니다. 실패는 이 합동을 만족하지 않음을 보여 주지만 밑 하나의 통과는 증거일 뿐 후보가 소수라는 증명이 아닙니다.
같은 피보나치 값을 돌려주는 두 프로시저의 시간과 공간 요구량은 어떻게 다르게 자랄까요?
답 n이 8이면 계측한 트리는 67번의 프로시저 적용 뒤 21을 반환하고 깊이 8에 닿습니다. 반복 프로세스는 이웃한 피보나치 값 두 개와 남은 횟수만 가지고 같은 값에 여덟 단계 만에 닿습니다. 이 교과서적인 두 프로시저에서 단순 재귀의 시간은 지수적으로 자라고 깊이는 선형으로 자라며 반복 프로세스의 시간은 선형이고 상태 변수 수는 일정합니다. 화면의 숫자는 여전히 이 유한한 프로그램과 입력만 설명합니다.
프로시저 호출의 결과가 또 다른 프로시저라면 어떤 새로운 구성이 가능해질까요?
답 average-damp도 프로시저를 반환합니다. 반환된 변환은 원래 f를 x에 적용한 값과 x의 평균을 계산합니다. 제곱근 변환 y ↦ 16/y에 추측값 2를 넣으면 5가 되고 고정점인 4를 넣으면 그대로 4가 됩니다. 프로시저 생성자는 재사용할 방법을 가지고 있고, 전달된 f가 실제로 바꿀 동작을 결정합니다.