schemeのsyntax-caseマクロで遊んだりしている。まず、何を題材にしようかと考え、letに多少の構文を付け加えたものを以前にsyntax-rulesを使って定義してみたのを思い出した。
id:SaitoAtsushi:20070126:1169813763
要はdefineと同じような関数定義用の構文糖衣を付け加えたletである。
補助マクロがグローバルなのが嫌なカンジだったのでsyntax-caseを使えばなんとかできるかと考えて書いたのがこれ。
(define-syntax letf (lambda(y) (define decexpand (lambda (x) (syntax-case x () ((dec ...) (let f ((dec #'(dec ...))) (syntax-case dec () (() #'()) ((a1 a2 ...) (with-syntax (((rest ...) (f #'(a2 ...)))) (syntax-case #'a1 () (((var arg ...) fbody) #'((var (lambda(arg ...) fbody)) rest ...)) ((var obj) #'((var obj) rest ...))))))))))) (syntax-case y () ((_ (decs ...) body ...) (with-syntax ((expanded (decexpand #'(decs ...)))) #'(let expanded body ...))) ((_ name (decs ...) body ...) (with-syntax ((expanded (decexpand #'(decs ...)))) #'(let name expanded body ...))))))
どこまでがコンパイル時に動いてどこからが実行時のコードなのかよく意識しないとすぐに混乱する。結構難しいよコレ。
Document ID: 02c7056eb5c56eead355cafab89e007d