drym-org / qi

An embeddable flow-oriented language.
58 stars 12 forks source link

Should Qi provide syntax/parse? #27

Open countvajhula opened 2 years ago

countvajhula commented 2 years ago

[See Qi macro: generalized sieve (partition)]

The options here seem to be:

  1. Don't provide syntax/parse (the current behavior)
  2. Provide it
  3. Don't provide the macro module by default in (require qi), and provide syntax/parse with (require qi/macro)
  4. Don't provide the macro module by default in (require qi), and don't provide syntax/parse with (require qi/macro) either

For (1): The drawback is that users need to (require syntax/parse) in order to use syntax patterns and syntax classes. The benefit is that it's more explicit, and is symmetric with usual Racket behavior of having to do this in defining Racket macros. Yet, the difference here is that we have the forms define-qi-syntax-rule without having to require something like qi/syntax-parse which is not the case in Racket.

For (2): The drawback with (2) is that users would need to (except-in ...) if they happen to already require syntax/parse in the module, which could be annoying, especially if they aren't using Qi macros (but are using Racket macros). The benefit is that users who haven't already required syntax/parse in the module would have access to syntax patterns and classes without an additional (require syntax/parse)

For (3): This seems to be a good compromise where users would only need to (except-in ...) if they are already using syntax/parse in the module and they specifically mean to write Qi macros as well. It would be backwards incompatible however, and not sure if there are any other concerns with exporting all of syntax/parse that aren't talked about here (e.g. would it take up more memory / slow down the loading of the requiring module?).

For (4): A final possibility for completeness is the same as (3) but without providing syntax/parse, so that the macro module is required only on demand, and likewise syntax/parse too must be explicitly required. This is the most conservative option, but may have some benefits (e.g. lower memory / require-time latency? Is this a real concern?). This too is backwards incompatible.

In choosing a solution, it would be ideal of course to avoid breaking backwards compatibility, but at this stage of development it is better to do the right thing than commit to supporting a wrong thing that may be a design error. So backwards compatibility should perhaps be considered a tie breaker rather than the main consideration.

For the moment, the usage for (1) has been better documented (e.g. in Defining Macros as well as in Common Encountered Errors).

Opinions ~welcome~ needed!