On Fri, Jun 4, 2021 at 6:21 PM flirora <tkoo...@gmail.com> wrote:

> Is there a way to define a struct so that it has a field whose value is
> filled in (instead of passed to the constructor) with a value derived from
> other fields? For example, could you define a struct foo with two
> explicit fields, x and y, plus a field called z whose value is computed
> as (+ x y) (yes, simple, but imagine that this is a more expensive
> operation):
>
> > (define foo1 (foo 1 2))
> > (define foo2 (foo 7 12))
> > (foo-z foo1)
> 3
> > (foo-z foo2)
> 19
>

Yes, with the struct-plus-plus module.  As a bonus you can also typecheck
your arguments:

#lang racket

(require struct-plus-plus)
(struct++ foo
          ([x number?] [y number?] [(z #f)])
          (#:rule ("autogenerate z. overrides the provided value"
                   #:transform z (x y) [(+ x y)]))
          #:transparent)

(define foo1 (foo++ #:x 1 #:y 2))
(define foo2 (foo++ #:x 7 #:y 12))
(foo-z foo1) ; 3
(foo-z foo2) ; 19

(define throws-exception (foo++ #:x 7 #:y "string")) ; contract violation


Note that the standard positional constructor is generated but does not
support the autocalculation feature or typechecking.  To get the advanced
features you need to use the keyword version.


>
> The closest I could find in the documentation was the #:auto property,
> but:
>
>    1. it makes the field mutable, even though I'm not interested in
>    mutating z
>    2. the default value is fixed across all constructions, while I want z
>    to depend on x and y
>
> Of course, I could make z an explicit field, write a custom constructor,
> and export that instead of the default constructor for foo. But that seems
> to be a Royal Pain, especially since (AFAIK) you can't provide the struct
> as a whole anymore. (And I need to write about 12 of these structs to boot.)
>
> --
> You received this message because you are subscribed to the Google Groups
> "Racket Users" group.
> To unsubscribe from this group and stop receiving emails from it, send an
> email to racket-users+unsubscr...@googlegroups.com.
> To view this discussion on the web visit
> https://groups.google.com/d/msgid/racket-users/9f9e1548-d01d-469f-b565-22601e02dd82n%40googlegroups.com
> <https://groups.google.com/d/msgid/racket-users/9f9e1548-d01d-469f-b565-22601e02dd82n%40googlegroups.com?utm_medium=email&utm_source=footer>
> .
>

-- 
You received this message because you are subscribed to the Google Groups 
"Racket Users" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to racket-users+unsubscr...@googlegroups.com.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/racket-users/CAE8gKofa5xPzBP%3DZpd0UjtBUdj7hHArPGtqKKxkUfz1g%3DSbaxQ%40mail.gmail.com.

Reply via email to