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 <[email protected]> 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 <[email protected]> > 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 < >>> [email protected]> 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 < >>>> [email protected]> 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 < >>>>> [email protected]> 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 [email protected]. >>>>>> 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 [email protected]. >>> 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 [email protected]. 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.

