값, 이름, 프로시저

리스펙스의 리터럴과 호출을 읽고, `define`과 `let`으로 이름을 붙이고, `lambda`로 다시 쓸 수 있는 프로시저를 만듭니다.

1단계에서는 완전한 프로그램을 실행했습니다. 이제 그 안의 몇 가지 모양을 분리해서 봅니다. 값, 값을 가리키는 이름, 값을 계산하는 프로시저 호출을 구분하면 괄호는 일정한 순서로 읽힙니다.

값은 홀로 설 수 있습니다

수, 불리언, 문자열, 문자, 인용 데이터는 값입니다.

LISPEX
42
#t
"Lispex"
#\L
'ready

작은따옴표가 없는 ready는 다릅니다. 리스펙스는 이를 이름으로 찾아봅니다. 'ready라고 쓰면 심볼을 데이터로 보존합니다.

호출 위치의 리스트는 일을 요청합니다

아래 식을 가장 안쪽부터 읽어 봅시다.

LISPEX
(+ 10 (* 2 3))

리스펙스는 +를 찾고, 10을 평가하고, (* 2 3)을 왼쪽부터 평가합니다. 안쪽 호출이 6을 내므로 바깥 호출은 (+ 10 6)과 같은 값을 계산합니다.

결과

OUTPUT
16

모든 괄호가 평범한 호출인 것은 아닙니다. define, lambda, let, if는 어느 부분을 평가하고 이름이 어디에서 보이는지 제어합니다.

값에 이름 붙이기

define은 최상위 바인딩을 만들거나 갱신합니다.

LISPEX
(define fee 3)
(+ 20 fee)

결과

OUTPUT
23

정의는 아무것도 출력하지 않고 마지막 덧셈이 값 하나를 출력합니다.

한 본문에서만 이름이 필요하면 let을 씁니다.

LISPEX
(let ((base 7))
  (* base 2))

결과

OUTPUT
14

base는 본문 안에서만 보입니다. 임시 계산의 범위를 작게 두면 규칙을 점검하기 쉽습니다.

다시 쓰는 프로시저 만들기

프로시저 정의 축약은 프로시저 이름과 입력 이름을 함께 적습니다.

LISPEX
(define (price-with-fee price fee)
  (+ price fee))

(price-with-fee 20 3)

결과

OUTPUT
23

긴 형식은 프로시저도 값이라는 사실을 더 분명히 보여 줍니다.

LISPEX
(define price-with-fee
  (lambda (price fee)
    (+ price fee)))

프로시저는 인자 수를 검사합니다. price-with-fee에 인자를 하나나 세 개 주면 임의의 기본값을 쓰지 않고 런타임 오류를 냅니다.

조각을 합치기

LISPEX
(define (price-with-fee price fee)
  (+ price fee))

(list (price-with-fee 20 3)
      (let ((base 7))
        (* base 2)))

결과

OUTPUT
(23 14)

첫 번째 리스트 원소를 계산한 뒤 두 번째 원소를 계산합니다. list는 준비된 두 값을 받아 (23 14)를 만듭니다.

연습

입력을 3배 하는 triple을 정의하고, list 안에서 두 번 호출해 (12 21)을 반환하세요.

답 하나 보기
LISPEX
(define (triple n)
  (* n 3))

(list (triple 4) (triple 7))

3단계로 갈 준비가 됐나요?

인용한 심볼이 왜 데이터인지, (* 2 3)이 왜 바깥 덧셈보다 먼저 끝나는지, let 이름이 어디에서 보이는지 설명할 수 있으면 됩니다. 다음은 데이터, 조건, 결정입니다.