问题
Can a macro be written in Scheme (with define-syntax
, for example) which will take expressions like this:
(op a b c d e f g h i j)
And yield expressions like this as output?
(op (op (op (op (op (op (op (op (op a b) c) d) e) f) g) h) i) j)
Of course, for arbitrary lengths. I can't think of a way to do it, given some template like this:
(define-syntax op
(syntax-rules ()
[(_) 'base-case]
[(v1 v2 ...) 'nested-case??]))
回答1:
(define bop list)
(define-syntax op
(syntax-rules ()
((op a b) (bop a b))
((op a b c ...) (op (bop a b) c ...))))
For example, (op 1 2 3 4)
expands to (bop (bop (bop 1 2) 3) 4)
and evaluates to (((1 2) 3) 4)
.
回答2:
The function you want to apply to the arguments should itself be an argument to the macro. Barring that, my solution was the same.
#!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 ...))))
回答3:
To show how the answer works out:
(op 1 2 3 4)
This is an op with 4 statements, so the 2nd case gets selected with a=1, b=2, c=3, ...=4:
(op (bop 1 2) 3 4)
This is an op with 3 statements, so 2nd case again. a=(bop 1 2), b=3, c=4:
(op (bop (bop 1 2) 3) 4)
Now this is a bop with 2 statements, so a=(bop (bop 1 2) 3), b=4, and it's done.
来源:https://stackoverflow.com/questions/340204/scheme-macro-for-nesting-expressions