Произвольные вычисления в макросе схемы

Говорят, что макросы схемы, по крайней мере, синтаксического разнообразия, позволяют преобразовывать произвольные вычисления в коде. Однако (как в общем, так и в конкретном случае, который я сейчас рассматриваю) это требует, чтобы вычисление было задано в терминах рекурсивных функций. Когда я пробую различные варианты этого, я получаю, например,

main.scm:32:71: compile: несвязанный идентификатор в модуле (в среде преобразователя, который не включает определение времени выполнения) в: expand-vars

(Реализация Racket, если это имеет значение.)

В результате получается, что вы не можете определить именованные функции до окончания макропереработки.

Я полагаю, что мог бы прибегнуть к комбинатору Y, но я думаю, что стоит спросить сначала, есть ли лучший подход?

1 ответ

Решение

Да, тот факт, что вы используете Racket, имеет значение - в Racket есть то, что называется "разделением фаз", что означает, что уровень синтаксиса не может использовать функции времени выполнения. Например, это:

#lang racket
(define (bleh) #'123)
(define-syntax (foo stx)
  (bleh))
(foo)

не будет работать с bleh связан во время выполнения, недоступен для синтаксиса. Вместо этого должно быть

(define-for-syntax (bleh) #'123)

или же

(begin-for-syntax (define (bleh) #'123))

или перемещен как внутреннее определение в тело макроса, или перемещен в собственный модуль и требует использования (require (for-syntax "bleh.rkt")),

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