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

Customizable code generation #105

Open
bitc opened this issue Jul 20, 2020 · 4 comments
Open

Customizable code generation #105

bitc opened this issue Jul 20, 2020 · 4 comments

Comments

@bitc
Copy link

bitc commented Jul 20, 2020

This is probably most relevant for the Haskell generator, but maybe could be interesting for other languages.

In Haskell there are many different styles for defining records:

  • Prefixed or non-prefixed field names. Example: personName, personAge vs name, age. Some teams prefer a 3rd alternative: person_name, person_age. The non-prefixed alternative usually requires the OverloadedRecordFields extension.

  • Various typeclass instances should be derived. Most people always want (Show, Eq, Ord). But some teams also will always want additional instances for things like Read or Hashable or Binary. Each team will have their own preference and standards.

  • Support for lenses / optics / others. Each team has there own way of doing this, some using generic-lens, some use generic-lens-labels, others use generic-optics or generic-optics-lite, etc... In the future there will be new alternatives...

  • Strict fields or not (Related to Generated Haskell records should have strict fields #97)

I think it would be too cumbersome to try to make ADL natively support all of these different styles (whether through command line flags or ADL annotations). And people would always come up with their own personal use case that isn't supported.

I think a better approach would be some kind of plugin-system, where users would be able to write their own custom code that would generate the Haskell source files.

For me personally, it is crucial that the ADL generated code will use non-prefixed record names, and will have support for lens/optics (depending on the project). But I know that everyone will have their own preference, which is why I propose this idea to allow customization.

Thank you

@timbod7
Copy link
Collaborator

timbod7 commented Jul 20, 2020

There is already some support for "plugin" or custom code generators:

One runs adlc in ast mode, and after parsing and checking the adl source, a single json file is written containing the ast. The json has adl type StringMap<sys.adlast.Module>. Then, a custom code generator written in any of ADL's target languages can be used to generate arbitrary code from the typed ADL AST.

This approach has been used for a variety of purposes - eg we use it for generating sql schemas from adl definitions.

Having said that, it's quite an undertaking to implement from scratch a generator for a language like haskell that supports all ADL features.

I'm wondering what a plugin customization approach would look like (as you suggest). It seems to sit somewhere between "writing a new generator from scratch" as above, and a growing list of annotations on the existing generator.

@timbod7
Copy link
Collaborator

timbod7 commented Jul 20, 2020

Note that your first customization on prefixed fields is already handled with the existing HaskellFieldPrefix annotation.

And the need for optics generation is raised here: #58

@bitc
Copy link
Author

bitc commented Jul 21, 2020

I suppose that it is possible that annotations could work for most of this stuff (ADL's annotation merging feature is very useful here!).

But I am a bit worried that for most of these things, you want to make the decision once on the project level, and not have to copy-paste the same annotations onto every single ADL declaration that you write.

For me personally, optics are very important, I will be following #58 👍

Thank you

@timbod7
Copy link
Collaborator

timbod7 commented Jul 22, 2020

not have to copy-paste the same annotations onto every single ADL declaration that you write.

The interpretation of annotations is up to the various language backends. But where appropriate, annotations can be applied at the module level, to affect all declarations in that module.

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

No branches or pull requests

2 participants