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.

