Gauche:immutableなデータの注意点

Gauche:immutableなデータの注意点

immutableなデータの注意点

Gauche 0.9.10 から、immutable なペアについては、変更するとエラーが出るようになりました。
( https://practical-scheme.net/gauche/man/?l=jp&p=変更可能なペアと変更不可なペア )
このため、以下の説明は、もう古いものとなっています。
(ただし、ベクタ等、他のリテラル定数については、まだ注意が必要なものも存在します)
(2020/12/30 11:46:36 UTC)


例1. リテラル定数

;; リテラルを破壊的変更している例 (悪い例)
(define x '(1 2 3 4 5))
(define y '(1 2 3 4 5))
(set-car! y 100)
(print x) ; -> (1 2 3 4 5)   ? (結果は保証されない)
(print y) ; -> (100 2 3 4 5) ? (結果は保証されない)
;; リテラルを使わない(コンストラクタを使う)例
(define x (list 1 2 3 4 5))
(define y (list 1 2 3 4 5))
(set-car! y 100)
(print x) ; -> (1 2 3 4 5)
(print y) ; -> (100 2 3 4 5)
;; (リテラルの)破壊的変更を使わない例
(define x '(1 2 3 4 5))
(define y '(1 2 3 4 5))
(set! y (cons 100 (cdr y)))
(print x) ; -> (1 2 3 4 5)
(print y) ; -> (100 2 3 4 5)
;; mutable なコピーを取得する例
(define x '(1 2 3 4 5))
(define y '(1 2 3 4 5))
(set! y (list-copy y))
(set-car! y 100)
(print x) ; -> (1 2 3 4 5)
(print y) ; -> (100 2 3 4 5)
(define (foo x)
  (define p '(head . tail))
  (set-cdr! p x)
  (cdr p))

(foo 'newtail) ; -> tail   ; newtailにならない

例2. ライブラリの手続き

;; append の戻り値を破壊的変更している例 (悪い例)
(define x (list 3 4 5))
(define y (append (list 1 2) x))
(list-set! y 2 300)
(print x) ; -> (300 4 5)
(print y) ; -> (1 2 300 4 5)
;; append の戻り値をコピーしてから破壊的変更する例
(define x (list 3 4 5))
(define y (append (list 1 2) x))
(set! y (list-copy y))
(list-set! y 2 300)
(print x) ; -> (3 4 5)
(print y) ; -> (1 2 300 4 5)

まとめ/関連情報

hamayama(2018/08/24 12:19:28 UTC)(2018/08/25 05:43:17 UTC)
(2018/08/26 06:41:16 UTC)(2018/08/28 06:03:54 UTC)
(2020/12/30 11:46:36 UTC)

More ...