--- title: section6 tags: macro --- ### 6 スプライシング・レットって何のためにあるの? ラケット・スプライシングを一番長く見つめていました。何のために使うのか?なぜそれを使うのでしょうか?なぜリファレンスのマクロのセクションにあるのか? ステップ1、~~箱に穴を開けて~~脱神話化する。例えば、splicing-letを次のように使います。 ```ocaml= > (require racket/splicing) > (splicing-let ([x 0]) (define (get-x) x)) ; get-x is visible out here: > (get-x) 0 ; but x is not: > x x: undefined; cannot reference an identifier before its definition in module: 'program ``` は以下と同じです。 ```ocaml= > (define get-y (let ([y 0]) (lambda () y))) ; get-y is visible out here: > (get-y) 0 ; but y is not: > y y: undefined; cannot reference an identifier before its definition in module: 'program ``` これはLisp/Scheme/Racketの古典的なイディオムで、「let over lambda」と呼ばれることもあります。クロージャはyを隠し、yにはget-yでしかアクセスできないようになっています。 > クロージャとオブジェクトに関する公案です。 では、なぜスプライシング形式を気にするのでしょうか?特に複数のボディフォームがある場合、より簡潔にすることができます。 ```ocaml= > (require racket/splicing) > (splicing-let ([x 0]) (define (inc) (set! x (+ x 1))) (define (dec) (set! x (- 1 x))) (define (get) x)) ``` スプライシングのバリエーションは、通常の方法よりも便利です。 ```ocaml= > (define-values (inc dec get) (let ([x 0]) (values (lambda () ; inc (set! x (+ x 1))) (lambda () ; dec (set! x (- x 1))) (lambda () ; get x)))) ``` 体の形がたくさんあって、それをマクロで生成している場合は、バリエーションのつなぎ方がもっと簡単になります。 * [next section(7 堅牢なマクロ:syntax-parse)](https://hackmd.io/sCt8NNyTTc6XyPrCCaMIPw) * [previous section(5 構文パラメータ)](https://hackmd.io/Hi_rX5oZTLKILvCF-QL6Lw)