On Sun, Oct 31, 2021, 7:49 AM Jens Axel Søgaard <jensa...@soegaard.net>
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 <m...@jadud.com>:
>
>> 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 <bc.beck...@gmail.com>
>> 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 <bc.be...@gmail.com>
>>>> 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 <
>>>>> clem...@brinckerhoff.org> 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 <bc.be...@gmail.com>
>>>>>> 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
>>>>>> jackh...@gmail.com 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 bc.be...@gmail.com
>>>>>> 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 racket-users...@googlegroups.com.
>>>>>> > 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 racket-users...@googlegroups.com.
>>>>>
>>>> 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 racket-users+unsubscr...@googlegroups.com.
>>> 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 racket-users+unsubscr...@googlegroups.com.
>> 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 racket-users+unsubscr...@googlegroups.com.
> 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 racket-users+unsubscr...@googlegroups.com.
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.

Reply via email to