Skip to content

ppx: allow dropping arbitrary values with [@drop_default]#77

Open
zazedd wants to merge 1 commit intomelange-community:mainfrom
zazedd:main
Open

ppx: allow dropping arbitrary values with [@drop_default]#77
zazedd wants to merge 1 commit intomelange-community:mainfrom
zazedd:main

Conversation

@zazedd
Copy link

@zazedd zazedd commented Feb 6, 2026

This PR allows [@drop_default] to drop default values provided by [@default].
It also changes [@drop_default] to potentially accept a function for comparison. If no function is provided, then structural equality is used.

[@drop_default] with [@option] remains unchanged

Not sure if ppx_compare works with melange. If yes I can change this PR to be closer to how ppx_yojson_conv implements their similar feature

Motivation

It brings melange-json closer to being able to substitute atd, and makes sense as an extension of the [@drop_default] attribute, which currently makes melange-json unable to fully express some records without making fields needlessly optional

@andreypopp
Copy link
Collaborator

I wonder if we can do the following:

  • have [@drop_default] require equal_<type> to be present for the corresponding types
  • have [@drop_default_if_json_equal] uses Melange_json.equal (to be added)

that way we won't be relying on structural equality

@zazedd
Copy link
Author

zazedd commented Feb 10, 2026

Sounds good.

To be clear, we want to replace structural equality by equal_<type>, which has to be available in the scope if [@drop_default] is used in flag mode with [@default]? Can the user can still provide a comparison function f of his accord using [@drop_default f]?

Melange_json.equal (to be added)

This should be easy to add, but I'll just leave it commented out since Melange_json.equal isn't here yet

@andreypopp
Copy link
Collaborator

To be clear, we want to replace structural equality by equal_, which has to be available in the scope if [@drop_default] is used in flag mode with [@default]?

Yes

Can the user can still provide a comparison function f of his accord using [@drop_default f]?

Can keep that too, I guess.

This should be easy to add, but I'll just leave it commented out since Melange_json.equal isn't here yet

Let's add it? Should be pretty easy.

@zazedd zazedd force-pushed the main branch 4 times, most recently from 994e673 to 4b1cc93 Compare February 11, 2026 14:03
@zazedd
Copy link
Author

zazedd commented Feb 11, 2026

Updated

  • Melange_json.equal and [@drop_default_if_json_equal] implemented
  • [@drop_default] with equal_<type> implemented. In the case of parameterized types, the equal function takes the inner type's equal as a parameter, e.g. int list generates equal_list equal_int

Please check correctness of Melange_json.equal for JS. Native is easy enough since we have Yojson's comparison function, but for JS it is always scary to write all those Obj.magic's 😅

Copy link
Collaborator

@andreypopp andreypopp left a comment

Choose a reason for hiding this comment

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

thanks! (left a small nit comment though)

Comment on lines 97 to 105
| Ptyp_constr ({ txt = Lident name; _ }, args) ->
let fn = pexp_ident ~loc { loc; txt = lident ("equal_" ^ name) } in
List.fold_left (List.rev args) ~init:fn ~f:(fun acc arg ->
pexp_apply ~loc acc [ Nolabel, equal_of_core_type ~loc arg ])
| Ptyp_constr ({ txt = Ldot (prefix, name); _ }, args) ->
let name = if name = "t" then "equal" else "equal_" ^ name in
let fn = pexp_ident ~loc { loc; txt = Ldot (prefix, name) } in
List.fold_left (List.rev args) ~init:fn ~f:(fun acc arg ->
pexp_apply ~loc acc [ Nolabel, equal_of_core_type ~loc arg ])
Copy link
Collaborator

Choose a reason for hiding this comment

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

Copy link
Author

Choose a reason for hiding this comment

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

Oh nice, I didn't know about this. Updated

@andreypopp
Copy link
Collaborator

@anmonteiro @jchavarri @davesnx anything we missed here? If no objections/comments, I'm going to merge in the coming days.

@davesnx
Copy link
Member

davesnx commented Feb 18, 2026

I might prefer to have [@drop_default] and [@drop_default { equal }] rather than a separate extension, so users could [@drop_default { equal: Melange_json.equal }] or some other fn

but that can also be added/improved later

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.

3 participants