Самый чистый способ сделать "производный" идентификатор?
Макросы Scheme очень часто создают "производные" идентификаторы, например, как определить тип записи. foo
(используя API синтаксической записи R6RS) по умолчанию определит конструктор с именем make-foo
, Я хотел сделать что-то подобное в своем собственном макросе, но я не мог найти какой-либо чистый способ в стандартных библиотеках. Я закончил тем, что написал это:
(define (identifier-add-prefix identifier prefix)
(datum->syntax identifier
(string->symbol (string-append prefix
(symbol->string (syntax->datum identifier)))))
Я преобразую объект синтаксиса (предполагается, что это идентификатор) в элемент данных, преобразую этот символ в строку, создаю новую строку с префиксом префикса, преобразую эту строку в символ, а затем, наконец, превращаю этот символ в идентификатор в та же синтаксическая среда, что и identifier
,
Это работает, но это кажется окольным и грязным. Есть ли более чистый или более идиоматический способ сделать это?
1 ответ
Хотя это может быть не гигиенический макрос, я полагаю, вы можете использовать синтаксис define, как это (в схеме курицы). Для куриной схемы документация для макросов находится здесь. Также этот вопрос проливает свет на макросы схемы курицы. Наконец, я не знаю, будет ли это идиоматическим способом решения проблемы.
(use format)
(use srfi-13)
(define-syntax recgen
(lambda (expr inject compare)
`(define (,(string->symbol (string-append "make-" (cadr expr))) ) (format #t "called"))))
#> (recgen "bar")
#> (make-bar)
called
Одиночное определение выше может быть изменено на (начало...), которое определяет методы получения / установки или другие способы взаимодействия с записью.