typed-struct-props.scrbl (4317B)
1 #lang scribble/manual 2 @require[@for-label[typed-struct-props 3 racket/base]] 4 5 @title{Struct type properties for Typed/Racket} 6 @author[@author+email["Suzanne Soy" "racket@suzanne.soy"]] 7 8 @defmodule[typed-struct-props] 9 10 @defform[#:literals (: prop:custom-write prop:equal+hash) 11 (struct/props maybe-type-vars name maybe-parent ([field : type] ...) 12 options ...) 13 #:grammar 14 [(maybe-type-vars (code:line) 15 (v ...)) 16 (maybe-parent (code:line) 17 parent-id) 18 (options #:transparent 19 (code:line #:property prop:custom-write custom-write) 20 (code:line #:property prop:equal+hash equal+hash))] 21 #:contracts ([custom-write 22 (→ name (code:comment "non-polymorphic case") 23 Output-Port 24 (U #t #f 0 1) 25 Any)] 26 [custom-write 27 (∀ (v ...) (code:comment "polymorphic case") 28 (→ (name v ...) 29 Output-Port 30 (U #t #f 0 1) 31 Any))] 32 [equal+hash 33 (List (→ name (code:comment "non-polymorphic case") 34 name 35 (→ Any Any Boolean) 36 Any) 37 (→ v 38 (→ Any Integer) 39 Integer) 40 (→ v 41 (→ Any Integer) 42 Integer))] 43 [equal+hash 44 (List (∀ (v ... v2 ...) (code:comment "polymorphic case") 45 (→ (name v ...) 46 (name v2 ...) 47 (→ Any Any Boolean) 48 Any)) 49 (∀ (v ...) 50 (→ (name v ...) 51 (→ Any Integer) 52 Integer)) 53 (∀ (v ...) 54 (→ (name v ...) 55 (→ Any Integer) 56 Integer)))])]{ 57 This form defines a @racketmodname[typed/racket] struct type, and accepts a 58 small subset of @racketmodname[racket]'s struct type properties. 59 60 For @racket[prop:custom-write] and @racket[prop:equal+hash], the function 61 types are polymorphic only if the struct is polymorphic (i.e. 62 @racket[maybe-type-vars] is present) and has at least one type variable (i.e. 63 @racket[maybe-type-vars] is not just @racket[()]). 64 65 It implements these struct type properties in a type-safe manner: the current 66 implementation in @racketmodname[typed/racket] does not properly type-check 67 functions and values used as struct type properties. This library declares the 68 user-provided functions outside of the struct definition, with the type given 69 above (e.g. 70 @racket[(∀ (v ...) (→ (name v ...) Output-Port (U #t #f 0 1) Any))] for the 71 argument of the @racket[prop:custom-write] property), to ensure that these 72 functions and values are properly checked. 73 74 The API should (hopefully) stay backward-compatible when Typed/Racket 75 officially supports (or rejects) structure type properties. In other words: 76 @itemlist[ 77 @item{If @racketmodname[typed/racket] eventually implements the same interface 78 as the one provided by this library, then we will update this library so 79 that it simply re-provide @racket[struct] renamed as @racket[struct/props].} 80 @item{If @racketmodname[typed/racket] eventually implements some type-safe 81 struct type properties, then we will update this library will so that it 82 translates back to @racketmodname[typed/racket]'s implementation, as much as 83 possible.} 84 @item{If @racketmodname[typed/racket] eventually disallows struct type 85 properties, then we will update this library so that it uses some 86 @racketmodname[typed/racket/unsafe] tricks to still make them available, if 87 it can be done.}]}