Alright, thank you for sticking with this. I'm refactoring now.

~slg

‐‐‐‐‐‐‐ Original Message ‐‐‐‐‐‐‐
On Friday, January 1, 2021 11:56 AM, Jay McCarthy <[email protected]> 
wrote:

> 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/xhOV-HJg6LAeonQMsnR0YYbbZjGOE8R6e5comR-j0RFDcc0liOMYs3-evzakJI7pOlFFNVzqPy0bguWls1pZHVkhas8NtexR2M2aLn0ujVc%3D%40sagegerard.com.

Reply via email to