# Help getting with started ppxlib

**URL:** <https://discuss.ocaml.org/t/help-getting-with-started-ppxlib/4103>\
**Category:** Learning\
**Created:** [July 16, 2019, 8:19am UTC](https://discuss.ocaml.org/t/help-getting-with-started-ppxlib/4103 "2019-07-16T08:19:07Z")\
**Posts on this page:** 5\
**Page:** 1

<div class="post-metadata">

**Author:** ![enetsee](https://sea2.discourse-cdn.com/flex020/user_avatar/discuss.ocaml.org/enetsee/32/1041_2.png) [@enetsee](https://discuss.ocaml.org/u/enetsee)\
**Post date:** [July 16, 2019, 8:19am UTC](https://discuss.ocaml.org/t/help-getting-with-started-ppxlib/4103/1 "2019-07-16T08:19:07Z")

</div>

Hi,

I would like to write a ppx rewriter which allows me to derive a ‘traversable’ given a type declaration. For example, given:

```ocaml
type litType = Int | Real | Str

type 'e expr =
  | Var of string
  | Lit of litType * string
  | FunApp of string * 'e list
  | TernaryIf of 'e * 'e * 'e
  | EAnd of 'e * 'e
  | EOr of 'e * 'e

```

I would like to be able to generate the following _module_ definition.

```ocaml
module Make_traversable_expr(A:Applicative.S) : Traversable.S 
    with type 'a t := 'a expr 
     and module A := A  
= struct
    
  let traverse x ~f = 
    match x with      
    | Var n -> 
       A.return @@ Var n 

    | Lit(ty,n) -> 
       A.return @@ Lit(ty,n)

    | FunApp(fn_kind,name,args) ->      
        List.map f args 
        |> A.all 
        |> A.map ~f:(fun args -> FunApp(fn_kind,name,args))        
 
    | TernaryIf(pred,te,fe) ->
        A.map3 ~f:(fun pred te fe -> TernaryIf(pred,te,fe)) (f pred) (f te) (f fe) 
       
    | EAnd(e1,e2) ->  
         A.map2 ~f:(fun e1 e2 -> EAnd(e1,e2) ) (f e1) (f e2)

    | EOr(e1,e2) ->  
         A.map2 ~f:(fun e1 e2 -> EOr(e1,e2) ) (f e1) (f e2)    

  end

```

Where `Applicative` is as defined in `Core_kernel` and `Traversable.S` is defined as:

```ocaml
module Traversable = struct
  
  module type S = sig
    module A : Applicative.S 
    type 'a t
    val traverse : 'a t -> f:('a -> 'b A.t) -> 'b t A.t
  end

end

```

My understanding is that [ppxlib](https://github.com/ocaml-ppx/ppxlib) is the framework within which ppx rewriters should now be written.

I’ve been reading through the [ppx\_show](https://gitlab.inria.fr/tmartine/ppx_show/tree/master) code by @thierry-martinez but I am making _very_ slow progress in building any sort of understanding.

Would anyone be willing to provide a brief explanation of what each of the three arguments below do?

My current understanding is that `str_type_decl` and `sig_type_decl` determines what should be generated ( a `Parsetree.structure` and `Parsetree.signature` respectively) when `@@deriving show` is attached to a structure or a signature but I’m not sure how they relate to `extension` (which generates a `Parsetree.expression`)

```auto
let deriver =
  Ppxlib.Deriving.add "show" ~str_type_decl ~sig_type_decl ~extension

```

I saw in [another thread](https://discuss.ocaml.org/t/ann-ppx-show-a-show-deriver-based-of-ppxlib-works-on-4-08-0/4026/5) that @gasche was looking for help porting the existing `ppx_deriving` rewriters over to ppxlib. If someone were able to give me some guidance I would be very happy to both contribute to this effort _and_ write this up in some detail so that others might have an easier time in doing so.

I don’t expect to be spoon-fed so any sort of guidance would be gratefully received!

Thanks,

Michael

---

<div class="post-metadata">

**Author:** ![leamingrad](https://sea2.discourse-cdn.com/flex020/user_avatar/discuss.ocaml.org/leamingrad/32/1616_2.png) [@leamingrad](https://discuss.ocaml.org/u/leamingrad)\
**Post date:** [July 16, 2019, 9:59am UTC](https://discuss.ocaml.org/t/help-getting-with-started-ppxlib/4103/2 "2019-07-16T09:59:43Z")

</div>

There are definitely people more qualified to help than me, but hopefully this is useful:

> My current understanding is that `str_type_decl` and `sig_type_decl` determines what should be generated ( a `Parsetree.structure` and `Parsetree.signature` respectively) when `@@deriving show` is attached to a structure or a signature but I’m not sure how they relate to `extension` (which generates a `Parsetree.expression` )

You are correct about the `str_type_decl` and `sig_type_decl` parts - they need to be `Deriving.Generator` instances that return chunks of AST when `[@@deriving]` is present in `struct` and `sig` declarations respectively.

I don’t think you need to worry about `extension`, as that is mostly for compatibility with `ppx_deriving`, which you don’t seem to be aiming for.

(Shameless plug) It might be worth looking at the [`ppx_enum source`](https://github.com/cryptosense/ppx_enum) which is a bit simpler than `ppx_show` as it doesn’t try to use extensions.

Some other useful resources:

- [An introduction to OCaml PPX ecosystem](https://tarides.com/blog/2019-05-09-an-introduction-to-ocaml-ppx-ecosystem.html) particularly the " How to write a PPX using `ppxlib`" section
- [Extension Points - 3 Years Later](http://rgrinberg.com/posts/extension-points-3-years-later/), which is also linked to a sample ppx at [GitHub - rgrinberg/ppx\_getenv2: Sample ppx to demo making, testing, and packaging a simple ppx rewriter](https://github.com/rgrinberg/ppx_getenv2)

---

<div class="post-metadata">

**Author:** ![enetsee](https://sea2.discourse-cdn.com/flex020/user_avatar/discuss.ocaml.org/enetsee/32/1041_2.png) [@enetsee](https://discuss.ocaml.org/u/enetsee)\
**Post date:** [July 16, 2019, 11:47am UTC](https://discuss.ocaml.org/t/help-getting-with-started-ppxlib/4103/3 "2019-07-16T11:47:27Z")

</div>

> - [https://tarides.com/blog/2019-05-09-an-introduction-to-ocaml-ppx-ecosystem.html](https://tarides.com/blog/2019-05-09-an-introduction-to-ocaml-ppx-ecosystem.html) particularly the " How to write a PPX using `ppxlib` " section

This looks great! (I thought I’d tracked down _all_ the ppx blogs / tutorials…). Thanks for the linked repo, too.

> I don’t think you need to worry about `extension` , as that is mostly for compatibility with `ppx_deriving` , which you don’t seem to be aiming for.

Do you know what the implications of this will be if I am also using `ppx_deriving` for `map`, `fold`, etc.?

Cheers,

Michael

---

<div class="post-metadata">

**Author:** ![leamingrad](https://sea2.discourse-cdn.com/flex020/user_avatar/discuss.ocaml.org/leamingrad/32/1616_2.png) [@leamingrad](https://discuss.ocaml.org/u/leamingrad)\
**Post date:** [July 16, 2019, 12:15pm UTC](https://discuss.ocaml.org/t/help-getting-with-started-ppxlib/4103/4 "2019-07-16T12:15:13Z")

</div>

> Do you know what the implications of this will be if I am also using `ppx_deriving` for `map` , `fold` , etc.?

My understanding is that won’t interact as long as there isn’t a naming conflict.

---

<div class="post-metadata">

**Author:** ![emillon](https://sea2.discourse-cdn.com/flex020/user_avatar/discuss.ocaml.org/emillon/32/1206_2.png) [@emillon](https://discuss.ocaml.org/u/emillon)\
**Post date:** [July 16, 2019, 12:38pm UTC](https://discuss.ocaml.org/t/help-getting-with-started-ppxlib/4103/5 "2019-07-16T12:38:36Z")

</div>

Just to clarify, the `extension` argument is to support turning `[%show: My.Module.something]` into `My.Module.show_something`; it’s not strictly required.
