1.3.1절(https://www.inforum24.com/memos/1249)에서 sum을 만들 때, term 이나 next 인자를 넘기기 위해 사전에 define을 해주어야 했다.
프로시저에 넘기기 위해서만 사용될 프로시저를 다 만들어놓는 것은 좋지 않다.
바로바로 표현할 수 있는 lambda 라는 특별한 형태를 사용하여 이런 문제를 해결할 수 있다.
sum-cubes 에 lambda 적용하기
(define (sum-cubes a b)
(sum
(lambda (x) (* x x x))
a
(lambda (x) (+ x 1)
b)))
위 식은 cube 프로시저와 next 프로시저를 따로 정의하지 않고, 인자에 넘길 때 바로 lambda로 넘겨 사용하였다.
프로시저를 define 하는 것과 lambda의 차이점은 프로시저 이름의 유무 밖에 없다.
이름 공간을 아낄 수 있고, 직관적이다.
let 으로 갇힌 변수 만들기
함수 f(x, y) 가 다음과 같다고 하자.
f(x, y) = x(1+xy)^2 + y(1-y) + (1+xy)(1-y)
위 식을 프로시저로 정의할 때, a = 1+xy, b=1-y 라고 사용하면 함수를 다음과 같이 간단하게 표현할 수 있다.
f(x, y) = a^2x + by + ab
이제 프로시저로 직접 작성해보자.
먼저, lambda를 사용한 f(x,y)를 살펴보자.
(define (f x y)
((lambda (a b)
(+ (* a a x)
(* b y)
(* a b)))
) (+ 1 (* x y))
(- 1 y)))
lambda 식을 사용해 a, b 값을 받아 xa^2 + yb + ab 를 계산하는 프로시저를 만들고 바로 a 값과 b 값을 대입하여 결과를 내는 프로시저이다.
다음으로, let 문법을 사용한 f(x, y)를 살펴보자.
(define (f x y)
(let ((a (+ 1 (* x y)))
(b (- 1 y)))
(+ (* a a x)
(* b y)
(* a b))))
let 문법을 사용하여 a, b 값을 지정하고, 바로 사용하고 있다.
let 문법을 살펴보면, 먼저 정의가 등장하고 이후 몸체가 나오는데, let 괄호 하나로 묶여있다. 즉, let 괄호 내에서만 정의한 변수들을 사용할 수 있다.
위 두식은 순서만 다를 뿐 a, b에 대입할 값을 넣으면 xa^2 + yb + ab 를 계산해주는 동일한 프로시저이다.
let 은 새로운 기능이라기보다는, lambda 식을 더 보기 좋게 만든 syntatic sugar 이다.
사실, 내부에서 define 을 사용한 것과도 같은 역할을 하나, 식의 계산 방법에서 차이가 있다 이후 4.1.6절에서 다룬다.