-
Notifications
You must be signed in to change notification settings - Fork 100
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
base: ppx-by-example
Are you sure you want to change the base?
Add AST section to examples #545
Conversation
3c7b85f
to
e5e4945
Compare
6a2f1e9
to
6ad21fe
Compare
6ad21fe
to
160f335
Compare
Makefile
Outdated
There was a problem hiding this comment.
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
@patricoferris Tagging you for the review as you reacted to this PR |
doc/dune
Outdated
(system "mkdir -p %{project_root}/_doc/_html/ppxlib/assets/images") | ||
(system "cp -R ./images/ %{project_root}/_doc/_html/ppxlib/assets/images/")))) |
There was a problem hiding this comment.
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?
There was a problem hiding this comment.
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?
There was a problem hiding this comment.
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.
There was a problem hiding this comment.
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 |
---|---|
![]() |
![]() |
The only sad part is that the Highlight is missing. However, it is still cleaner, and people can copy/paste the code.
7bf1887
to
2aeef20
Compare
@pedrobslisboa just pushed a |
2aeef20
to
e585e65
Compare
Signed-off-by: Pedro B S Lisboa <[email protected]>
737d517
to
f08cc55
Compare
I just updated the ppx-by-example branch and rebased it on top of Can you please rebase this @pedrobslisboa ? I'll review straight away! |
f08cc55
to
8ce22a4
Compare
Signed-off-by: Pedro B S Lisboa <[email protected]>
Signed-off-by: Pedro B S Lisboa <[email protected]>
8ce22a4
to
91b7524
Compare
Makefile
Outdated
There was a problem hiding this comment.
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.
Rebased and ready for review. |
91b7524
to
fc8fb70
Compare
Signed-off-by: Pedro B S Lisboa <[email protected]>
fc8fb70
to
c215825
Compare
🏓 |
There was a problem hiding this 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. |
There was a problem hiding this comment.
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. |
There was a problem hiding this comment.
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. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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: |
There was a problem hiding this comment.
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. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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 |
There was a problem hiding this comment.
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 |
There was a problem hiding this comment.
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. |
There was a problem hiding this comment.
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. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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:
Line 226 in b3c240e
let eint t = pexp_constant (const_int t) |
You can further simplify it: | ||
|
||
{[ | ||
let match_int_payload = |
There was a problem hiding this comment.
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))
41 files where: 20 are pngs and 8 are old examples files deleted. So don't be scared
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 entireppx-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)