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.

Reply via email to