hash-view:   Struct-like Views of Hashes
1 Introduction to Hash Views
2 Hash Views

hash-view: Struct-like Views of Hashes

Ryan Culpepper <ryanc@racket-lang.org>

 (require hash-view) package: hash-view-lib

This library provides a form for declaring a struct-like interface to hashes with symbol keys.

1 Introduction to Hash Views

A hash view is declared like this:
> (hash-view point (x y))

This declares a constructor and match pattern point, a predicate point?, and accessors point-x and point-y.

Instances of points are represented by hashes with symbol keys:
> (point 1 2)

'#hasheq((x . 1) (y . 2))

> (point? (point 1 2))


> (point? 12)


All of the (required) fields must be present to satisfy the predicate. Additional keys are allowed and ignored.
> (point? (hasheq 'x 1))


> (point? (hash 'x 1 'y 2 'z 3))


The hash-view name also acts as a match pattern:
> (match (hasheq 'x 1 'y 2 'z 3)
    [(point x y) (+ x y)])


A hash-view declaration can include optional fields with default values. Fields declared with #:default are included by the constructor, but fields declared with #:default/omit are omitted when they have their default values.
> (hash-view location (host [port #:default 80] [proto #:default/omit 'tcp]))
> (location "racket-lang.org")

'#hasheq((host . "racket-lang.org") (port . 80))

> (location "racket-lang.org" 80 'tcp)

'#hasheq((host . "racket-lang.org") (port . 80))

> (location "docs.racket-lang.org" 443)

'#hasheq((host . "docs.racket-lang.org") (port . 443))

> (location "localhost" 20 'udp)

'#hasheq((host . "localhost") (port . 20) (proto . udp))

An optional field’s accessor normally returns the declared default if the field is missing:
> (location-port (hasheq 'host "racket-lang.org"))


> (match (hasheq 'host "racket-lang.org")
    [(location host port _) (format "~a:~a" host port)])


But if the accessor is given a second argument, that argument replaces the default failure argument to hash-ref:
> (location-port (hasheq 'host "racket-lang.org")


> (location-port (hasheq 'host "racket-lang.org")
                 (lambda () (printf "port missing!\n")))

port missing!

2 Hash Views


(hash-view view-id (field-decl ...) maybe-mutability)

field-decl = field-id
  | [field-id #:default default-expr]
  | [field-id #:default/omit default-expr]
maybe-mutability = 
  | #:immutable
  | #:accept-mutable
Similar to (struct view-id (field-id ...)), but represents view-id instances as hashes with symbol keys ('field-id).

Defines view-id as a constructor and match pattern, view-id? as a predicate, and the view-id-field-id identifiers as accessors.

The view-id constructor always creates immutable eq?-based hashes (hasheq), but the predicate and accessors also accept eqv?-based and equal?-based hashes (hasheqv and hash). The predicate and accessors accept hashes that have additional keys.

If a field has a default value, then it is an optional field: the predicate does not check for its presence. An accessor for an optional field takes an optional second argument that is used as the failure argument for the hash-ref call; if the second argument is omitted, the accessor returns the declared default value if the field is absent. If a field is optional and there is no required field after it, then the corresponding constructor argument is also optional. If the field is declared with #:default, the constructor always includes the field in the hash; if the default is declared with #:default/omit, the constructor omits the field when the corresponding argument is the same (equal?) to the default value.

If the #:immutable option is given, then the predicate and accessors accept only immutable hashes as instances of view-id. If the #:accept-mutable option is given, then the predicate and accessors accept both mutable and immutable hashes, and a make-mutable-view-id function is defined that creates mutable instances (using make-hasheq). If neither option is given, the behavior defaults to the #:accept-mutable behavior.


(hash-view-out hash-view-id)

Like struct-out but provides the identifiers associated with the given hash-view.