レコード型の詳細を隠蔽する


Tags: R6RS, レコード

define-record-type 中で opaque 属性に #t を指定するとそのレコード型は不透明になり、ために、 record-rtd 手続きに対して例外を発生させるようになり、事実上 (rnrs records inspection) ライブラリの手続きが適用できなくなる。

(import (rnrs))

(define-record-type point
  (opaque #t)
  (fields
   (mutable x)
   (mutable y)))

(define p (make-point 0 0))

(record? p) ; => #f
(record-rtd p) ; => &assertion

一方で、 (rnrs records syntactic) の record-type-descriptor 構文を用いれば、不透明な構造体からもレコード型記述子を取り出せるため、レコード型の詳細を完全に隠蔽するためには構造体名をライブラリを使って非公開にしなければならない。

(import (rnrs))

(define-record-type point
  (opaque #t)
  (fields
   (mutable x)
   (mutable y)))

(define p (make-point 0 0))

(record-type-name (record-type-descriptor point)) ; => point
(library (foo)
  (export make-point) ; not export record type name
  (import (rnrs))

  (define-record-type point
    (opaque #t)
    (fields
     (mutable x)
     (mutable y)))
  )

(import (rnrs) (foo))

(define p (make-point 0 0))

(record-type-name
 (record-type-descriptor point) ; => &syntax
 )