[ANN] ppx_yojson: a ppx extension for Yojson literals and patterns

ppx
json
yojson

#1

Hi,

I’m happy to announce the release of ppx_yojson a rewriter for all of you out there working with Yojson. Version 0.1.0 provides an extension to write Yojson literal expressions in a more concise and readable way.

As an example, you can write:

let json = [%yojson {some_string = "string"; some_list = [1; 2; 3]}]

instead of:

let json =
  `Assoc
    [ ("some_string", `String "string")
    ; ("some_list", `List [`Int 1; `Int 2; `Int 3])
    ]

It’s available on github and opam.
There’s more to come soon, including extensions for patterns and antiquotations. You can see the full list of features goals for the 1.0.0 here.


#2

This is very cool!

Something to keep in mind for future pattern matching support - since yojson represents JSON objects as lists, key order matters if the list is matched directly. It would be nice if that order dependence could be avoided. Maybe could be worked around by generating a set of parallel match cases with each list order permutation (which could be heavy) or by generating something with when cases.

Sorry to drop this implementation discussion here! It looks like the issue tracker is locked from external comments.


#3

No worries!

I wanted to keep the feature tracking issue clean but feel free to open a separate issue if you have suggestions!

It is indeed a concern. I’m not sure exactly what’s the best way to handle those but I like the idea of the or-pattern with permutations because it would compose nicely with a binding anti-quotation extension. It could indeed be heavy for objects with an important number of fields. I assume most yojson users also use ppx_deriving_yojson which would prevent from the need of writing pattern-matching on such large json objects by hand.

In fact I’m not 100% sold on the value of a pattern extension. The only cases where I write a pattern-matching on a Yojson value are parsers that need to be retro-compatible with older format and usually look like:

let of_yojson = function
  | `List _ as json -> legacy_of_yojson json
  | json -> of_yojson json

if it used to be represented as a json array and is now represented as a json string for instance. In such cases the ppx version of it would most likely be longer than the original.

I still want to do it though. If it turns out to be really useful to someone then it’s great and I’d be happy to discuss their specific use case and needs.