언제 필요한가요?
식이 셀을 바꾸거나 출력을 하거나 오류를 내거나 아예 건너뛸 수 있다면 평가 순서가 중요해집니다. 리스펙스는 이 순서를 고정합니다. 그래서 같은 소스가 호스트 언어의 피연산자 관습에 좌우되지 않습니다.
실행으로 확인하기
LISPEX
(define x 0)
(list (begin (set! x 1) x) (begin (set! x (+ x 1)) x))관측 결과
OUTPUT
(1 2)예제 읽기
첫 begin이 x를 0에서 1로 바꾸고 1을 돌려줍니다. 그다음에 두 번째 피연산자가 이 새 값을 읽어 1을 더한 뒤 2를 저장하고 돌려줍니다. 그래서 list는 1과 2를 차례로 받습니다.
이 순서로 생각하세요
let의 초기식은 바깥 환경에서 왼쪽부터 평가합니다.let*은 바인딩을 하나 만들 때마다 스코프를 넓히고,letrec은 모든 셀을 먼저 할당합니다.- 시퀀스는 왼쪽부터 평가하고, 마지막이 아닌 값 패킷은 버립니다.
and와or는 왼쪽부터 단락 평가합니다. 거짓인 값은#f하나뿐입니다.
빠르게 고르기
| 문맥 | 평가 순서 | 건너뛸 수 있는 것 |
|---|---|---|
| 프로시저 호출 | 연산자, 피연산자를 왼쪽부터 | 없음 |
begin | 폼을 왼쪽부터 | 없음, 앞선 값만 버림 |
if | 검사식 뒤 선택한 분기 하나 | 선택하지 않은 분기 |
and / or | 피연산자를 왼쪽부터 | 답이 정해진 뒤의 나머지 |
let | 바깥 스코프에서 초기식을 왼쪽부터 | 없음 |
let* | 초기식마다 바인딩하고 스코프 확장 | 없음 |
흔한 오해
리스펙스는 다른 Scheme 구현의 미지정 피연산자 순서를 물려받지 않습니다.
현재 경계
- 인자 수 오류는 정해진 연산자·피연산자 평가가 모두 끝난 뒤에 발생합니다.
다음으로
let 계열의 스코프 차이는 바인딩에서 이어집니다. 의도적으로 일찍 멈추는 형식은 조건식에서 다룹니다.