Skip to content

Add AST section to examples #545

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

Open
wants to merge 4 commits into
base: ppx-by-example
Choose a base branch
from

Conversation

pedrobslisboa
Copy link
Contributor

@pedrobslisboa pedrobslisboa commented Dec 15, 2024

41 files where: 20 are pngs and 8 are old examples files deleted. So don't be scared

Captura de Tela 2024-12-15 às 19 11 58
Captura de Tela 2024-12-15 às 19 12 57

Description

This is the first part of adding the ppx-by-example to ppxlib
I will divide it into PR so we can review it better, focusing on the explanation and typos without having tons of files to review. It is really necessary that this section is easy to understand and is aligned with ppxlib.
@NathanReb Can you create a ppx-by-example base branch? So I can point this one to it, and after all merges (Other sections) on this branch, we move with the entire ppx-by-example branch to main?

AST

This PR adds the AST sections AST / Building ASTs / Destructing ASTs

How to test it (It's important to check it not only by code but also as styles)

  • At this branch run
     make doc
     open _build/default/_doc/_html/ppxlib/index.html
  • Access Examples
  • Access each section:
    • AST
    • Building an AST
    • Destructing an AST

Makefile Outdated
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@NathanReb I've made some improvements on Makefile, can you check out if it makes sense?

The main feature is to add doc-dev, but I also added the help command

@pedrobslisboa
Copy link
Contributor Author

pedrobslisboa commented Dec 23, 2024

@patricoferris Tagging you for the review as you reacted to this PR

doc/dune Outdated
Comment on lines 10 to 12
(system "mkdir -p %{project_root}/_doc/_html/ppxlib/assets/images")
(system "cp -R ./images/ %{project_root}/_doc/_html/ppxlib/assets/images/"))))
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Btw, I didn't know any other way to get assets on odoc. Do you guys happen to know?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@NathanReb @patricoferris I know that Odoc v3 supports it; maybe there is no alternative other than due to a hack similar to this one. Do you guys know a better hack?

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Indeed, this hack will unfortunately not work for the documentation generated for ocaml.org.

The proper way to do it is to:

  • install the image files in the odoc-pages folder of the doc (see this example for how to do it with dune)
  • Include it with the odoc3 syntax, in your case {image!filename.png}

The tooling support for for odoc 3 is still under construction, so dune won't yet be able to build the documentation with the images... however, odoc_driver can and soon dune and ocaml.org will be able to do it! You would be one of the first users of images the odoc 3 way!

(Another way to do it is to use permalinks to the image eg {image:https://github.com/ocaml-ppx/ppxlib/<hash>/filename.png})

I also wonder if turning some images into text wouldn't be better for accessibility.

Copy link
Contributor Author

@pedrobslisboa pedrobslisboa May 28, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@panglesd Thanks for the review. I followed the idea of having it as text/code instead, and I loved how it is right now.

Before After
Captura de Tela 2025-05-28 às 16 17 09 Captura de Tela 2025-05-28 às 16 12 35

The only sad part is that the Highlight is missing. However, it is still cleaner, and people can copy/paste the code.

@pedrobslisboa pedrobslisboa force-pushed the examples/ast branch 5 times, most recently from 7bf1887 to 2aeef20 Compare December 27, 2024 21:12
@NathanReb
Copy link
Collaborator

@pedrobslisboa just pushed a ppx-by-example branch, sorry for the delay!

@pedrobslisboa pedrobslisboa changed the base branch from main to ppx-by-example January 6, 2025 21:33
Signed-off-by: Pedro B S Lisboa <[email protected]>
@pedrobslisboa pedrobslisboa force-pushed the examples/ast branch 2 times, most recently from 737d517 to f08cc55 Compare May 2, 2025 12:04
@NathanReb
Copy link
Collaborator

I just updated the ppx-by-example branch and rebased it on top of main.

Can you please rebase this @pedrobslisboa ? I'll review straight away!

Signed-off-by: Pedro B S Lisboa <[email protected]>
Signed-off-by: Pedro B S Lisboa <[email protected]>
Makefile Outdated
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@NathanReb, I've made some improvements on Makefile. Does it make sense?

The main feature is to add the example to the makefile, but I also added the help command.
image

@pedrobslisboa
Copy link
Contributor Author

I just updated the ppx-by-example branch and rebased it on top of main.

Can you please rebase this @pedrobslisboa ? I'll review straight away!

Rebased and ready for review.

Signed-off-by: Pedro B S Lisboa <[email protected]>
@pedrobslisboa
Copy link
Contributor Author

🏓

Copy link
Collaborator

@patricoferris patricoferris left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for all of the hardwork here -- I've started a review. In general, I like the idea of having more documentation like this, but I do worry about the maintenance overhead if we don't try to automate some of this.


{1:building-asts-with-pure-ocaml Building ASTs with Low-Level Builders}

The most fundamental way to build an AST is to manually construct it using Low-Level Builders data structures.
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I was a little confused what Low-Level Builders meant. Looking at the example it seems we could perhaps rephrase this as something like "building values from the {! Parsetree} directly" ?

- {b Using {!Ppxlib.Ast_builder}}: A more readable and maintainable option.
- {b Using Metaquot}: The most intuitive method, especially when combined with Anti-Quotations for dynamic values.

Each method has its strengths, so choose the one that best fits your needs. Understanding all three will give you greater flexibility in creating effective and maintainable PPXs.
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think we should tell our users to use Ast_builder or Metaquot -- having just gone through a big merge for the internal AST bump we have greater control and flexibility in helping users migrate if they use these two approaches over building AST nodes. What do you think @pedrobslisboa ?


{1:description Description}

Building an AST (Abstract Syntax Tree) is a fundamental part of creating a PPX in OCaml. You'll need to construct an AST to represent the code you want to generate or transform.
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
Building an AST (Abstract Syntax Tree) is a fundamental part of creating a PPX in OCaml. You'll need to construct an AST to represent the code you want to generate or transform.
Building an abstract syntax tree (AST) is a fundamental part of creating a PPX in OCaml. You'll need to construct an AST to represent the code you want to generate or transform.


Building an AST (Abstract Syntax Tree) is a fundamental part of creating a PPX in OCaml. You'll need to construct an AST to represent the code you want to generate or transform.

For example, if you want to generate the following code:
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It seems to me that it might be a little confusing to say "generate the following code", the reader may think this code is what the ppx might generate when in fact it seems to the be the starting point of the example. Maybe something like "For example, if we have the following code: ... and we wish to replace"

let zero = [%int 0]
]}

and replace the extension point [%int 0] with [0] to produce [let zero = 0], you’ll need to build an AST that represents this transformation.
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
and replace the extension point [%int 0] with [0] to produce [let zero = 0], you’ll need to build an AST that represents this transformation.
and replace the extension point [[%int 0]] with [0] to produce [let zero = 0], you’ll need to build an AST that represents this transformation.

@@ -0,0 +1,80 @@
open Ppxlib
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I wonder if it would make more sense if these code snippets lived alongside the docs themselves. In conjunction with mdx that could help keep everything up to date?

The previous examples that lived here were more end-to-end examples that I think should be kept.

{[
let let_expression =
let expression =
Ast_builder.Default.pexp_constant ~loc:Location.none
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If we can, I think we want to try and suggest best practices and not have write ~loc:Location.none, how about this becomes a let let_expression ~loc = or we open a module where ~loc is defined which is usually what we suggest doing?


{1:ast-structure-pattern-matching AST Structure Pattern Matching}

The most fundamental method for destructuring an AST in PPXLib is by directly matching on the AST’s structure.
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looking through the current documentation and README, it seems to me that we tend to write Ppxlib rather than PPXLib. Perhaps we could even change all occurrences of PPXLib into {! Ppxlib}.

pstr (pstr_eval (eint (int 1)) nil ^:: nil)
]}

Using [eint] instead of [pexp_constant] and [pconst_integer] provides better type safety. The [int] wildcard captures the integer value.
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
Using [eint] instead of [pexp_constant] and [pconst_integer] provides better type safety. The [int] wildcard captures the integer value.
Using [eint] instead of [pexp_constant] and [pconst_integer] provides better type safety. The [int] combinator captures the integer value.

I'm not entirely sure about the claim of "better type safety", I think eint is just a short-hand for the same code:

let eint t = pexp_constant (const_int t)
?

You can further simplify it:

{[
let match_int_payload =
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can we further simplify this to:

let match_int_payload =
  let open Ast_pattern in
  single_expr_payload (eint (int 1))

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

Successfully merging this pull request may close these issues.

4 participants