SRFI-99

Changes On Branch chicken-5
Login

Many hyperlinks are disabled.
Use anonymous login to enable hyperlinks.

Changes In Branch chicken-5 Excluding Merge-Ins

This is equivalent to a diff from d3622ab6b3 to 6cd10267ff

2018-08-18
00:14
Cleanup files, set version Leaf check-in: 6cd10267ff user: murphy tags: chicken-5, v1.4.5
2018-08-14
11:27
Added imports for extend-procedure and procedure-data, re-enabled tests check-in: 6e33be7cc6 user: murphy tags: chicken-5
2018-06-19
21:29
Port the egg to CHICKEN 5 check-in: adfc004653 user: kooda tags: chicken-5
2017-09-01
11:58
Point release-info to main repository Leaf check-in: d3622ab6b3 user: murphy tags: trunk
2017-02-23
18:34
Point release-info to chisel mirror check-in: b27df4d42d user: murphy tags: trunk

Added srfi-99.egg.

























>
>
>
>
>
>
>
>
>
>
>
>
1
2
3
4
5
6
7
8
9
10
11
12
((version "1.4.5")
 (category data)
 (license "BSD")
 (author "Thomas Chust")
 (synopsis "SRFI-99 record types")
 (dependencies srfi-1 srfi-69 miscmacros)
 (test-dependencies test)
 (components
   (extension srfi-99
     (modules srfi-99-primitives srfi-99-records-procedural
              srfi-99-records-inspection srfi-99-records-syntactic
              srfi-99-records srfi-99-variants srfi-99))))

Deleted srfi-99.meta.

1
2
3
4
5
6
7
8
9
;; -*- mode: Scheme; -*-
((category data)
 (license "BSD")
 (author "Thomas Chust")
 (synopsis "SRFI-99 record types")
 (doc-from-wiki)
 (needs)
 (test-depends test)
 (files "srfi-99.scm"))
<
<
<
<
<
<
<
<
<


















Changes to srfi-99.release-info.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
;; -*- mode: Scheme; -*-
(repo fossil "https://chust.org/repos/chicken-{egg-name}")

(uri targz "https://chust.org/repos/chicken-{egg-name}/tarball/{egg-name}.tar.gz?uuid=v{egg-release}")
(release "1.4.4")
(release "1.4.3")
(release "1.4.2")
(release "1.4.1")
(release "1.4.0")
(release "1.3.0")
(release "1.2.0")
(release "1.1.1")
(release "1.1.0")
(release "1.0.0")




|
<
<
<
<
<
<
<
<
<
1
2
3
4
5









;; -*- mode: Scheme; -*-
(repo fossil "https://chust.org/repos/chicken-{egg-name}")

(uri targz "https://chust.org/repos/chicken-{egg-name}/tarball/{egg-name}.tar.gz?uuid=v{egg-release}")
(release "1.4.5")









Changes to srfi-99.scm.

19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37





38
39
40
41
42
43
44
;; MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
;; NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
;; BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
;; ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
;; CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
;; SOFTWARE.

(require-library
 srfi-1 srfi-69
 data-structures lolevel)

(module srfi-99-primitives
  (%make-rtd %get-rtd rtd? record?
   %rtd-name %rtd-uid %rtd-child-uids %rtd-fields %rtd-parent %rtd-properties
   %rtd-child-uid?
   %rtd-count-fields %rtd-count-all-fields
   %rtd-field-ref %rtd-field-find)
  (import
   scheme chicken





   srfi-69)

(define-values (%make-rtd %get-rtd)
  (letrec ((%link!
	    (lambda (rtd)
	      (do ((rtd rtd (%rtd-parent rtd)) (uid (%rtd-uid rtd))) ((not rtd))
		(cond







<
<
<
<







|
>
>
>
>
>







19
20
21
22
23
24
25




26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
;; MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
;; NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
;; BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
;; ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
;; CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
;; SOFTWARE.





(module srfi-99-primitives
  (%make-rtd %get-rtd rtd? record?
   %rtd-name %rtd-uid %rtd-child-uids %rtd-fields %rtd-parent %rtd-properties
   %rtd-child-uid?
   %rtd-count-fields %rtd-count-all-fields
   %rtd-field-ref %rtd-field-find)
  (import
   scheme
   (chicken base)
   (chicken fixnum)
   (chicken plist)
   (chicken gc)
   miscmacros
   srfi-69)

(define-values (%make-rtd %get-rtd)
  (letrec ((%link!
	    (lambda (rtd)
	      (do ((rtd rtd (%rtd-parent rtd)) (uid (%rtd-uid rtd))) ((not rtd))
		(cond
111
112
113
114
115
116
117
118

119
120
121
122
123
124
125
126

)

(module srfi-99-records-procedural
  (make-rtd rtd?
   rtd-constructor rtd-predicate rtd-accessor rtd-mutator)
  (import
   scheme chicken

   srfi-1 srfi-69 srfi-99-primitives data-structures)

(define (make-rtd name fields . args)
  (let-values (((fields)
		(list->vector
		 (map
		  (lambda (field)
		    (cond







|
>
|







112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128

)

(module srfi-99-records-procedural
  (make-rtd rtd?
   rtd-constructor rtd-predicate rtd-accessor rtd-mutator)
  (import
   scheme (chicken base) (chicken fixnum)
   miscmacros
   srfi-1 srfi-69 srfi-99-primitives)

(define (make-rtd name fields . args)
  (let-values (((fields)
		(list->vector
		 (map
		  (lambda (field)
		    (cond
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266

(module srfi-99-records-inspection
  (record? record-rtd
   rtd-name rtd-uid rtd-sealed? rtd-opaque? rtd-parent
   rtd-field-names rtd-all-field-names rtd-field-mutable?
   make-rtp rtd-properties rtd-all-properties)
  (import
   scheme chicken
   srfi-1 srfi-69 srfi-99-primitives srfi-99-records-procedural data-structures)

(define (record-rtd v)
  (and (record? v)
       (%get-rtd (##sys#slot v 0))))

(define (rtd-name rtd)
  (##sys#check-structure rtd 'rtd 'rtd-name)







|
|







253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268

(module srfi-99-records-inspection
  (record? record-rtd
   rtd-name rtd-uid rtd-sealed? rtd-opaque? rtd-parent
   rtd-field-names rtd-all-field-names rtd-field-mutable?
   make-rtp rtd-properties rtd-all-properties)
  (import
   scheme (chicken base) (chicken fixnum)
   srfi-1 srfi-69 srfi-99-primitives srfi-99-records-procedural)

(define (record-rtd v)
  (and (record? v)
       (%get-rtd (##sys#slot v 0))))

(define (rtd-name rtd)
  (##sys#check-structure rtd 'rtd 'rtd-name)
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
   define-record-predicate
   %define-record-predicate/default
   define-record-field
   %define-record-field/mutable-default %define-record-field/immutable-default
   define-record-property
   define-record-printer)
  (import
   scheme (except chicken define-record-type define-record-printer)
   srfi-99-records-procedural)

(define-syntax %define-record-constructor/default
  (ir-macro-transformer
   (lambda (stx inject id=)
     (let* ((rtd (cadr stx))
	    (name (symbol-append 'make- (strip-syntax rtd))))







|







355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
   define-record-predicate
   %define-record-predicate/default
   define-record-field
   %define-record-field/mutable-default %define-record-field/immutable-default
   define-record-property
   define-record-printer)
  (import
   scheme (except (chicken base) define-record-type define-record-printer)
   srfi-99-records-procedural)

(define-syntax %define-record-constructor/default
  (ir-macro-transformer
   (lambda (stx inject id=)
     (let* ((rtd (cadr stx))
	    (name (symbol-append 'make- (strip-syntax rtd))))
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496


497

498
499
500
501
502
503
504
505
     (##sys#register-record-printer (rtd-uid rtd) expr))))

)

(module srfi-99-records
  ()
  (import
   scheme chicken)
  (reexport
   srfi-99-records-procedural srfi-99-records-inspection
   srfi-99-records-syntactic)

)

(module srfi-99-variants
  (define-variant-type
   define-variant-constructor
   variant-case)
  (import


   scheme (except chicken define-record-type)

   srfi-99-records lolevel)

(define-syntax define-variant-type
  (syntax-rules ()
    ((define-variant-type (rtd option ...) predicate
       (variant field ...)
       ...)
     (begin







|











>
>
|
>
|







480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
     (##sys#register-record-printer (rtd-uid rtd) expr))))

)

(module srfi-99-records
  ()
  (import
   scheme (chicken base) (chicken module))
  (reexport
   srfi-99-records-procedural srfi-99-records-inspection
   srfi-99-records-syntactic)

)

(module srfi-99-variants
  (define-variant-type
   define-variant-constructor
   variant-case)
  (import
   scheme
   (chicken module)
   (except (chicken base) define-record-type)
   (only (chicken memory representation) extend-procedure procedure-data)
   miscmacros srfi-99-records)

(define-syntax define-variant-type
  (syntax-rules ()
    ((define-variant-type (rtd option ...) predicate
       (variant field ...)
       ...)
     (begin
561
562
563
564
565
566
567
568
569
570
571
572
	(error "no matching variant"))))))

)

(module srfi-99
  ()
  (import
   scheme chicken)
  (reexport
   srfi-99-records srfi-99-variants)

)







|




566
567
568
569
570
571
572
573
574
575
576
577
	(error "no matching variant"))))))

)

(module srfi-99
  ()
  (import
   scheme (chicken base) (chicken module))
  (reexport
   srfi-99-records srfi-99-variants)

)

Deleted srfi-99.setup.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
;; -*- mode: Scheme; -*-
(compile -s -O2 -d1 "srfi-99.scm"
	 -j srfi-99
	 -j srfi-99-primitives
	 -j srfi-99-records
	 -j srfi-99-records-procedural
	 -j srfi-99-records-inspection
	 -j srfi-99-records-syntactic
	 -j srfi-99-variants)

(cond-expand
 (enable-static
  (compile -c -O2 -d1 "srfi-99.scm"
	   -unit srfi-99))
 (else
  ))

(compile -s -O2 -d0 "srfi-99.import.scm")
(compile -s -O2 -d0 "srfi-99-primitives.import.scm")
(compile -s -O2 -d0 "srfi-99-records.import.scm")
(compile -s -O2 -d0 "srfi-99-records-procedural.import.scm")
(compile -s -O2 -d0 "srfi-99-records-inspection.import.scm")
(compile -s -O2 -d0 "srfi-99-records-syntactic.import.scm")
(compile -s -O2 -d0 "srfi-99-variants.import.scm")

(install-extension
 'srfi-99
 `("srfi-99.so"
   ,@(cond-expand
      (enable-static
       '("srfi-99.o"))
      (else
       '()))
   "srfi-99.import.so"
   "srfi-99-primitives.import.so"
   "srfi-99-records.import.so"
   "srfi-99-records-procedural.import.so"
   "srfi-99-records-inspection.import.so"
   "srfi-99-records-syntactic.import.so"
   "srfi-99-variants.import.so")
 `((version "1.4.4")
   ,@(cond-expand
      (enable-static
       '((static "srfi-99.o")))
      (else
       '()))))
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<




























































































Deleted test/run.scm.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
;; -*- mode: Scheme; -*-
;;
;; This file is part of SRFI-99 for CHICKEN
;; Copyright (c) 2011 by Thomas Chust.  All rights reserved.
;;
;; Permission is hereby granted, free of charge, to any person
;; obtaining a copy of this software and associated documentation
;; files (the Software), to deal in the Software without restriction,
;; including without limitation the rights to use, copy, modify,
;; merge, publish, distribute, sublicense, and/or sell copies of the
;; Software, and to permit persons to whom the Software is furnished
;; to do so, subject to the following conditions:
;; 
;; The above copyright notice and this permission notice shall be
;; included in all copies or substantial portions of the Software.
;; 
;; THE SOFTWARE IS PROVIDED ASIS, WITHOUT WARRANTY OF ANY KIND,
;; EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
;; MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
;; NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
;; BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
;; ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
;; CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
;; SOFTWARE.

(require-extension
 srfi-99 test)

(test-group "procedural layer"

  (test-group "RTD creation"
    (test-assert "null record" (rtd? (make-rtd 'foo '#())))
    (test-error "bad name" (make-rtd 42 '#()))
    (test-error "bad fields" (make-rtd 'foo '#((murks quark))))
    (test-error "bad parent" (make-rtd 'foo '#() 'murks)))

  (test-group "RTD properties"
    (test "type name" 'foo (rtd-name (make-rtd 'foo '#())))
    (test "type UID" 'bar (rtd-uid (make-rtd 'foo '#() #f #:uid 'bar)))
    (test "unsealed type" #f (rtd-sealed? (make-rtd 'foo '#() #f)))
    (test "sealed type" #t (rtd-sealed? (make-rtd 'foo '#() #f #:sealed #t)))
    (test "transparent type" #f (rtd-opaque? (make-rtd 'foo '#() #f)))
    (test "opaque type" #t (rtd-opaque? (make-rtd 'foo '#() #f #:opaque #t)))
    (test "implicit immutable field" #f (rtd-field-mutable? (make-rtd 'foo '#(x)) 'x))
    (test "explicit immutable field" #f (rtd-field-mutable? (make-rtd 'foo '#((immutable x))) 'x))
    (test "implicit mutable field" #t (rtd-field-mutable? (make-rtd 'foo '#((x))) 'x))
    (test "explicit mutable field" #t (rtd-field-mutable? (make-rtd 'foo '#((mutable x))) 'x)))

  (test-group "RTD instances"
    (let ((t (make-rtd 'foo '#(x (y)))))
      (define make-t (rtd-constructor t))
      (define t? (rtd-predicate t))
      (define t-x (rtd-accessor t 'x))
      (define t-y (rtd-accessor t 'y))
      (test "instance detection" #t (t? (make-t 1 2)))
      (test "non-instance detection" #f (t? 'foo))
      (test "field access" 42 (t-x (make-t 42 23)))
      (test "field mutation" 23 (let ((r (make-t 42 0))) (set! (t-y r) 23) (t-y r)))
      (test-error "disallowed field mutation" (set! (t-x (make-t 42 23)) 0))))

  (test-group "RTD inheritance"
    (let* ((t0 (make-rtd 'foo '#(x y)))
	   (t1 (make-rtd 'bar '#(z) t0 #:sealed #t)))
      (define make-t1 (rtd-constructor t1 '#()))
      (define t0? (rtd-predicate t0))
      (define t1? (rtd-predicate t1))
      (test "direct field enumeration" '#(z) (rtd-field-names t1))
      (test "full field enumeration" '#(x y z) (rtd-all-field-names t1))
      (test "direct instance detection" #t (t1? (make-t1)))
      (test "indirect instance detection" #t (t0? (make-t1)))
      (test-error "disallowed derivation" (make-rtd 'baz '#() t1))))
  
  (test-group "properties"
    (let* ((p0 (make-rtp 42))
	   (p1 (make-rtp))
	   (t0 (make-rtd 'foo '#(x) #:property p0 23))
	   (t1 (make-rtd 'bar '#(y) t0 #:property p1 'y)))
      (define make-t0 (rtd-constructor t0 '#(x)))
      (define make-t1 (rtd-constructor t1 '#(y)))
      (test "direct type property access" 23 (p0 #f t0))
      (test "derived type property access" 23 (p0 #f t1))
      (test "direct instance property access" 23 (p0 (make-t0 1)))
      (test "derived instance property access" 23 (p0 (make-t1 1)))
      (test-error "illegal field property access" (p1 #f t1))
      (test "field property access" 2 (p1 (make-t1 2)))))

)

(test-group "syntactic layer" (let ()

  (define-record-type foo
    #t #t
    x (y))
  
  (test-assert "RTD" (rtd? foo))
  (test-assert "constructor" (procedure? make-foo))
  (test-assert "predicate" (procedure? foo?))
  (test-assert "immutable accessor" (procedure? foo-x))
  (test-assert "mutable accessor" (procedure? foo-y))
  (test-assert "mutable mutator" (procedure? foo-y-set!))
  (test-assert "mutable accessor setter" (procedure? (setter foo-y)))

))

(test-group "variants" (let ()

  (define-variant-type foo
    #t
    (foobar x)
    (foobaz x y))
  
  (test-assert "RTD" (rtd? foo))
  (test-assert "predicate" (procedure? foo?))
  (test-assert "variant constructors" (every procedure? (list foobar foobaz)))
  (test-assert "variant RTDs" (every rtd? (map procedure-data (list foobar foobaz))))
  (test "variant extraction" 2 (variant-case foo (foobaz 1 2)
				 ((foobar x) x)
				 ((foobaz y) y)))
  (test "else clause" 42 (variant-case foo (foobaz 1 2)
			   ((foobar x) x)
			   (else 42)))
  (test-error "match error" (variant-case foo (foobaz 1 2)
			      ((foobar x) x)))

))
	 
(test-exit)
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<






























































































































































































































































Added tests/run.scm.

































































































































































































































































>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
;; -*- mode: Scheme; -*-
;;
;; This file is part of SRFI-99 for CHICKEN
;; Copyright (c) 2011 by Thomas Chust.  All rights reserved.
;;
;; Permission is hereby granted, free of charge, to any person
;; obtaining a copy of this software and associated documentation
;; files (the Software), to deal in the Software without restriction,
;; including without limitation the rights to use, copy, modify,
;; merge, publish, distribute, sublicense, and/or sell copies of the
;; Software, and to permit persons to whom the Software is furnished
;; to do so, subject to the following conditions:
;; 
;; The above copyright notice and this permission notice shall be
;; included in all copies or substantial portions of the Software.
;; 
;; THE SOFTWARE IS PROVIDED ASIS, WITHOUT WARRANTY OF ANY KIND,
;; EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
;; MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
;; NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
;; BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
;; ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
;; CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
;; SOFTWARE.

(import
 (only (chicken memory representation) procedure-data)
 srfi-1 srfi-99 test)

(test-group "procedural layer"

  (test-group "RTD creation"
    (test-assert "null record" (rtd? (make-rtd 'foo '#())))
    (test-error "bad name" (make-rtd 42 '#()))
    (test-error "bad fields" (make-rtd 'foo '#((murks quark))))
    (test-error "bad parent" (make-rtd 'foo '#() 'murks)))

  (test-group "RTD properties"
    (test "type name" 'foo (rtd-name (make-rtd 'foo '#())))
    (test "type UID" 'bar (rtd-uid (make-rtd 'foo '#() #f #:uid 'bar)))
    (test "unsealed type" #f (rtd-sealed? (make-rtd 'foo '#() #f)))
    (test "sealed type" #t (rtd-sealed? (make-rtd 'foo '#() #f #:sealed #t)))
    (test "transparent type" #f (rtd-opaque? (make-rtd 'foo '#() #f)))
    (test "opaque type" #t (rtd-opaque? (make-rtd 'foo '#() #f #:opaque #t)))
    (test "implicit immutable field" #f (rtd-field-mutable? (make-rtd 'foo '#(x)) 'x))
    (test "explicit immutable field" #f (rtd-field-mutable? (make-rtd 'foo '#((immutable x))) 'x))
    (test "implicit mutable field" #t (rtd-field-mutable? (make-rtd 'foo '#((x))) 'x))
    (test "explicit mutable field" #t (rtd-field-mutable? (make-rtd 'foo '#((mutable x))) 'x)))

  (test-group "RTD instances"
    (let ((t (make-rtd 'foo '#(x (y)))))
      (define make-t (rtd-constructor t))
      (define t? (rtd-predicate t))
      (define t-x (rtd-accessor t 'x))
      (define t-y (rtd-accessor t 'y))
      (test "instance detection" #t (t? (make-t 1 2)))
      (test "non-instance detection" #f (t? 'foo))
      (test "field access" 42 (t-x (make-t 42 23)))
      (test "field mutation" 23 (let ((r (make-t 42 0))) (set! (t-y r) 23) (t-y r)))
      (test-error "disallowed field mutation" (set! (t-x (make-t 42 23)) 0))))

  (test-group "RTD inheritance"
    (let* ((t0 (make-rtd 'foo '#(x y)))
	   (t1 (make-rtd 'bar '#(z) t0 #:sealed #t)))
      (define make-t1 (rtd-constructor t1 '#()))
      (define t0? (rtd-predicate t0))
      (define t1? (rtd-predicate t1))
      (test "direct field enumeration" '#(z) (rtd-field-names t1))
      (test "full field enumeration" '#(x y z) (rtd-all-field-names t1))
      (test "direct instance detection" #t (t1? (make-t1)))
      (test "indirect instance detection" #t (t0? (make-t1)))
      (test-error "disallowed derivation" (make-rtd 'baz '#() t1))))
  
  (test-group "properties"
    (let* ((p0 (make-rtp 42))
	   (p1 (make-rtp))
	   (t0 (make-rtd 'foo '#(x) #:property p0 23))
	   (t1 (make-rtd 'bar '#(y) t0 #:property p1 'y)))
      (define make-t0 (rtd-constructor t0 '#(x)))
      (define make-t1 (rtd-constructor t1 '#(y)))
      (test "direct type property access" 23 (p0 #f t0))
      (test "derived type property access" 23 (p0 #f t1))
      (test "direct instance property access" 23 (p0 (make-t0 1)))
      (test "derived instance property access" 23 (p0 (make-t1 1)))
      (test-error "illegal field property access" (p1 #f t1))
      (test "field property access" 2 (p1 (make-t1 2)))))

)

(test-group "syntactic layer" (let ()

  (define-record-type foo
    #t #t
    x (y))
  
  (test-assert "RTD" (rtd? foo))
  (test-assert "constructor" (procedure? make-foo))
  (test-assert "predicate" (procedure? foo?))
  (test-assert "immutable accessor" (procedure? foo-x))
  (test-assert "mutable accessor" (procedure? foo-y))
  (test-assert "mutable mutator" (procedure? foo-y-set!))
  (test-assert "mutable accessor setter" (procedure? (setter foo-y)))

))

(test-group "variants" (let ()

  (define-variant-type foo
    #t
    (foobar x)
    (foobaz x y))
  
  (test-assert "RTD" (rtd? foo))
  (test-assert "predicate" (procedure? foo?))
  (test-assert "variant constructors" (every procedure? (list foobar foobaz)))
  (test-assert "variant RTDs" (every rtd? (map procedure-data (list foobar foobaz))))
  (test "variant extraction" 2 (variant-case foo (foobaz 1 2)
				 ((foobar x) x)
				 ((foobaz y) y)))
  (test "else clause" 42 (variant-case foo (foobaz 1 2)
			   ((foobar x) x)
			   (else 42)))
  (test-error "match error" (variant-case foo (foobaz 1 2)
			      ((foobar x) x)))

))
	 
(test-exit)