Gauche:変更手続きへの変換

Gauche:変更手続きへの変換

変更手続きへの変換

線形更新 (Scheme:LinearUpdate) な手続きを、
変更手続き (mutation procedure (R7RS 1.3.5)) に変換するマクロを考えてみました。
(マクロは手続きではないですが)

reverse!!1 は、reverse! の第1引数を変更するようにしたものです。

!!1 ~ !!3 は、手続き名を指定可能にしたものです。それぞれ第1引数~第3引数を変更します。

!! は、「どちらも ! でまぎらわしい ! 」くらいの意味です。

後から戻り値の使用が必要と分かって、修正箇所が多いときに使ってみてください。
(自分のことですが。。。)

;; convert linear update to mutation procedure

(use srfi-1)

(define-syntax reverse!!1
  (syntax-rules ()
    ((_ x1 rest ...)
     (set! x1 (reverse! x1 rest ...)))))

(define-syntax !!1
  (syntax-rules ()
    ((_ proc x1 rest ...)
     (set! x1 (proc x1 rest ...)))))

(define-syntax !!2
  (syntax-rules ()
    ((_ proc x1 x2 rest ...)
     (set! x2 (proc x1 x2 rest ...)))))

(define-syntax !!3
  (syntax-rules ()
    ((_ proc x1 x2 x3 rest ...)
     (set! x3 (proc x1 x2 x3 rest ...)))))

;; test

(define list1 (list 1 2 3 4 5))
(define list2 (list 1 2 3 4 5))
(define list3 (list 1 2 3 4 5))
(define list4 (list 1 2 3 4 5))

(reverse!!1 list1)
(!!1 reverse! list2)
(!!2 map! + list3 (make-list 5 1))
(!!3 map! + (make-list 5 1) list4)

(print list1)
(print list2)
(print list3)
(print list4)

hamayama(2018/10/30 11:34:29 UTC)


もう少し考えて、一括して定義ができるようにしてみました。

(define-!!s (変更手続き名1 線形更新手続き名1 変更引数番号1) (変更手続き名2 線形更新手続き名2 変更引数番号2) ...)

変更する引数の番号は、1~3 のみ対応しています。

;; convert linear update to mutation procedure v2.2

(use srfi-1)

(define-syntax define-!!s
  (syntax-rules ()
    ((_ (name-mut name-lin 1) rest-group ...)
     (begin
       (define-syntax name-mut
         (syntax-rules ooo ()
           ((_ x1 rest ooo)
            (set! x1 (name-lin x1 rest ooo)))))
       (define-!!s rest-group ...)))
    ((_ (name-mut name-lin 2) rest-group ...)
     (begin
       (define-syntax name-mut
         (syntax-rules ooo ()
           ((_ x1 x2 rest ooo)
            (set! x2 (name-lin x1 x2 rest ooo)))))
       (define-!!s rest-group ...)))
    ((_ (name-mut name-lin 3) rest-group ...)
     (begin
       (define-syntax name-mut
         (syntax-rules ooo ()
           ((_ x1 x2 x3 rest ooo)
            (set! x3 (name-lin x1 x2 x3 rest ooo)))))
       (define-!!s rest-group ...)))
    ((_ (name-mut name-lin arg-no) rest-group ...)
     (syntax-error "third element must be 1-3." (name-mut name-lin arg-no)))
    ((_) #f)))

(define-!!s (reverse!!1 reverse! 1)
            (take!!1    take!    1)
            (map!!2     map!     2)
            (map!!3     map!     3))

;; test

(define list1 (list 1 2 3 4 5))
(define list2 (list 1 2 3 4 5))
(define list3 (list 1 2 3 4 5))
(define list4 (list 1 2 3 4 5))

(reverse!!1 list1)
(take!!1 list2 3)
(map!!2 + list3 (make-list 5 1))
(map!!3 + (make-list 5 1) list4)

(print list1)
(print list2)
(print list3)
(print list4)

hamayama(2018/11/09 12:10:12 UTC)(2018/11/11 08:35:16 UTC)

More ...