Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Let macros yield to other macros with the same name #241

Open
gelisam opened this issue May 18, 2024 · 2 comments
Open

Let macros yield to other macros with the same name #241

gelisam opened this issue May 18, 2024 · 2 comments

Comments

@gelisam
Copy link
Owner

gelisam commented May 18, 2024

We sometimes define a single macro which checks whether they are in the expression Problem or the type Problem and then behaves accordingly.

(define-macros
  ([m (lambda (stx)
        (>>= (which-problem)
          (lambda (prob)
            (case prob
              [(declaration)  (pure '(example (the (m) (m))))]
              [(type)         (pure 'Bool)]
              [(expression t) (pure 'true)]
              [(pattern)      (pure 'unit)]))))]))

We have discussed the following alternative, in which several macros (perhaps provided by different libraries) cooperate in order to provide the above behaviour. The way in which the cooperate is that each one indicates whether or not they are applicable to the current situation, and if there is only one macro which is applicable, then that's the macro whose returned Syntax object is used.

(define-macros
  ([m (lambda (stx)
        (>>= (which-problem)
          (lambda (prob)
            (case prob
              [(declaration)  (pure '(example (the (m) (m))))]
              [_ (not-applicable)]))))]
   [m (lambda (stx)
        (>>= (which-problem)
          (lambda (prob)
            (case prob
              [(type) (pure 'Bool)]
              [_ (not-applicable)]))))]
   [m (lambda (stx)
        (>>= (which-problem)
          (lambda (prob)
            (case prob
              [(expression t) (pure 'true)]
              [_ (not-applicable)]))))]
   [m (lambda (stx)
        (>>= (which-problem)
          (lambda (prob)
            (case prob
              [(pattern) (pure 'unit)]
              [_ (not-applicable)]))))]))
@gelisam
Copy link
Owner Author

gelisam commented May 18, 2024

Hmm, if there are four distinct bindings to m coming from different libraries, what's the bahaviour of (free-identifier=? 'm my-identifier)? Would it only return true if both identifiers see the same set of m bindings?

@gelisam
Copy link
Owner Author

gelisam commented May 18, 2024

One alternative would be to have one main binding which states that the behaviour of m will obtained that way:

(define-combining-macro m)

And then to have each sub-definition refer to this main m binding, to indicate that it wants to contribute to this combining-macro:

(extend-combining-macro m
  (lambda (stx)
    (>>= (which-problem)
      (lambda (prob)
        (case prob
          [(declaration)  (pure '(example (the (m) (m))))]
          [_ (not-applicable)])))))

This way, free-identifier=? would only have to check whether the two identifiers see the same main m binding. They would behave the same, even if a different set of extend-combining-macro m definitions are in scope for each, because each such definition would affect the behaviour of m calls as a side-effect.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant