Предположим, авторы встроенного языка правил хотят писать age>=18=>allow без пробелов и скобок. Внешне изменение небольшое. Чтобы найти ему место, нужно понять, какой слой распознаёт отдельные части ещё до выполнения правила.
В Racket reader формирует исходное синтаксическое представление. При обычном чтении этот фрагмент может оказаться одним символом, а не последовательностью операторов, которую представляет автор. Макрос мог бы специально разобрать написание символа, но тогда внутри нотации появится маленький парсер. Лексические соглашения вокруг макроса от этого не изменятся. Собственный reader уместен, если языку действительно нужны другие границы токенов или правила разделителей.
У раскрытия синтаксиса другая работа. Получив распознанную форму, оно может отвергнуть некорректные правила, установить связывания и преобразовать правило в вызовы. Код времени выполнения всё ещё должен получить возраст, определить поведение при его отсутствии и выполнить разрешённое действие. Если позже появится форма attempt, раскрытие может организовать вызов механизма повторных попыток. Повторяет ли он проверку, действие или оба шага, должен определять контракт времени выполнения.
Именованный язык позволяет объединить начальные точки reader и expander, когда эти решения образуют цельную среду написания правил. Вместе с этим появляются обязанности по документации и инструментам. Если запрос означает лишь вызов существующего сравнения с возвратом решения, обычный библиотечный вызов уже может быть достаточно понятным. Дополнительную границу я бы обосновывал тем, какие правила авторам предстоит читать и сопровождать.