0

「ラッピング」関数のマクロを作成しようとしています。つまり、リストを取得してシンボル「a」を最初の要素に変換する関数がある場合、通常はラムダ(l)(cons)として定義されます。 'al)、しかし私は関数と整数式のペアのリストを取り、'古い関数のいくつかの引数を取り、ペアに基づいて残りを取得する新しい関数を作成することによってその関数を'ラップするマクロが必要です、関数を与えるために、位置として整数を使用し、値として式を使用します。このようなもの:

(wrap list (0 'blah) (2 'bloo) (4 'blee))

次のように展開する必要があります。

(lambda (a1 a2 . rest)
  (apply list 'blah a1 'bloo a2 'blee rest))

問題は、マクロがペアの整数の値を見つける方法がわからないことです。マクロは構文オブジェクトとしてしか認識していません。私はマクロにかなり慣れていないので、これはかなり単純なはずです。ドキュメントに問題があり、マクロに関する単純なチュートリアル以外の情報をWeb上で見つけることができません。どんな助けでもいただければ幸いです。

4

1 に答える 1

3

これは、特にSRFI 26の方がはるかに直感的に使用できる場合は、書きたいと思うクレイジーなマクロのようです。の代わりに(wrap list (0 'blah) (2 'bloo) (4 'blee))、次を使用できます。

(cut list 'blah <> 'bloo <> 'blee <...>)

それは確かにはるかに読みやすいです。


本当にそのようなマクロを作成する必要がある場合は、の使用法wrapを同等の使用法に変換することにより、これを実行する1つの方法がありcutます。

(require (for-syntax syntax/parse) srfi/26)
(define-syntax (wrap stx)
  (syntax-parse stx
    ((_ func:expr (idx:nat expr:expr) ...)
     (let* ((alist (map cons
                        (syntax->datum #'(idx ...))
                        (syntax-e #'(expr ...))))
            (upper (add1 (apply max -1 (map car alist))))
            (listfunc (lambda (i)
                        (cond ((assv i alist) => cdr)
                              (else #'<>)))))
       (with-syntax (((args ...) (build-list upper listfunc)))
         #'(cut func args ... <...>))))))

構文オブジェクトを指定して整数を取得する方法についての質問に答える鍵は、syntax->datum(深い構文ストリッピングの場合)またはsyntax-e(浅い構文ストリッピングの場合)を使用することです。


(PS(これを読んでいるラケットの専門家にとって。)私は非常に新しいので、専門家は上記を書くためのより良い方法を見つけることができると確信しています。私はもともとマクロをマクロとして書きsyntax-parse、次に構文クラスを叩きました。それだけです。 )。syntax-parsesyntax-casesyntax-parse

于 2012-11-12T05:23:12.047 に答える