생각해 볼 질문
평가기가 보통 프로시저도 만들고 바꿀 수 있는 같은 리스트 구조를 받아들이면 무엇이 가능해질까요? lambda 적용을 보통 기호 리스트 데이터로 구성하기 실행 전에 생성된 연산자·매개변수·본문 구조 살펴보기 명시적인 환경에서 생성한 프로시저 데이터 평가하기 산술 식의 한 기호가 나타나는 곳을 모두 바꾸기 프로그램 변환과 나중 실행하는 평가기 분리하기 make-linear-program은 리스트 ((lambda (x) (+ (* 3 x) 2)) 5)를 반환합니다. 평가하기 전에 보통 car와 cadr와 리스트 선택자로 구조를 살펴보거나 바꿀 수 있습니다. tiny-eval은 같은 데이터를 해석합니다. lambda는 표현된 compound procedure를 만들고 적용은 저장된 환경에 x = 5를 연결합니다.
두 번째 프로그램은 이차식을 데이터로 다루고 기호 x를 재귀적으로 3으로 바꿉니다. 변환 자체는 산술을 수행하지 않습니다. arithmetic-eval이 나중에 +와 *를 해석하여 16을 만듭니다. 이 유한 평가기는 나열된 산술 폼을 처리하며 생산자와 변환기와 평가기 사이의 명시적 표현 연결을 보여 줍니다.
SICP 코드 UTF-8 2,016 / 1,048,576바이트
( begin
( define ( make-linear-program slope intercept input )
( list
( list ' lambda
' ( x )
( list ' +
( list ' * slope ' x )
intercept ) )
input ) )
( define ( lookup name environment )
( let ( ( record ( assoc name environment ) ) )
( if record ( cdr record ) ' unbound ) ) )
( define ( extend parameters arguments environment )
( if ( null? parameters )
environment
( cons ( cons ( car parameters ) ( car arguments ) )
( extend ( cdr parameters )
( cdr arguments )
environment ) ) ) )
( define ( make-procedure parameters body environment )
( list ' compound parameters body environment ) )
( define ( tiny-eval expression environment )
( cond ( ( number? expression ) expression )
( ( symbol? expression ) ( lookup expression environment ) )
( ( and ( pair? expression )
( eq? ( car expression ) ' lambda ) )
( make-procedure
( cadr expression )
( caddr expression )
environment ) )
( ( pair? expression )
( let* ( ( procedure ( tiny-eval ( car expression ) environment ) )
( arguments
( map ( lambda ( operand )
( tiny-eval operand environment ) )
( cdr expression ) ) ) )
( cond ( ( procedure? procedure )
( apply procedure arguments ) )
( ( eq? ( car procedure ) ' compound )
( tiny-eval
( caddr procedure )
( extend ( cadr procedure )
arguments
( cadddr procedure ) ) ) )
( else ' not-a-procedure ) ) ) )
( else ' unknown-expression ) ) )
( define primitive-environment
( list ( cons ' + + ) ( cons ' * * ) ) )
( define program ( make-linear-program 3 2 5 ) )
( list program
( car ( car program ) )
( cadr ( car program ) )
( tiny-eval program primitive-environment ) ) ) 코드 실행Ctrl/⌘ Enter 파일 열기 코드 저장 코드 복사 편집기 지우기
예제 lambda 적용을 생성하고 평가하기 기호 식을 전문화한 뒤 실행하기
실행은 브라우저 안에서 이루어지며 프로그램 결과와 실행 추적을 보여줍니다. 예상 결과 생성 프로그램은 (((lambda (x) (+ (* 3 x) 2)) 5) lambda (x) 17)을 반환합니다. 전문화 프로그램은 ((+ (+ (* x x) (* 2 x)) 1) (+ (+ (* 3 3) (* 2 3)) 1) 16)을 반환합니다.
실행 추적에서 볼 점 리스트 생성과 기호 교체를 나중 평가와 분리하세요. tiny-eval에서는 생성한 lambda가 compound 레코드가 되고 생성한 적용이 환경 하나를 확장하는 과정을 따라가세요. arithmetic-eval 중에는 기호 교체가 일어나지 않는지 확인하세요.
직접 해보기 프로그램을 수정하고 결과를 비교해 보세요. 두 매개변수를 가진 affine 프로그램 (+ (* slope x) (* offset y))을 생성하고 매개변수 목록을 살펴본 뒤 평가하세요. 그 다음 생성한 본문에서 x만 전문화하고 y는 기호로 남기세요.
힌트 보기 프로그램 생성은 데이터만 반환해야 합니다. 환경 확장은 매개변수와 인자를 순서대로 짝짓고 전문화는 평가 전에 replace-symbol을 재사용할 수 있습니다.