I’d imagine that you would only provide program and the modifiers. Everything well work out :)
Jay On Fri, Jan 1, 2021 at 11:44 AM Sage Gerard <[email protected]> wrote: > Ah, I see. Thank you for that! > > As for rephrasing my original question: If program were provided as > #%module-begin, I expect that syntax-protect would prevent a programmer > from > using out the phase-0 bindings. But in my version of the program Racket > would keep complaining about unbound identifiers unless I provided > everything. > > The thing is, I don't want the user to be able to write things like > set-field* in their program just because I'm forced to provide it. > That's why I'm trying to figure out a way to say "Ok, this module language > happens to include set-field*, but set-field* must only appear > in module context, or not at all." > > *~slg* > > > ‐‐‐‐‐‐‐ Original Message ‐‐‐‐‐‐‐ > On Thursday, December 31, 2020 1:40 PM, Jay McCarthy < > [email protected]> wrote: > > I meant like this: > > ``` > #lang racket/base > (require (for-syntax racket/base > syntax/parse) > syntax/parse/define) > > ;; Run-time > (struct state (a b c d) #:transparent) > (define mt (state #f #f #f #f)) > (define-simple-macro (set-field st:expr f:id v:expr) > (struct-copy state st [f v])) > (define-simple-macro (set-field* f:id v:expr) > (λ (st) (set-field st f v))) > > ;; Compile-time > (begin-for-syntax > (define-struct modifier (f))) > > (define-simple-macro (define-modifier (m . args) body) > (begin > (define-syntax m-f > (syntax-parser [(_ args) #'body])) > (define-syntax m (modifier #'m-f)))) > > (define-modifier (the-a-says x:string) > (set-field* a x)) > (define-modifier (the-b-says 'x:id) > (set-field* b 'x)) > (define-modifier (the-c-is x:string) > (set-field* c x)) > (define-modifier (the-d-looks-like x:nat) > (set-field* d x)) > > (define-syntax-parser term > [(_ ((~var m (static modifier? "state modifier")) . args)) > #:with f (modifier-f (attribute m.value)) > #'(f args)]) > > (define-syntax-parser program > [(_) #'mt] > [(_ x . more) #'((term x) (program . more))]) > > ;; Example > (program > (the-a-says "Aaah") > (the-b-says 'Baah) > (the-c-is "Caaah") > (the-d-looks-like 42)) > ``` > > -- > Jay McCarthy > Associate Professor @ CS @ UMass Lowell > http://jeapostrophe.github.io > Vincit qui se vincit. > > > On Thu, Dec 31, 2020 at 12:07 PM Sage Gerard <[email protected]> wrote: > >> I didn't see an answer to my original question, but I still want to make >> sure I understood you before I rephrase. Thank you for the insights! >> >> By your three step suggestion, is something like this what you meant? I'm >> not sure I understood Step 3. It seems like I still have to add new >> structure types and macros to define new terms, which is about as laborious >> as what I was doing with #:datum-literals and struct-copy. >> >> (module id racket/base >> (require racket/format >> (for-syntax racket/base syntax/parse)) >> >> (begin-for-syntax (struct item (name num))) >> >> (define (record-item name num) >> (~a num ". " name)) >> >> (define-syntax (term stx) >> (syntax-parse stx >> #:literals ([stmt item #:phase 1]) >> [(_ (stmt name:id num:exact-positive-integer)) >> #'(define name (record-item 'name num))])) >> >> (define-syntax-rule (program x ...) >> (begin (term x) ...))) >> >> >> *~slg* >> >> >> ‐‐‐‐‐‐‐ Original Message ‐‐‐‐‐‐‐ >> On Thursday, December 31, 2020 9:45 AM, Jay McCarthy < >> [email protected]> wrote: >> >> Are you trying to take a macro argument and ensure that it is an >> expression? If so, then you can expand into `#%expression` >> >> https://docs.racket-lang.org/reference/__expression.html >> >> On the other hand, if you are trying to take a macro argument and ensure >> that it is NOT an expression... then that means that you know what it is >> allowed to be, so I don't think there's any better way than to just >> enumerate what it CAN be. I think I would use a syntax class that specifies >> the allowable patterns and then use that. For example, in my little >> teachlog language, I have the `term` syntax class for this purpose >> >> https://github.com/jeapostrophe/teachlog/blob/master/main.rkt#L119 >> >> Looking at your code, I think what I would do is: >> 1) Define a phase-1 structure that represents one of these fields and an >> associated phase-0 function that records its values >> 2) Define `define-syntax` bindings for each particular field as an >> instance of these fields >> 3) Write `update` as a short `syntax-parse` that expects a list where the >> head is a static instance of the phase-1 structure and expands into an >> application of the associate phase-0 function on the arguments >> >> This would allow you to better abstract things so you don't have tie the >> `update` function to the particular fields. >> >> Jay >> >> -- >> Jay McCarthy >> Associate Professor @ CS @ UMass Lowell >> http://jeapostrophe.github.io >> Vincit qui se vincit. >> >> >> On Wed, Dec 30, 2020 at 10:20 PM Sage Gerard <[email protected]> wrote: >> >>> I'm trying to learn how to restrict where expressions appear. Those >>> expressions might be procedure applications, *or* macros before >>> expansion. >>> >>> [1] shows a library I use to help me implement a collection pass for a >>> module language. To save you some reading, it uses syntax-parse with a >>> lengthy #:datum-literals. That's the only way I know how to restrict what >>> expressions appear in module context. >>> >>> One element of the #:datum-literals happens to share an identifier with >>> a bound procedure, so I expand the calls as-is in a module-level expression >>> [2][3]. I want that procedure to be applied ONLY in the module context, but >>> nothing in the language enforces that. >>> >>> I don't know what I don't know. Could I please get a link to a part of >>> the documentation that teaches me what I need to understand? I'm tied >>> between querying syntax properties for a fully expanded module, and writing >>> a second set of macros that somehow know where they should be. Not sure >>> which is best. >>> >>> [1]: https://github.com/zyrolasting/xiden/blob/master/pkgdef/expand.rkt >>> [2]: >>> https://github.com/zyrolasting/xiden/blob/master/pkgdef/expand.rkt#L111 >>> [3]: >>> https://github.com/zyrolasting/xiden/blob/master/pkgdef/expand.rkt#L156 >>> >>> *~slg* >>> >>> >>> >>> -- >>> 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/bVbaZ_0mwFcWTIaeuwqMUr7TVY6Rhr5dusG9LkbT0gqW7gWIYAb8IOEUYnKQPIVR2ZrDGm9QMGnW-2YvYqw81oUJVCSCuwhuX_Wx2OGVG-w%3D%40sagegerard.com >>> <https://groups.google.com/d/msgid/racket-users/bVbaZ_0mwFcWTIaeuwqMUr7TVY6Rhr5dusG9LkbT0gqW7gWIYAb8IOEUYnKQPIVR2ZrDGm9QMGnW-2YvYqw81oUJVCSCuwhuX_Wx2OGVG-w%3D%40sagegerard.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/AqmR-7s3hD8k0bf_kMXDsZzwswfEDWXltrNMX4L8EmghOzqZdXHsptRiSANiepcq-m_JBjriooGpx8PbJmu9Bppci68ViREo6un9Fv0uXM0%3D%40sagegerard.com >> <https://groups.google.com/d/msgid/racket-users/AqmR-7s3hD8k0bf_kMXDsZzwswfEDWXltrNMX4L8EmghOzqZdXHsptRiSANiepcq-m_JBjriooGpx8PbJmu9Bppci68ViREo6un9Fv0uXM0%3D%40sagegerard.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/nV9CQYlVP_TDoZiSKSx9xKAATgrOhrG2z9Q5erXF04cza6pfHq3kUIPiTEUZX3HNOJeFVDrcbG-f6qHOYTT79yS6JPYKDM5KbtAdCbWoMdM%3D%40sagegerard.com > <https://groups.google.com/d/msgid/racket-users/nV9CQYlVP_TDoZiSKSx9xKAATgrOhrG2z9Q5erXF04cza6pfHq3kUIPiTEUZX3HNOJeFVDrcbG-f6qHOYTT79yS6JPYKDM5KbtAdCbWoMdM%3D%40sagegerard.com?utm_medium=email&utm_source=footer> > . > -- -- Jay McCarthy Associate Professor @ CS @ UMass Lowell http://jeapostrophe.github.io Vincit qui se vincit. -- 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/CAJYbDa%3DfTAvFUTVvbLvmwbtDHuU6uA7kkOg%3DSphj5Q6VTTBdTw%40mail.gmail.com.

