janestreet / ppx_stable

Stable types conversions generator
MIT License
18 stars 2 forks source link

Renaming fields #2

Open cuihtlauac opened 1 year ago

cuihtlauac commented 1 year ago

It would be nice to be able to write something like this:

type person = {
  first : string;
  last : string;
  age : int;
}
type individual = {
  given : string;
  family : string;
  age : int;
} [@@deriving stable_record ~version:person ~rename:[(given, first); (family, last)])
neojski commented 1 year ago

Hi @cuihtlauac. We could technically add support for it but looks like we didn't find too many use cases for it internally. You can achieve the same thing by a combination of add & remove. Also, the proposed syntax would be quite inconsistent with what we have right now where the "label" is the field name and the "value" is a type. In your case the value is the renamed field which would be a bit confusing.

Although in your particular case, if the number of fields in the record is exactly three it woudl be more readable to simply write:

let individual_of_person { first; last; age } = { given = first; family = last; age }
cuihtlauac commented 1 year ago

Hi @neojski, thanks for answering, this is nice :-)

You can achieve the same thing by a combination of add & remove.

Do you mean this?

[@@deriving stable_record ~version:a ~remove:[given; family] ~add:[first; last])

Actually, I need first to be copied into given (and respectively, last into family). I'd like that copying to be generated automatically.

Also, the proposed syntax would be quite inconsistent with what we have right now where the "label" is the field name and the "value" is a type. In your case the value is the renamed field which would be a bit confusing.

Maybe there was a misunderstanding, there was a typo in my code sample, I've fixed it, sorry. Now ~version is passed a type and ~rename is passed a list of pairs of renamed fields. I believe it is fairly consistent with the existing syntax, if I'm not mistaken.

Although in your particular case, if the number of fields in the record is exactly three it woudl be more readable to simply write:


let individual_of_person { first; last; age } = { given = first; family = last; age }

I'm already writing definitions like that, except the records involved have many more fields and I have many such definitions, that's why I'd like to avoid writing them manually.

neojski commented 1 year ago

We'd normally write this code like that:

type person =
  { first : string
  ; last : string
  ; age : int (* age represents an awful lot of other fields *)
  }

type individual =
  { given : string
  ; family : string
  ; age : int
  }
[@@deriving
  stable_record ~version:person ~add:[ first; last ] ~remove:[ given; family ]]

let individual_to_person t = individual_to_person ~first:t.given ~last:t.family t

Would this work for you?

cuihtlauac commented 1 year ago

Thanks, the way you write it is indeed better. However, this is a manual shadowing of the individual_to_person function which was automatically generated. When there are many pairs of renamed fields or many shadowing definitions, it becomes pretty bureaucratic :-)

neojski commented 1 year ago

I left a comment on https://github.com/janestreet/ppx_stable/issues/3#issuecomment-1384335500 where I'm sceptical about it. I think I would be more willing to have support for renames, though.