LINUX.ORG.RU

Scheme, macros


0

0

Мне нужно заменить все вхождения (g param) на (begin (display "g: ") (display 'param) param)

Причём в выражении произвольной вложенности, например в
(let [(x 1)] (g x))

Все остальные выражения должны остаться без изменений.

Сделал такой макрос:

(define-syntax g-processor
  (syntax-rules (g)
    [(_ (g x)) (begin (display "g: ") (display 'x) (newline) x)]
    [(_ (x . y)) ((g-processor x) . (g-processor y))]
    [(_ x) x]))

Но он не работает. Например:

(g-processor (+ 1)) -> ((g-processor +) . (g-processor (1)) -> (+ . (g-processor (1))) == (+ g-procesor (1)), и здесь, конечно, всё стопорится,
потому что g-processor не в позиции применения, и получается invalid syntax.

По идее должно быть просто — прогуляться по двоичному дереву и заменить все вхождения (g x) на нужное выражение, но не получается.
★★★★★

Хмм, сделал вот так:

(define-syntax g-processor
  (syntax-rules (g)
    [(_ (g x)) (begin (display "g: ") (display 'x) (newline) x)]
    [(_ (x ...)) ((g-processor x) ...)]
    [(_ x) x]))

вроде работает.

Legioner ★★★★★
() автор топика

Типичный пример, когда гигиена просто на хрен не нужна, и создаёт только лишние неприятности. Ведь гораздо же проще сказать:

(define-macro (g param) `(begin (display "g:") (display (quote ,param)) ,param))

anonymous
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.