Rescript: ppx, macro support?

Does ReScript support ppx / macros? If so, where is this documented ? If not, is this one area where ReScript diverges from OCaml ?

You will find a lot of interesting posts if you search for posts mentioning ppx on this forum. There have been many, many, throughout the years, and you will even find posts from Hongbo (here is one example) and other team members discussing this question.

1 Like

Just to make it clear…I think this is an interesting question. But the answer about the status of ppx, and whether it is encouraged, I think isn’t too straightforward.

I’m currently working through the manual: Pipe | ReScript Language Manual

It would be really helpful if someone with authority could add an official statement on ppx / macros to the reference manual.

Although digging through the forums is more efficient than digging through the source code, it’s really efficient if every new comer to ReScript has to dig through the forums to answer a basic question.

I’m not disagreeing with you; there probably should be a stronger statement in the manual. There is this statement in the manual at least. And as for people with authority chiming in, again, they have in the forums. As to why some of it hasn’t made it to the docs, I cannot say. But it may be worth opening an issue on the docs, if you think a stronger clarifying statement is needed than the one here provides.

Edit: it is currently the case that many “advanced” features aren’t exactly covered in-depth the manual, but are discussed in the forums. So I think it is an explicit choice of those who have written the manual.

2 Likes

I mis-interpreted your original post as RTF-FP (read the “friendly” forum posts), which was a bit annoying given I was working exhaustively through the manual.

However, upon further research, it does seem your advice is ‘optimal’ in that ppx seems to be in this weird ‘purgatory’ of:

(1) it appears to be, at least in some form, supported in ReScript

(2) there appears to be no examples in the manual

(3) devs appear to strongly discourage its use (possibly due to reserving the right for future breaking changes?)

I will concede that in this case there is really no option besides reading the forum posts as it seems the issue is still being debated. :slight_smile:

1 Like

My apologies for not being clearer in my original post; it wasn’t my intent to be dismissive of your question.

Not your fault, my fault. I incorrectly assumed (1) there was a simple answer and (2) you were telling me to RTFM, when in reality, (1) there was no simple answer and (2) the most ‘official’ statement was the link you provided. LOL. :slight_smile:

In my experience a more ‘encouraged’ approach has been codegen. It’s a bit more annoying to set up, but it doesn’t depend on any compiler internals, so the team doesn’t discourage it like they do PPX.

2 Likes

how are you doing codegen @yawaramin ?

Recently bitten by ppx,
Alex

I personally haven’t used it yet, but atdgen is probably the most successful pure codegen example in ReScript: GitHub - TheSpyder/bs-atdgen-generator: Pre-compiled versions of atdgen binaries to be consumed from ReScript projects

It generates JSON codecs from schema files.

There has also been discussion of SQL codegen, I haven’t seen anything concrete for ReScript yet but sqlgg does exist in the OCaml world so we know it’s possible.

2 Likes

There is also GitHub - cca-io/rescript-react-intl-extractor: Extracts messages for localization from ReScript source files. by @cknitt.
This was a good starting point for a gql-schema generator we are working on at my company which is unfortunately closed source atm.

2 Likes

One day we’re hoping we can package up and provide a lot of the utilities and so on we’ve built for the editor tooling. Would make for a pretty powerful base for building various codegen things when you need to tap into the syntax/AST or the actual type information produced by the compiler.

5 Likes

I started a code gen for sql. It works somehow, but I decided to start another approach, because I didn’t like it.
For simplicity I just combined functions which produces string representations of rescript types. If I run the code e.g. “node db_codege.bs.js” it prints the results to the console. Then I piped the output to a “db.res”.

If you’re interested… GitHub - dkirchhof/rescript-sql-typegen

To elaborate a bit:
We started our experiments to generate a gql-schema based on rescript types with writing a ppx, but we hit a couple of limits for our goal.

A completely separate generator, which parses the codebase has (for us) the most important benefit, that the generator is able to “know” about and optimize over the whole codebase. - instead of just the location where the extension was found.
Furthermore, we don’t need the generator to run at every build. We can use watch with rescript’s high performance and only run the generator when needed (or in ci).

It would be nice, if we (the community) could find some best practices on how to write generators for rescript.


I liked the idea, which @cknitt uses in his extractor to use extensions / “ppx-notations” in the codebase but not registering any ppx for it in bsconfig. Therefore the compiler ignores these extensions during build. The generator (which parses the codebase) recognizes these extensions and acts on them.

6 Likes

I’d love to discuss this more in depth (codegen in ReScript) because this is something I’ve spent a lot of time thinking about, and I have a lot of ideas. I also think it’d be valuable if we could come up with a good set of best practices, like you say @woeps, including the tooling/infra needed to do good codegen.

But, I feel this is starting to get slightly off topic :smile: @woeps maybe you could start a new thread detailing your thoughts (and your use case, it sounds interesting), and we can do a general discussion about codegen in ReScript and what we can do to make that a great experience?

4 Likes

@zth I’ll be happy to start a new thread, but it will take me some time to come up with a meaningful summary

1 Like

Note: I haven’t been following this since marking the problem as solved.

If it matters, as the OP, you have my permission to hijack this thread.