내장 규칙 언어의 작성자가 공백이나 괄호 없이 age>=18=>allow라고 쓰고 싶어 한다고 해 봐요. 겉보기 변화는 작아요. 하지만 어디서 처리할지 정하려면 규칙을 실행하기 전에 어느 단계가 각 조각을 인식하는지 살펴야 해요.
Racket에서는 리더가 최초의 구문 표현을 만들어요. 일반적인 읽기 규칙에서 이 조각은 작성자가 상상한 연산자들의 나열이 아니라 하나의 심벌로 들어올 수 있어요. 매크로가 의도적으로 그 심벌의 철자를 파싱할 수는 있지만, 그러면 표기 안에 작은 파서가 생기는 거예요. 매크로를 둘러싼 어휘 규칙이 바뀌는 것은 아니에요. 실제로 다른 토큰 경계나 구분자 규칙이 필요한 언어라면 사용자 정의 리더가 적절해요.
확장은 다른 일을 맡아요. 인식된 구문을 받아 잘못된 규칙 형식을 거부하고, 바인딩을 만들고, 규칙을 호출로 바꿀 수 있어요. 실행 시점의 코드는 여전히 나이 값을 얻고, 값이 없을 때의 동작을 정하고, 허용된 행동을 수행해야 해요. 나중에 attempt 형식이 추가된다면 확장은 재시도 엔진을 호출하도록 구성할 수 있어요. 그 엔진이 검사와 행동 중 무엇을 반복하는지는 런타임 계약이 필요해요.
이 선택들이 하나의 일관된 작성 환경을 이룬다면 이름 붙은 언어로 리더와 확장기의 시작점을 묶을 수 있어요. 문서화와 도구 지원의 책임도 따라와요. 요청의 뜻이 기존 비교를 호출하고 결정을 반환하는 정도라면 평범한 라이브러리 호출로도 충분히 분명할 수 있어요. 추가 언어 경계의 가치는 작성자가 읽고 유지할 규칙을 기준으로 따져 보겠어요.