Макрос схемы для вложенных выражений - PullRequest
5 голосов
/ 04 декабря 2008

Может ли макрос быть написан на схеме (например, с define-syntax), который будет принимать такие выражения:

(op a b c d e f g h i j)

И вывести такие выражения как выходные?

(op (op (op (op (op (op (op (op (op a b) c) d) e) f) g) h) i) j) 

Конечно, для произвольной длины. Я не могу придумать, как это сделать, учитывая такой шаблон:

(define-syntax op
  (syntax-rules ()
    [(_) 'base-case]
    [(v1 v2 ...) 'nested-case??]))

Ответы [ 3 ]

6 голосов
/ 04 декабря 2008
(define bop list)

(define-syntax op
  (syntax-rules ()
    ((op a b) (bop a b))
    ((op a b c ...) (op (bop a b) c ...))))

Например, (op 1 2 3 4) расширяется до (bop (bop (bop 1 2) 3) 4) и оценивается до (((1 2) 3) 4).

1 голос
/ 10 декабря 2008

Функция, которую вы хотите применить к аргументам, сама должна быть аргументом макроса. За исключением этого, мое решение было таким же.

#!r6rs

(import (rnrs base))

(define-syntax claudiu
  (syntax-rules ()
    ((claudiu fun first second)
     (fun first second))
    ((claudiu fun first second rest ...)
     (claudiu fun (claudiu fun first second) rest ...))))
0 голосов
/ 04 декабря 2008

Чтобы показать, как работает ответ:

(op 1 2 3 4)

Это операция с 4 операторами, поэтому второй случай выбирается с a = 1, b = 2, c = 3, ... = 4:

(op (bop 1 2) 3 4)

Это операция с 3 операторами, так что снова 2-й случай. а = (боп 1 2), б = 3, с = 4:

(op (bop (bop 1 2) 3) 4)

Теперь это боб с 2 операторами, поэтому a = (bop (bop 1 2) 3), b = 4, и все готово.

...