Struct type properties for Typed/  Racket
struct/  props
6.12

Struct type properties for Typed/Racket

Georges Dupéron <[email protected]>

 (require typed-struct-props)
  package: typed-struct-props

syntax

(struct/props maybe-type-vars name maybe-parent ([field : type] ...)
              options ...)
 
maybe-type-vars = 
  | (v ...)
     
maybe-parent = 
  | parent-id
     
options = #:transparent
  | #:property prop:custom-write custom-write
  | #:property prop:equal+hash equal+hash
 
  custom-write : 
( name                    ; non-polymorphic case
   Output-Port
   (U #t #f 0 1)
   Any)
  custom-write : 
( (v ...)                 ; polymorphic case
   ( (name v ...)
      Output-Port
      (U #t #f 0 1)
      Any))
  equal+hash : 
(List ( name                ; non-polymorphic case
         name
         ( Any Any Boolean)
         Any)
      ( v
         ( Any Integer)
         Integer)
      ( v
         ( Any Integer)
         Integer))
  equal+hash : 
(List ( (v ... v2 ...)      ; polymorphic case
         ( (name v ...)
            (name v2 ...)
            ( Any Any Boolean)
            Any))
      ( (v ...)
         ( (name v ...)
            ( Any Integer)
            Integer))
      ( (v ...)
         ( (name v ...)
            ( Any Integer)
            Integer)))
This form defines a typed/racket struct type, and accepts a small subset of racket’s struct type properties.

For prop:custom-write and prop:equal+hash, the function types are polymorphic only if the struct is polymorphic (i.e. maybe-type-vars is present) and has at least one type variable (i.e. maybe-type-vars is not just ()).

It implements these struct type properties in a type-safe manner: the current implementation in typed/racket does not properly type-check functions and values used as struct type properties. This library declares the user-provided functions outside of the struct definition, with the type given above (e.g. ( (v ...) ( (name v ...) Output-Port (U #t #f 0 1) Any)) for the argument of the prop:custom-write property), to ensure that these functions and values are properly checked.

The API should (hopefully) stay backward-compatible when Typed/Racket officially supports (or rejects) structure type properties. In other words:
  • If typed/racket eventually implements the same interface as the one provided by this library, then we will update this library so that it simply re-provide struct renamed as struct/props.

  • If typed/racket eventually implements some type-safe struct type properties, then we will update this library will so that it translates back to typed/racket’s implementation, as much as possible.

  • If typed/racket eventually disallows struct type properties, then we will update this library so that it uses some typed/racket/unsafe tricks to still make them available, if it can be done.