Several struct extensions need to construct accessors unhygienically even though the accessors can be extracted from struct types. The reason is that there’s not enough information to establish connection between field names and accessors.
For instance, consider struct*
from racket/match
.
#lang racket
(module submodule racket
(provide struct-id)
#;(provide struct-id-a struct-id-b)
(struct struct-id (a b)))
(require 'submodule)
(match (struct-id 1 2)
[(struct-id p q) (printf "~a ~a\n" p q)])
#;(match (struct-id 1 2)
[(struct* struct-id ([a p] [b q])) (printf "~a ~a\n" p q)])
The above code runs fine. Notice that we only provide struct-id
from the submodule, but match
could still destruct the struct correctly because it can obtain accessors from the struct type inside struct-id
.
However, if we uncomment the second comment, the code fails with the error:
; struct*: field name not associated with given structure type
; at: struct-id-b
; in: (struct* struct-id ((a p) (b q)))
By uncommenting code inside the submodule to provide struct-id-b
and struct-id-a
, the code now runs fine again.
As I understand, the reason why struct*
and other struct extensions like kw-make-struct
couldn’t use accessors extracted from struct-id
is that there’s no mapping from field name to accessors.
Hence the question: why struct type doesn’t include field names?
Hence the question: why struct type doesn’t include field names?
--
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...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/racket-users/CADcuegvjQ_%2BgYg_VQb4TG-czSAMzZJOtZ0K3Ge7c_XNUO2QzCQ%40mail.gmail.com.
For more options, visit https://groups.google.com/d/optout.
First of all, .
won’t work in standard Racket because .
has a special meaning (see https://docs.racket-lang.org/reference/reader.html#%28part._parse-pair%29).
But yes, this is directly related to the discussion above because with the field name information, you can write your own accessor.
#lang racket
(module submodule racket
(provide @)
(require syntax/parse/define)
(define (access e fld)
(match-define-values (info _) (struct-info e))
;; for now we hard code it; would be able to extract it from struct-type-info in Racket 2
(define fields '(bar baz))
(match-define-values (name _ _ accessor _ _ _ _) (struct-type-info info))
(accessor e (index-of fields fld)))
(define-simple-macro (@ e:expr fld:id) (access e 'fld)))
(require 'submodule)
(struct foo (bar baz) #:transparent)
(define my-foo (foo 1 2))
(@ my-foo baz) ;=> 2
Note that your struct must not be opaque for this to work. Typed Racket might have enough compile-time data to make this to work with opaque structs, though.
But for now, https://docs.racket-lang.org/struct-define/index.html might be a good workaround for your problem.
--
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...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/racket-users/d23df714-e808-91f3-b978-29bcca849100%40iaaras.ru.
But yes, this is directly related to the discussion above because with the field name information, you can write your own accessor.
Yes it will be a way to go in Racket 2.
But for now, https://docs.racket-lang.org/struct-define/index.html might be a good workaround for your problem.
Thank you, I did not know about it. define-struct-define is indeed very handy.
Best regards,
Dmitry