structure.hl.rkt (3928B)
1 #lang hyper-literate typed/racket/base #:no-require-lang #:no-auto-require 2 @(require racket/require 3 scribble-math 4 scribble-enhanced/doc 5 (for-label phc-toolkit 6 (lib "phc-adt/tagged.hl.rkt") 7 multi-id 8 racket/base 9 phc-toolkit/untyped-only)) 10 @doc-lib-setup 11 12 @(unless-preexpanding 13 (require (for-label (submod "..")))) 14 15 @title[#:style (with-html5 manual-doc-style) 16 #:tag "structure" 17 #:tag-prefix "phc-adt/structure" 18 ]{User API for untagged structures} 19 20 @(chunks-toc-prefix 21 '("(lib phc-adt/scribblings/phc-adt-implementation.scrbl)" 22 "phc-adt/structure")) 23 24 @(table-of-contents) 25 26 @section{Introduction} 27 28 Untagged structures are implemented exactly like @racket[tagged] structures, 29 except that they always use the @racket[untagged] tag name. 30 31 @chunk[<structure> 32 (define-multi-id structure 33 #:type-expander <expand-to-tagged> 34 #:match-expander <expand-to-tagged> 35 #:call <expand-to-tagged>)] 36 37 All three cases simply expand to 38 @racket[(tagged untagged . _original-arguments)]. 39 40 @chunk[<expand-to-tagged> 41 (λ/syntax-case (_ . _original-arguments) () 42 (syntax/top-loc stx 43 (tagged untagged . _original-arguments)))] 44 45 The @racket[structure?] predicate is implemented in the same way: 46 47 @chunk[<structure?> 48 (define-syntax structure? 49 (λ/syntax-case (_ . _original-arguments) () 50 (syntax/top-loc stx 51 (tagged? untagged . _original-arguments))))] 52 53 @section{Defining untagged structures with @racket[define-structure]} 54 55 The @racket[define-structure] expands to the 56 @racket[(define-tagged #:tag untagged . _original-arguments)], which uses 57 @racket[define-tagged] but forces the tag name to be @racket[untagged]. 58 59 @chunk[<define-structure> 60 (define-syntax/case (define-structure . _original-arguments) () 61 (syntax/top-loc stx 62 (define-tagged #:tag untagged . _original-arguments)))] 63 64 @section{Implementation of @racket[StructureTop] and @racket[StructureTop?]} 65 66 The @racket[StructureTop?] predicate is defined in terms of 67 @racket[tagged-any-fields-predicate]: 68 69 @CHUNK[<StructureTop?> 70 (define-syntax StructureTop? 71 (make-id+call-transformer-delayed 72 (λ () (tagged-any-fields-predicate #'untagged))))] 73 74 Similarly, the @racket[StructureTop] type is defined using 75 @racket[tagged-any-fields-type]: 76 77 @CHUNK[<StructureTop> 78 (define-type-expander (StructureTop stx) 79 (syntax-case stx () 80 [id 81 (identifier? #'id) 82 (tagged-any-fields-type #'untagged)]))] 83 84 @section{Supertypes for structures} 85 86 Like the @racket[structure] and @racket[structure?] identifiers, 87 @racket[structure-supertype] is defined in terms of its tagged structure 88 counterpart, @racket[tagged-supertype]: 89 90 @chunk[<structure-supertype> 91 (define-multi-id structure-supertype 92 #:type-expander <expand-to-tagged-supertype> 93 #:match-expander <expand-to-tagged-supertype>)] 94 95 @chunk[<expand-to-tagged-supertype> 96 (λ/syntax-case (_ . _original-arguments) () 97 (syntax/top-loc stx 98 (tagged-supertype untagged . _original-arguments)))] 99 100 @section{Putting it all together} 101 102 @chunk[<*> 103 (require phc-toolkit 104 "tagged.hl.rkt" 105 "tagged-structure-low-level.hl.rkt" 106 "tagged-supertype.hl.rkt" 107 multi-id 108 type-expander 109 (for-syntax racket/base 110 phc-toolkit/untyped)) 111 112 (provide structure 113 structure? 114 define-structure 115 StructureTop 116 StructureTop? 117 structure-supertype) 118 119 <structure> 120 <structure?> 121 <define-structure> 122 <StructureTop> 123 <StructureTop?> 124 <structure-supertype>]