The actual accessor functions are in there as well, not just the names.

On Sun, Oct 31, 2021, 9:58 AM Jens Axel Søgaard <[email protected]>
wrote:

> A quick example:
>
> #lang racket
> (require racket/require)
> (require (filtered-in (λ (name) (regexp-replace #rx"struct[+][+]" name
> "struct"))
>                       struct-plus-plus))
>
> (struct horse (breed color legs))
>
> (define beauty (horse 'arabian 'black 4))
>
> (define info (force (struct-ref beauty)))
> (map struct-field-name (struct-info-fields info))
>
> The result is:
> '(breed color legs)
>
> Den søn. 31. okt. 2021 kl. 13.06 skrev David Storrs <
> [email protected]>:
>
>>
>>
>> On Sun, Oct 31, 2021, 7:49 AM Jens Axel Søgaard <[email protected]>
>> wrote:
>>
>>> Hi Brian,
>>>
>>> A few random thoughts:
>>>
>>> > I would like, given only the symbol foo referring to the struct type
>>> itself,
>>> > to discover (at least) the list of procedures foo?, foo-a, foo-b, plus
>>> > anything else the author of foo (the type) wants me to see.
>>>
>>> When you want to look this up, is it in the repl (i.e. at runtime)?
>>>
>>> The standard `struct` construct doesn't store much reflection
>>> information.
>>> Instead of fighting the standard construct, you can consider making a
>>> little variation.
>>>
>>> If you are satisfied with having info for the structs defined in your
>>> own program
>>> (i.e. modules you have written yourself), then you can consider making a
>>> module, say, `fancy-struct` that exports a macro where
>>>
>>>    (fancy-struct yada ...)
>>>
>>> expands into
>>>
>>>    (begin
>>>       (fancy-struct yada ...)
>>>       <store reflection information>)
>>>
>>> Using `rename-out` you can export it as `struct`, so it can be used
>>> without changing any existing code.
>>>
>>> /Jens Axel
>>>
>>
>> Coincidentally, that module exists!
>>
>>
>> https://docs.racket-lang.org/struct-plus-plus/index.html#%28part._.Reflection%29
>>
>>
>>
>>>
>>>
>>> Den søn. 31. okt. 2021 kl. 11.42 skrev Matt Jadud <[email protected]>:
>>>
>>>> Hi Brian,
>>>>
>>>> Does this help move you forward?
>>>>
>>>> It has been a while since I've stared at macros in Racket, so this
>>>> might be easier...
>>>>
>>>> Also, make sure you're executing this code in a module. If you're
>>>> working in a REPL, I suspect all bets are off. It is certainly the case
>>>> that you could combine several of my exploration steps into a
>>>> simpler/cleaner macro, instead of generating lists of symbols, converting
>>>> them back to syntax objects, and so on.
>>>>
>>>> Also, as a solution/exploration, I... don't know how this would
>>>> interact with the full range of possible structs. Someone who knows more
>>>> about syntax and structs should be able to speak to how you'd find out all
>>>> of the defined functions that spawn from struct definition/creation. (It
>>>> might also be useful to know *why* you want to destructure structs this
>>>> way? Knowing that may illuminate some other path forward.)
>>>>
>>>> #lang racket
>>>> (require racket/struct-info)
>>>>
>>>> (struct A (b c))
>>>>
>>>> (struct B (e f) #:transparent)
>>>>
>>>> (require (for-syntax racket/struct-info))
>>>> (define-syntax (get-field-names stx)
>>>>   (syntax-case stx ()
>>>>     [(_ sym)
>>>>      #`(quote
>>>>         #,(struct-field-info-list
>>>>            (syntax-local-value #'sym)))
>>>>               ]))
>>>>
>>>> ;; These let me see the field names
>>>> (get-field-names A)
>>>> ;; Returns '(c b)
>>>> (get-field-names B)
>>>> ;; Returns '(f e)
>>>>
>>>> ;;
>>>> https://stackoverflow.com/questions/20076868/how-to-know-whether-a-racket-variable-is-defined-or-not
>>>> (define-syntax (defined? stx)
>>>>   (syntax-case stx ()
>>>>     [(_ id)
>>>>      (with-syntax ([v (identifier-binding #'id)])
>>>>        #''v)]))
>>>>
>>>> (define-syntax (proc-names stx)
>>>>   (syntax-case stx ()
>>>>     [(_ sym)
>>>>      (let ([names (map (λ (s)
>>>>                          (string->symbol
>>>>                           (format "~a-~a" (syntax-e #'sym) s)))
>>>>                        (struct-field-info-list
>>>>                         (syntax-local-value #'sym))
>>>>                        )])
>>>>        #`(quote #,names))]))
>>>>
>>>> ;; This...
>>>> (proc-names A)
>>>> ;; Returns '(A-c A-b)
>>>>
>>>> (define-syntax (names-exist? stx)
>>>>   (syntax-case stx ()
>>>>     [(_ sym)
>>>>      (let ([names (map (λ (s)
>>>>                          (string->symbol
>>>>                           (format "~a-~a" (syntax-e #'sym) s)))
>>>>                        (struct-field-info-list
>>>>                         (syntax-local-value #'sym))
>>>>                        )])
>>>>        #`(andmap (λ (s)
>>>>                    (equal? 'lexical s))
>>>>                  (map (λ (s)
>>>>                         (defined? s))
>>>>                       (quote #,names)))
>>>>        )]))
>>>>
>>>> (names-exist? A)
>>>> (names-exist? B)
>>>>
>>>>
>>>> On Sat, Oct 30, 2021 at 10:33 PM Brian Beckman <[email protected]>
>>>> wrote:
>>>>
>>>>> Here are some of my latest (failed) experiments:
>>>>>
>>>>> #lang racket
>>>>>
>>>>> (require (for-syntax racket/struct-info))
>>>>> (require racket/pretty)
>>>>>
>>>>> (struct foo (a b) #:transparent)
>>>>>
>>>>> (displayln `("a foo object is transparent: I can see inside: \n
>>>>> (struct->vector (foo 1 2)) ~~> "
>>>>>              ,(struct->vector (foo 1 2))))
>>>>>
>>>>> (displayln `("syntax object is opaque I can't see inside: \n
>>>>> (struct->vector #'foo) ~~> "
>>>>>              ,(struct->vector #'foo)))
>>>>>
>>>>> ;;; Why do two copies of the syntax display? (One copy
>>>>> ;;; is a side-effect. The other is a result).
>>>>>
>>>>> ;;; At expansion time, I can get some graphics in Dr-Racket for
>>>>> ;;; definition of foo, but I cannot get likewise
>>>>> ;;; not into the definition of syntax.
>>>>> (begin-for-syntax
>>>>>   (displayln
>>>>>    (extract-struct-info
>>>>>     (syntax-local-value
>>>>>      #'foo))))  ; #'syntax))))
>>>>>
>>>>> ;;; But the access procedures for #'syntax are known!?!? (I just
>>>>> ;;; happen to know that there is a procedure named 'syntax-position';
>>>>> ;;; my whole issue is in trying to find out the list of all
>>>>> ;;; procedures defined in the system when the syntax type is created!)
>>>>>
>>>>> (syntax-position #'42)
>>>>>
>>>>> ;;; Whereas #'foo is known in this module scope,
>>>>> ;;; (syntax struct:foo) is not known! Looks like the shorthand
>>>>> ;;; #'whatever for making a syntax object is known, but the longhand,
>>>>> ;;; presumably (syntax 'whatever), is not known.
>>>>>
>>>>> (begin-for-syntax
>>>>>   (displayln
>>>>>    (extract-struct-info
>>>>>     (syntax-local-value
>>>>>      #'syntax))))
>>>>>
>>>>> ~~~~~~~~
>>>>>
>>>>> Welcome to DrRacket, version 8.2 [cs].
>>>>> Language: racket, with debugging; memory limit: 128 MB.
>>>>> (.#<syntax:GSI/nanosim-apu-docs/WIKIS/BELEX_3/racket-sandbx-public.rkt:6:8
>>>>> struct:foo>
>>>>> .#<syntax:GSI/nanosim-apu-docs/WIKIS/BELEX_3/racket-sandbx-public.rkt:6:8
>>>>> foo>
>>>>> .#<syntax:GSI/nanosim-apu-docs/WIKIS/BELEX_3/racket-sandbx-public.rkt:6:8
>>>>> foo?>
>>>>> (.#<syntax:GSI/nanosim-apu-docs/WIKIS/BELEX_3/racket-sandbx-public.rkt:6:8
>>>>> foo-b>
>>>>> .#<syntax:GSI/nanosim-apu-docs/WIKIS/BELEX_3/racket-sandbx-public.rkt:6:8
>>>>> foo-a>) (#f #f) #t)
>>>>> . .
>>>>> ../../../../../../usr/share/racket/pkgs/errortrace-lib/errortrace/stacktrace.rkt:690:2:
>>>>> extract-struct-info: contract violation
>>>>>   expected: struct-info?
>>>>>   given: #<procedure:...rivate/template.rkt:563:0>
>>>>> >
>>>>>
>>>>> On Friday, October 29, 2021 at 4:10:37 PM UTC-7 Siddhartha Kasivajhula
>>>>> wrote:
>>>>>
>>>>>> I was able to find this interface
>>>>>> <https://docs.racket-lang.org/reference/inspectors.html#%28def._%28%28quote._~23~25kernel%29._struct-type-info%29%29>,
>>>>>> but it doesn't quite provide the same information. E.g. (struct-type-info
>>>>>> struct:foo)
>>>>>>
>>>>>> The ability to "introspect" values in a shell (or in the application)
>>>>>> is useful in languages like python (e.g. dir(object) tells you what
>>>>>> methods it provides, help(anything) gives you the interface/function
>>>>>> signature, docstrings, etc.). I haven't seen this style emphasized in
>>>>>> Racket documentation, and that may be because racket isn't 
>>>>>> object-oriented
>>>>>> by default as python is, so that there often isn't a single object
>>>>>> encapsulating all of this information.
>>>>>>
>>>>>> But all the same, if there are analogous facilities in racket, like
>>>>>> the kind Brian asked about, I'd love to know as well.
>>>>>>
>>>>>>
>>>>>> On Fri, Oct 29, 2021 at 3:14 PM Brian Beckman <[email protected]>
>>>>>> wrote:
>>>>>>
>>>>>>> Well, as I understand it, a struct (usually? always?), #:transparent
>>>>>>> or not, when declared, defines symbols that are meant to be visible in 
>>>>>>> the
>>>>>>> current scope, so (struct foo (a b)) defines foo #|constructor|#, foo?
>>>>>>> #|instance-predicate|# foo-a and foo-b #|data accessors|# , that I can 
>>>>>>> call
>>>>>>> on instances:
>>>>>>>
>>>>>>>     (struct foo (a b))
>>>>>>>     (let ([my-foo (foo 42 37)]
>>>>>>>        (list (foo? my-foo)
>>>>>>>              (foo-a my-foo)
>>>>>>>              (foo-b my-foo)))  ~~>  '(#t 42 37)
>>>>>>>
>>>>>>> I would like, given only the symbol foo referring to the struct type
>>>>>>> itself, to discover (at least) the list of procedures foo?, foo-a, 
>>>>>>> foo-b,
>>>>>>> plus anything else the author of foo (the type) wants me to see.
>>>>>>>
>>>>>>>
>>>>>>> On Fri, Oct 29, 2021 at 1:45 PM John Clements <
>>>>>>> [email protected]> wrote:
>>>>>>>
>>>>>>>> In the text below, you refer to the “public” interface. Can I ask
>>>>>>>> what you mean by “public” in this context?
>>>>>>>>
>>>>>>>> John
>>>>>>>>
>>>>>>>> > On Oct 29, 2021, at 11:16 AM, Brian Beckman <[email protected]>
>>>>>>>> wrote:
>>>>>>>> >
>>>>>>>> > I believe that run time will be the most plausible use case. I
>>>>>>>> may write macros that refer to struct-procedure names at macro-writing
>>>>>>>> time, but I don't expect to invoke the struct procedures at 
>>>>>>>> macro-expansion
>>>>>>>> time. My primary issue is "discoverability:" how can I find out the
>>>>>>>> interface of any struct?
>>>>>>>> >
>>>>>>>> > On Thursday, October 28, 2021 at 1:00:15 PM UTC-7
>>>>>>>> [email protected] wrote:
>>>>>>>> > Are you intending to use the struct procedure names at compile
>>>>>>>> time (such as in a macro) or runtime?
>>>>>>>> >
>>>>>>>> > On Tuesday, October 26, 2021 at 5:02:46 PM UTC-7
>>>>>>>> [email protected] wrote:
>>>>>>>> > I understand why structs are opaque, by default, but I want to
>>>>>>>> discover the public interface of some struct type, that is, a list of 
>>>>>>>> the
>>>>>>>> procedures defined by the struct.
>>>>>>>> >
>>>>>>>> > Here is an example. Suppose I want to find out all the procedures
>>>>>>>> defined on an instance of the syntax struct
>>>>>>>> >
>>>>>>>> >     #'42
>>>>>>>> >
>>>>>>>> > Dr. Racket shows an expander clicky that shows some formatted
>>>>>>>> information inside the instance :
>>>>>>>> >
>>>>>>>> >
>>>>>>>> >
>>>>>>>> > Uncapitializing the names in the display reveals the interface:
>>>>>>>> >
>>>>>>>> >     (syntax-position #'42) ~~> 790
>>>>>>>> >     (syntax-span #'42) ~~> 2
>>>>>>>> >     (syntax-original? #'42) ~~> #t
>>>>>>>> >
>>>>>>>> > etc.
>>>>>>>> >
>>>>>>>> > I want to discover those procedure names in my racket program,
>>>>>>>> not manually by visually inspecting graphics in Dr Racket.
>>>>>>>> >
>>>>>>>> > I found this trick for structs that I define:
>>>>>>>> >
>>>>>>>> > #lang racket
>>>>>>>> > (require (for-syntax racket/struct-info))
>>>>>>>> > (require racket/pretty)
>>>>>>>> >
>>>>>>>> > (struct foo (a b))
>>>>>>>> > (begin-for-syntax
>>>>>>>> >   (displayln
>>>>>>>> >    (extract-struct-info
>>>>>>>> >     (syntax-local-value
>>>>>>>> >      #'foo))))
>>>>>>>> >
>>>>>>>> > ~~>
>>>>>>>> >
>>>>>>>> >
>>>>>>>> >
>>>>>>>> > but it doesn't work for the syntax type
>>>>>>>> >
>>>>>>>> > (begin-for-syntax
>>>>>>>> >   (displayln
>>>>>>>> >    (extract-struct-info
>>>>>>>> >     (syntax-local-value
>>>>>>>> >      #'syntax))))
>>>>>>>> >
>>>>>>>> > ~~>
>>>>>>>> >
>>>>>>>> >
>>>>>>>> >
>>>>>>>> > I'd be grateful for advice and an example of how to get the
>>>>>>>> interface of "syntax" without Dr Racket and without grovelling docs.
>>>>>>>> >
>>>>>>>> > --
>>>>>>>> > 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 [email protected].
>>>>>>>> > To view this discussion on the web visit
>>>>>>>> https://groups.google.com/d/msgid/racket-users/8e4ca03e-e276-4c42-a662-4fcf7c994387n%40googlegroups.com
>>>>>>>> .
>>>>>>>>
>>>>>>>> --
>>>>>>> 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 [email protected].
>>>>>>>
>>>>>> To view this discussion on the web visit
>>>>>>> https://groups.google.com/d/msgid/racket-users/CAK2VK6tMxFH0oEq4iCgk7PW-4yJTB8xNr_b3F6GPwQS1MZVLwQ%40mail.gmail.com
>>>>>>> <https://groups.google.com/d/msgid/racket-users/CAK2VK6tMxFH0oEq4iCgk7PW-4yJTB8xNr_b3F6GPwQS1MZVLwQ%40mail.gmail.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 [email protected].
>>>>> To view this discussion on the web visit
>>>>> https://groups.google.com/d/msgid/racket-users/c1c4f0f3-9c8d-430d-8615-4ec2cbea90f4n%40googlegroups.com
>>>>> <https://groups.google.com/d/msgid/racket-users/c1c4f0f3-9c8d-430d-8615-4ec2cbea90f4n%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 [email protected].
>>>> To view this discussion on the web visit
>>>> https://groups.google.com/d/msgid/racket-users/CAAGM456vwtx80%3DX44UiLZAMjbL6O0zMHOZSyc32L6opM89Bjew%40mail.gmail.com
>>>> <https://groups.google.com/d/msgid/racket-users/CAAGM456vwtx80%3DX44UiLZAMjbL6O0zMHOZSyc32L6opM89Bjew%40mail.gmail.com?utm_medium=email&utm_source=footer>
>>>> .
>>>>
>>>
>>>
>>> --
>>> --
>>> Jens Axel Søgaard
>>>
>>> --
>>> 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 [email protected].
>>> To view this discussion on the web visit
>>> https://groups.google.com/d/msgid/racket-users/CABefVgwBi8-2cLuA7-dtiM%2BnbxN5ZriPLcG1JX3ATTw2xyQd8w%40mail.gmail.com
>>> <https://groups.google.com/d/msgid/racket-users/CABefVgwBi8-2cLuA7-dtiM%2BnbxN5ZriPLcG1JX3ATTw2xyQd8w%40mail.gmail.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 [email protected].
>> To view this discussion on the web visit
>> https://groups.google.com/d/msgid/racket-users/CAE8gKofkEmZ4M64_QjSLrLAz_LH0CdDG%3DhrWX%2B-fRxJt6RcR0Q%40mail.gmail.com
>> <https://groups.google.com/d/msgid/racket-users/CAE8gKofkEmZ4M64_QjSLrLAz_LH0CdDG%3DhrWX%2B-fRxJt6RcR0Q%40mail.gmail.com?utm_medium=email&utm_source=footer>
>> .
>>
>
>
> --
> --
> Jens Axel Søgaard
>
>

-- 
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 [email protected].
To view this discussion on the web visit 
https://groups.google.com/d/msgid/racket-users/CAE8gKoedHwEh%3D7d%3DWPXuoU_fg6%2BgfmaiVVfUKM%2Bb72ypcA%2BBdg%40mail.gmail.com.

Reply via email to