0

というマクロがありcompare-and-swap!ます:

(define-macro (compare-and-swap! l x y)
  `(if (> (vector-ref ,l ,x) (vector-ref ,l ,y))
    (vector-swap! ,l ,x ,y)))

動作します。次のようにテストしています。

(define v (list->vector '(5 4 3 2 1)))
(print v)
(compare-and-swap! v 1 2)
(print v)

コンペア アンド スワップと呼べるペアのリストを返す関数があります。リスト全体を並べ替えるには、次のようにします。

(batcher 8) → ((0 1) (2 3) (0 2) (1 3) (1 2) (4 5) (6 7) (4 6) (5 7) (5 6) (0 4) (2 6) (2 4) (1 5) (3 7) (3 5) (1 2) (3 4) (5 6))

ここで、batcher を呼び出してcompare-and-swap!for each pair を実行することにより、N 要素リストをソートするラムダを生成するマクロを作成したいと考えています。

例えば、

(generate-sorter 8)
→
(lambda (l) (begin (compare-and-swap! l 0 1) (compare-and-swap! l 2 3) ...))
→
(lambda (l) (begin (if (> (vector-ref l 0) (vector-ref l 1)) (vector-swap! 0 1)) (if (> (vector-ref l 2) (vector-ref l 3)) (vector-swap! 2 3))) ... )

必要なコードを生成する関数を作成しました。

(define generate-sorter (lambda (len)
    (list 'lambda '( li ) 'begin (map (lambda (pair) (list 'compare-and-swap! 'li (first pair) (second pair))) (batcher len)))
))

しかし、私は今それをマクロにする方法を知りません。

4

1 に答える 1

1

これには、特に「生成」部分にはマクロは必要ありません。generate-sorterの結果は呼び出しごとに異なる可能性があり、マクロ展開によって結果をエンコードすることを望んでいたため、マクロを考えていたと思われます。別の方法として、レキシカル環境で結果を取得する方法があります。

(define-syntax compare-and-swap!
  (syntax-rules ()
    ((_ l x y)
     (when (> (vector-ref l x) (vector-ref l y))
       (vector-swap! l x y)))))

(define (generate-sorter n)
  (let ((sorters (generate-sorter n)))
    (lambda (l)
      (for-each (lambda (sorter) 
                  (compare-and-swap! l (car sorter) (card sorter)))
                sorters))))

(define sorter-8 (generate-sorter 8))
(sorter-8 <l-thingy>)
-> <sorted-l-thingy>
于 2013-05-14T02:21:40.650 に答える