Hi, Matt ... I'll try your ideas in a little while. Regarding "why," I want the ability, from a module or a REPL, to quickly dump the attributes of an instance without having to look things up. The need arose when I was barnstorming and trying to explain syntax objects to someone, and he asked "what are the attributes of a syntax object?" I replied, "let's just dump one out," and that turned out impossible. So we did an F1 lookup of the doc and were confronted with the general meta-syntactic definition file:///usr/share/doc/racket/reference/stx-patterns.html#%28form._%28%28lib._racket%2Fprivate%2Fstxcase-scheme..rkt%29._syntax%29%29. Well, we weren't going to finish understanding that in the one-hour lunch meeting we had.
Bottom line, I was unable to give a quick answer to a reasonable question. On Sunday, October 31, 2021 at 3:42:19 AM UTC-7 Matt Jadud wrote: > 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/ad2ae5dd-487a-49b2-84bf-c8315baa5722n%40googlegroups.com.

