Struct-type properties with a struct-like interface
define-struct-like-struct-type-property
7.1

Struct-type properties with a struct-like interface

Source code: https://github.com/AlexKnauth/struct-like-struct-type-property.

 (require struct-like-struct-type-property)
  package: struct-like-struct-type-property

syntax

(define-struct-like-struct-type-property name [field ...]
  prop-option ...)
 
prop-option = #:property prop-expr val-expr
Defines these identifiers:

The property prop:name expects a function that takes a "self" argument and returns a name result. When someone wants to use the value as a prop:name, this function should construct a more basic structure that contains the field values.

Examples:
> (require struct-like-struct-type-property)
> (define-struct-like-struct-type-property foo [a b c])
> (foo-a (foo 1 2 3))

1

> (foo? (foo "a" "b" "c"))

#t

> (struct bar [x]
    #:property prop:foo ; when a bar is used as a foo, do this
    (lambda (self)
      (foo (first (bar-x self))
           (second (bar-x self))
           (third (bar-x self)))))
> (foo-a (bar (list 4 5 6)))

4

> (foo? (bar (list 'd 'e 'f)))

#t

> (match (bar (list 1 3 5))
    [(foo a b c) c])

5

The #:property prop-expr val-expr options specify super-properties. Anything that implements prop:name will automatically implement all the properties specified by the given prop-exprs.

Examples:
> (require struct-like-struct-type-property)
> (define-struct-like-struct-type-property quadratic [a b c]
    #:property prop:procedure
    (λ (self x)
      (+ (* (quadratic-a self) (sqr x))
         (* (quadratic-b self) x)
         (quadratic-c self))))
> (define f (quadratic 1 -2 -3))
> (f 0)

-3

> (f 1)

-4

> (f 2)

-3

> (f 3)

0

> (f 4)

5

> (struct vertex-form [a vertex]
    #:property prop:quadratic
    (λ (self)
      (match (vertex-form-vertex self)
        [(list h k)
         (define a (vertex-form-a self))
         (define b (* -2 a h))
         (define c (+ (* a (sqr h)) k))
         (quadratic a b c)])))
> (define g (vertex-form 1 '(1 -4)))
> (g 0)

-3

> (g 1)

-4

> (g 2)

-3

> (g 3)

0

> (g 4)

5