Самый чистый способ сделать "производный" идентификатор?

Макросы 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

Одиночное определение выше может быть изменено на (начало...), которое определяет методы получения / установки или другие способы взаимодействия с записью.

Другие вопросы по тегам