Oops, noted, I have to use 'reply all'. In the benefit of context I'll post again my reply to Sorawee:
Short summary: I'm trying to have a macro (mymacro oldname newname (fields ...)) that accesses oldname-foo, which contains a list of symbols, and then define a function that takes (cons oldname-foo (fields ...)) formated as identifiers as arguments. Or at least to get the length of oldname-foo and name them whatever. Full explanation: using make-struct-type I'm building a different struct system I call cards, where structs can be defined as a function call, which will be their constructor, and they are printed as the constructor function call that would generate them. So, for instance, we can do: > (card (hola a b #:c c)) > (hola 1 2 #:c 3) (hola 1 2 #:c 3) or > (card (ciao a [b 3])) > (ciao 7) (ciao 7) > (ciao 7 4) (ciao 7 4) or even > (card (line . xs)) > (line 1 2 3 4 5 6 7 8 9) (line 1 2 3 4 5 6 7 8 9) Also the names of the fields are stored in *<name-of-the-card>-fields (this is the oldname-foo of the above example), so *hola-fields contains '(a b #:c c). So far this is working perfectly, but I don't have inheritance. So when I create a card that inherits from a previous card, I need to access its *<parent-card>-fields to define a new function containing both the parent and the son fields. That is, I'm trying to get this behavior: > (card (hola a #:b b)) > (card hola (ciao c)) ;;; should expand to (define (ciao a #:b b c) ...), among other things > (ciao 1 #:b 2 3) (ciao 1 #:b 2 3) On Fri, 17 Sept 2021 at 21:13, David Storrs <david.sto...@gmail.com> wrote: > Additional thought and self-plug: My struct-plus-plus module creates > structures with full reflection information available, including field > names, contracts, and wrappers. It also supports type checking, data > normalization, default values, and automatically provides both keyword > constructors and dotted accessors for clarifying field names. It doesn't > support inheritance but it would make it easy to do many of the things I > think you might be interested in. > https://docs.racket-lang.org/struct-plus-plus/index.html > > On Fri, Sep 17, 2021 at 3:08 PM David Storrs <david.sto...@gmail.com> > wrote: > >> >> NB: You did a 'reply' to Sorawee instead of to the list as a whole, and >> also the same for the email I sent. Probably good to 'reply all' so that >> the list gets the full context. >> >> Sorawee offered some good advice on how to do the things you're asking >> about and asked relevant questions. I'm wondering about the macro level: >> >> A) What exactly are you trying to do, because I think I've got it but >> I'm still fuzzy. >> B) Why are you trying to do it? >> C) Is there a simpler / more Racket-ish way to do it? >> >> On Thu, Sep 16, 2021 at 2:12 PM Dimaugh Silvestris < >>> dimaughsilvest...@gmail.com> wrote: >>> >>>> Sorry, I haven't posted the full macro because it's long and makes use >>>> of several other functions, but I'll try to summarize what it does: >>>> >>>> Short summary: I'm trying to have a macro (mymacro oldname newname >>>> (fields ...)) that accesses oldname-foo, which contains a list of symbols, >>>> and then define a function that takes (cons oldname-foo (fields ...)) >>>> formated as identifiers as arguments. Or at least to get the length of >>>> oldname-foo and name them whatever. >>>> >>>> Full explanation: using make-struct-type I'm building a different >>>> struct system I call cards, where structs can be defined as a function >>>> call, which will be their constructor, and they are printed as the >>>> constructor function call that would generate them. So, for instance, we >>>> can do: >>>> >>> >> I notice that you're using make-struct-type instead of struct -- is that >> intentional or is there some specific feature you want? I suspect I'm >> about to get a more experienced person telling me that I've missed >> something, but to the best of my knowledge struct is the more modern >> version and can do everything that make-struct-type can do but cleaner. >> >> As to the printing as a constructor call: putting the #:prefab option >> on a struct will allow you to print it in a reversible form that can be >> called in order to generate the struct again, but it makes explicit all the >> values that go in instead of hiding them away as defaults or etc. For >> example: >> >> #lang racket >> >> (struct person (name age) #:prefab) >> >> (person 'bob 17) >> >> (with-output-to-file >> "/tmp/struct-demo" >> #:exists 'replace >> (thunk >> (display (person 'fred 18)))) >> >> (with-input-from-file >> "/tmp/struct-demo" >> (thunk (read))) >> >> (with-input-from-file >> "/tmp/struct-demo" >> (thunk (person-name (read)))) >> >> >> >> Output: >> >> '#s(person bob 17) >> '#s(person fred 18) >> 'fred >> >> Obviously, reading code directly from a file is a bad plan, but the same >> would work from any appropriate port and I'm using a file because it's >> easy. The point is that I was able to write it into a port (in this case a >> file port) such that it produced a format that represented the constructor >> call and then read it back into an actual struct that I could use accessors >> on etc. One disadvantage is that you can't attach properties to a prefab >> struct but that might or might not be relevant to you. >> >> >> > (card (hola a b #:c c)) >>>> > (hola 1 2 #:c 3) >>>> (hola 1 2 #:c 3) >>>> or >>>> > (card (ciao a [b 3])) >>>> > (ciao 7) >>>> (ciao 7) >>>> > (ciao 7 4) >>>> (ciao 7 4) >>>> >>>> or even >>>> >>>> > (card (line . xs)) >>>> > (line 1 2 3 4 5 6 7 8 9) >>>> (line 1 2 3 4 5 6 7 8 9) >>>> >>>> Also the names of the fields are stored in *<name-of-the-card>-fields >>>> (this is the abc-foo of the above example), so *hola-fields contains '(a b >>>> #:c c). >>>> So far this is working perfectly, but I don't have inheritance. So when >>>> I create a card that inherits from a previous card, I need to access its >>>> *<parent-card>-fields to define a new function containing both the parent >>>> and the son fields. That is, I'm trying to get this behavior: >>>> > (card (hola a #:b b)) >>>> > (card hola (ciao c)) ;;; should expand to (define (ciao a #:b b c) >>>> ...), among other things >>>> > (ciao 1 #:b 2 3) >>>> (ciao 1 #:b 2 3) >>>> >>> >> How are you going to handle the situation where a parent and child struct >> have a field with the same name? This is entirely legit: >> >> #lang racket >> >> (struct person (name age) #:prefab) ; age is years since birth >> >> (struct employee person (age) #:prefab) ; age is years since hiring >> >> >> (define bob (employee 'bob 17 3)) >> bob >> (employee-age bob) >> (person-age bob) >> >> Output: >> >> '#s((employee person 2) bob 17 3) >> 3 >> 17 >> >> >> Going back to the earlier question: What is it you are ultimately trying >> to accomplish at a high level? i.e. Not "generate a lot of struct types >> and field data" but something like "store information about a hierarchical >> structure of <thing> in a persistent way so that it is recoverable across >> server restarts." >> >> >> >>>> On Thu, 16 Sept 2021 at 22:35, Sorawee Porncharoenwase < >>>> sorawee.pw...@gmail.com> wrote: >>>> >>>>> In general, it would be helpful to provide an example of the macro >>>>> use, so that we know what you want to do. If it doesn't work, it would be >>>>> helpful to provide the buggy program and an error message so that we can >>>>> help with the issue that you are encountering. >>>>> >>>>> From my guess, you have a variable named abc-foo somewhere, and with >>>>> this macro, you wish to define a function named abc that can access >>>>> the value of abc-foo? If so, here’s an example of a working program: >>>>> >>>>> #lang racket >>>>> >>>>> (require (for-syntax racket/syntax)) >>>>> >>>>> (define-syntax (my-macro stx) >>>>> (syntax-case stx () >>>>> [(_ name other-args ...) >>>>> (with-syntax ([varname (format-id #'name "~a-foo" #'name)]) >>>>> #'(define name >>>>> (λ (other-args ...) >>>>> (println (list varname other-args ...)))))])) >>>>> >>>>> (define abc-foo 123) >>>>> (my-macro abc x y) >>>>> (abc 5 6) ;=> '(123 5 6) >>>>> >>>>> >>>>> >>>>> >>>>> >>>>> On Thu, Sep 16, 2021 at 1:21 PM Dimaugh Silvestris < >>>>> dimaughsilvest...@gmail.com> wrote: >>>>> >>>>>> (sorry if I'm asking too many questions about macros lately, I'm >>>>>> learning about them but I keep running into scenarios I can't find >>>>>> documentation for) >>>>>> >>>>>> I'm trying to capture the value of a variable whose identifier I can >>>>>> only get with format-id, inside a with-syntax. >>>>>> Something like this pseudocode (imagine name-foo contains a list of >>>>>> symbols): >>>>>> (define-syntax (my-macro stx) >>>>>> (syntax-case stx () >>>>>> ((_ name other-args ...) >>>>>> (with-syntax* ((varname (format-id #'name "~a-foo" #'name)) >>>>>> (varval (cons (datum->syntax #'varname) >>>>>> (datum->syntax #'(other-args ...))))) >>>>>> #'(define name (λ varval (print varval))))))) >>>>>> >>>>>> >>>>>> Which of course doesn't work. I understand this might have to do with >>>>>> how macros work at an earlier phase than runtime, so is it impossible? >>>>>> >>>>>> -- >>>>>> 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/CAN4YmRF%3Do3NsXOvK2fvUDeYL_jfA9r946%3D%3DguoGb_%3DKyS%3Dm%2Bxw%40mail.gmail.com >>>>>> <https://groups.google.com/d/msgid/racket-users/CAN4YmRF%3Do3NsXOvK2fvUDeYL_jfA9r946%3D%3DguoGb_%3DKyS%3Dm%2Bxw%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/CADcuegvgnUpin2sMeg%3DPHRAN4gBRDx0HpUAuz8dM3aaZ8uAGvw%40mail.gmail.com >>> <https://groups.google.com/d/msgid/racket-users/CADcuegvgnUpin2sMeg%3DPHRAN4gBRDx0HpUAuz8dM3aaZ8uAGvw%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/CAN4YmRFM%2B7%3DJDSD7%3DLNd%3De8vRRosH_ZNds%2BgGQW%2BMGKp7WSU2w%40mail.gmail.com.