Переопределить встроенную схему, но только если она используется в качестве аргумента для конкретной процедуры?

Как я могу переопределить процедуру and только когда он вызывается в качестве аргумента процедуры fetch?

Например:

; this `and` returns #f
(and #t #f)

; this `and` returns "and a b" 
(fetch (foo (bar (and "a" "b"))))

Я хотел бы написать макрос для этого, но я не могу понять, как написать шаблон, который соответствует and в любом месте произвольного дерева аргументов, переданных fetch,

Я использую Chicken и с удовольствием использую столько R7RS, сколько поддерживает Chicken.

1 ответ

Решение

Один кирка: and это не процедура, это синтаксис (подумайте об этом: оценка останавливается, как только первый #f встречается).

Но независимо от этого, я не думаю, что вы пытаетесь сделать это, переопределив and, Вам нужно будет конвертировать fetch быть макросом. Вместо того, чтобы пытаться сканировать вход и заменить andЯ бы использовал негигиеничный let переопределить значение and на местном уровне. Немного так:

(define my-local-and ...)
(define the-real-fetch ...)

(define-syntax fetch
  (ir-macro-transformer
    (lambda (e i c)
      `(let ((,(i 'and) my-local-and))
         (the-real-fetch ,@(cdr e))))))

Я бы на самом деле возразил против этого, потому что это действительно испортит ожидания пользователей в отношении того, что происходит. Возможно, вы можете объяснить немного больше о том, почему вы хотите это сделать?

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