Metadata
meta?
meta-ref
meta-has-key?
meta-set
meta-update
meta-remove
8.12

Metadata🔗ℹ

Cameron Moy

 (require meta) package: meta

This package provides a mechanism for associating arbitrary metadata with values. It’s inspired by Clojure’s metadata. Attaching metadata to a value does not affect equal? or chaperone-of? comparisons, but it may affect eq? comparisons. The following datatypes support metadata: procedures, transparent structs, vectors, boxes, hashes, sets, struct types, events, channels, continuation prompt tags, continuation mark keys, pairs, regular expressions, byte regular expressions, opaque structs (so long as the struct type descriptor is provided).

Under the hood, it uses Impersonator Properties to store metadata for datatypes that support chaperones. For others (pairs and regular expressions), it copies the value and uses a weak mutable hash table (compared with eq?) to store metadata behind the scenes.

procedure

(meta? v)  boolean?

  v : any/c
Returns whether v can have metadata (without providing a struct type descriptor).

Examples:
> (meta? (vector 1 2 3))

#t

> (meta? 42)

#f

procedure

(meta-ref v key [failure-result])  any/c

  v : any/c
  key : any/c
  failure-result : failure-result/c
   = 
(lambda ()
  (raise (make-exn:fail:contract ....)))
Returns the value for key in the metadata for v. If no value is found for key, then failure-result determines the result in the same way as hash-ref.

Examples:
> (define v (meta-set (vector) 'key "value"))
> (meta-ref v 'key)

"value"

procedure

(meta-has-key? v key)  boolean?

  v : any/c
  key : any/c
Returns #t if the metadata for v contains a value for the given key, #f otherwise.

Examples:
> (define v (meta-set (cons 1 2) 'key "value"))
> (meta-has-key? v 'key)

#t

procedure

(meta-set v key val [#:struct-type st])  meta?

  v : meta?
  key : any/c
  val : any/c
  st : struct-type? = #f
Returns a value that is equal? to v, but where the metadata maps key to val, overwriting any existing mapping for key.

Examples:
> (define func (meta-set (lambda () 2) 'key "value"))
> (func)

2

> (meta-ref func 'key)

"value"

procedure

(meta-update v    
  key    
  updater    
  [failure-result    
  #:struct-type st])  meta?
  v : meta?
  key : any/c
  updater : (-> any/c any/c)
  failure-result : failure-result/c
   = 
(lambda ()
  (raise (make-exn:fail:contract ....)))
  st : struct-type? = #f
Returns a value that is equal? to v, but with the metadata updated in the same way as hash-update.

Examples:
> (define b (meta-update (box 2) 'key add1 1))
> (meta-ref b 'key)

2

procedure

(meta-remove v key [#:struct-type st])  any/c

  v : any/c
  key : any/c
  st : struct-type? = #f
Removes any existing mapping for key in the metadata for v.

Examples:
> (define v (meta-set (vector) 'key "value"))
> (meta-has-key? (meta-remove v 'key) 'key)

#f