works :) after 'raco install struct-plus-plus' tyvm
On Sunday, October 31, 2021 at 7:03:14 AM UTC-7 [email protected] wrote: > 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/c0424e63-ee8c-4aa1-9f5f-b0e8f12b2c03n%40googlegroups.com.

