Skip to content

Commit 74e3e3d

Browse files
committed
Clarify docs to recommend extenders over attr_replace
Signed-off-by: Jack Rickard <[email protected]>
1 parent 4e10d5d commit 74e3e3d

File tree

1 file changed

+16
-10
lines changed

1 file changed

+16
-10
lines changed

doc/writing-ppxs.mld

+16-10
Original file line numberDiff line numberDiff line change
@@ -102,7 +102,7 @@ See below for examples on when the above name and context will trigger rewriting
102102
let _ = match () with [%add_suffix "payload"] -> () (* wrong context *)
103103
]}
104104

105-
{3:extender-payload The Payload Extraction}
105+
{3 The Payload Extraction}
106106

107107
An extension node contains a {{!Ppxlib.Parsetree.payload}[payload]}, which will be passed to the transformation function. However, while this payload contains all information, it is not always structured the best way for the transformation function. For instance, in [[%add_suffix "payload"]], the string ["payload"] is encoded as a structure item consisting of an expression’s evaluation, a constant that is a string.
108108

@@ -137,8 +137,7 @@ Building and inspecting AST nodes can be painful due to how
137137
modules to ease this generation, such as {{!Ppxlib.Ast_builder}[Ast_builder]},
138138
{!Ppxlib_metaquot}, {{!Ppxlib.Ast_pattern}[Ast_pattern]}, and {{!Ppxlib.Ast_traverse}[Ast_traverse]}, which are
139139
explained in their own chapters: {{!"generating-code"}Generating AST nodes},
140-
{{!"matching-code"}Destructing AST nodes} and {{!"ast-traversal"}Traversing AST
141-
nodes}.
140+
{{!"matching-code"}Destructing AST nodes} and {{!"ast-traversal"}Traversing AST nodes}.
142141

143142
In the example below, you can ignore the body of the function until reading
144143
those chapters.
@@ -360,11 +359,17 @@ in both structures and signatures.
360359

361360
{2 Attribute-guided Rewriting}
362361

363-
There are rules that apply to AST nodes that, like derivers, apply based on their
362+
[ppxlib] provides context-free rules that, like derivers, apply to nodes based on their
364363
attributes but, like extenders, allow rewriting the entire AST node. These provide
365364
lighter-weight syntax than extenders but that also means it's less obvious that they're
366365
rewriting the syntax tree.
367366

367+
Before using this kind of rule, carefully consider using an extender instead. [ppxlib]
368+
provides an opinionated syntax for preprocessors so that it's easy for users to understand
369+
what code is being affected by the PPX. In general, these should only be used to slightly
370+
modify the node the attribute is attached to, rather than rewrite it to something new.
371+
The syntax of extenders highlights to users where more involved rewriting is taking place.
372+
368373
These are composed of:
369374
- The name of the rewrite rule
370375
- The list of attributes they define
@@ -379,8 +384,8 @@ A given rewrite rule can have multiple attributes that trigger it, if any of the
379384
attributes are present on a single node then the rule is triggered and provided with the
380385
AST node along with the payload of all the attributes registered by this rule. To declare
381386
attributes use the {{!Ppxlib.Attribute.declare}[Attribute.declare]} function (or the other
382-
similar functions in that module). Note that the [Context.t] must match the type of AST
383-
nodes that the rule will apply to.
387+
similar functions in that module). Note that the {{!Ppxlib.Attribute.Context}[Context.t]}
388+
must match the type of AST nodes that the rule will apply to.
384389

385390
{@ocaml[
386391
# let prefix_attr = Attribute.declare "example.prefix" Expression
@@ -394,7 +399,7 @@ nodes that the rule will apply to.
394399
{3 The Expand Function}
395400

396401
The expand function takes the AST node (with this rule's attributes already stripped) and
397-
the payloads of all the declared attributes (as a list of [payload option]s to allow for
402+
the payloads of all the declared attributes (as a list of [payload option] to allow for
398403
attributes that haven't been included).
399404

400405
{@ocaml[
@@ -419,9 +424,10 @@ attributes that haven't been included).
419424
{3 Creating a rewriting rule}
420425

421426
Finally, we can create the rule using the appropriate
422-
{{!Ppxlib.Extension.Context}[Ppxlib.Extension.Context]} and register it with the driver.
423-
There's also a {{!Ppxlib.Context_free.attr_replace}[Context_free.attr_replace]} function
424-
with a slightly simpler API if you only use a single attribute.
427+
{{!Ppxlib.Extension.Context}[Ppxlib.Extension.Context]} and register it with the driver using
428+
{{!Ppxlib.Context_free.Rule.attr_multiple_replace}[Context_free.Rule.attr_multiple_replace]}.
429+
There's also a {{!Ppxlib.Context_free.Rule.attr_replace}[Context_free.Rule.attr_replace]}
430+
function with a slightly simpler API if you only use a single attribute.
425431

426432
{@ocaml[
427433
# let rewrite_rule = Context_free.Rule.attr_multiple_replace "example" Expression

0 commit comments

Comments
 (0)