Date: Sun, 12 May 2024 15:00:51 -0400
Hi,
My two cents on this topic.
I believe user defined attributes is not a bad idea per-se. Serialization /
deserialization is simply one of the use-cases. There's others, like
command-line parsing (annotating the cmdline flag corresponding to the
field name), python bindings (picking whether return type of a function is
returned to python as a reference or as a value), I think the list goes on.
My favorite syntax for this is Golang's annotation (source of snippet :
https://www.makeuseof.com/reflection-in-go/). Of course we won't want this
in C++ but just as an example.
```
type User struct {
Name string `json:"name" required:"true"`
}
user := User{"John"}
field, ok := reflect.TypeOf(user).Elem().FieldByName("Name")
fmt.Println(field.Tag, field.Tag.Get("required"))
```
Anyhow, there's various reasons I think as to why this is not a
make-or-break thing right now. Some of those are mentioned here in P2911
<https://wg21.link/P2911> under the section "Customization". The gist of my
thoughts:
1. Customization at the point of definition is not the only way to do
things. As shown in P2996 Command Line Arguments II
<https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2024/p2996r2.html#parsing-command-line-options-ii>
section,
if we're willing to do a little bit more work, we can get away with a
decent interface. Especially if there's no existing point of definition. If
there is, then the approach mentioned in P2911 earlier works similarly. But
without the define_class from in the P2996 link.
2. Customization at the point of definition is also not applicable in
situations where you don't have control over the source code.
Hopefully, if someday user-defined attributes do land, they would be made
to work with P2996 and we'll have the ideal choice (customization at the
point of definition, or at the point of use). That would certainly make
serialization libraries better UX wise.
Regards,
Saksham
On Sun, May 12, 2024 at 11:24 AM ykiko via SG7 <sg7_at_[hidden]> wrote:
> I think P2996 lacks an important feature, that is, customized metadata for
> reflection. As we all know, we can serialize and deserialize struct
> automatically through static reflection, but sometimes, for some fields
> (maybe private), we want to skip it. It is a common demand, But
> unfortunately, there is no way to allow users to attach metadata to fields
> in P2996 currently.
>
> In other languages, customized metadata is widely used. For example, we
> can mark a field *[JsonIgnore] *in *C#*
> <https://www.newtonsoft.com/json/help/html/PropertyJsonIgnore.htm> and
> *#[serde(skip_deserializing)] *in *Rust*
> <https://serde.rs/field-attrs.html#skip> to skip fields for
> serialization. Besides, although C++ does not have reflection now, some
> frameworks implement reflection on their own through code generation. They
> all support customized metadata. For example, *UPROPERTY
> <https://docs.unrealengine.com/4.27/en-US/ProgrammingAndScripting/GameplayArchitecture/Properties/> *in
> UE and *Q_PROPERTY <https://doc.qt.io/qt-6/properties.html> *in QT. Clang
> and GCC also support an attribute to expose metadata in AST, which is
> [[clang::annotate("")]]; some code generation tools use it to customize
> metadata.
>
> So, in my opinion, we cannot write a serialization library based on P2996
> that is as convenient as those in other languages without a way to allow
> users to customize metadata. I suggest adding a new attribute *[[annotate(constant-expression,
> ...)]] *to allow users to attach metadata to some entries. And, we can
> use reflection to get the annotations of entries.
>
> This topic may be related to the proposal *Attributes Introspection. *And
> the idea is at an early stage, any suggestion is welcome.
>
> ykiko.
> --
> SG7 mailing list
> SG7_at_[hidden]
> https://lists.isocpp.org/mailman/listinfo.cgi/sg7
>
My two cents on this topic.
I believe user defined attributes is not a bad idea per-se. Serialization /
deserialization is simply one of the use-cases. There's others, like
command-line parsing (annotating the cmdline flag corresponding to the
field name), python bindings (picking whether return type of a function is
returned to python as a reference or as a value), I think the list goes on.
My favorite syntax for this is Golang's annotation (source of snippet :
https://www.makeuseof.com/reflection-in-go/). Of course we won't want this
in C++ but just as an example.
```
type User struct {
Name string `json:"name" required:"true"`
}
user := User{"John"}
field, ok := reflect.TypeOf(user).Elem().FieldByName("Name")
fmt.Println(field.Tag, field.Tag.Get("required"))
```
Anyhow, there's various reasons I think as to why this is not a
make-or-break thing right now. Some of those are mentioned here in P2911
<https://wg21.link/P2911> under the section "Customization". The gist of my
thoughts:
1. Customization at the point of definition is not the only way to do
things. As shown in P2996 Command Line Arguments II
<https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2024/p2996r2.html#parsing-command-line-options-ii>
section,
if we're willing to do a little bit more work, we can get away with a
decent interface. Especially if there's no existing point of definition. If
there is, then the approach mentioned in P2911 earlier works similarly. But
without the define_class from in the P2996 link.
2. Customization at the point of definition is also not applicable in
situations where you don't have control over the source code.
Hopefully, if someday user-defined attributes do land, they would be made
to work with P2996 and we'll have the ideal choice (customization at the
point of definition, or at the point of use). That would certainly make
serialization libraries better UX wise.
Regards,
Saksham
On Sun, May 12, 2024 at 11:24 AM ykiko via SG7 <sg7_at_[hidden]> wrote:
> I think P2996 lacks an important feature, that is, customized metadata for
> reflection. As we all know, we can serialize and deserialize struct
> automatically through static reflection, but sometimes, for some fields
> (maybe private), we want to skip it. It is a common demand, But
> unfortunately, there is no way to allow users to attach metadata to fields
> in P2996 currently.
>
> In other languages, customized metadata is widely used. For example, we
> can mark a field *[JsonIgnore] *in *C#*
> <https://www.newtonsoft.com/json/help/html/PropertyJsonIgnore.htm> and
> *#[serde(skip_deserializing)] *in *Rust*
> <https://serde.rs/field-attrs.html#skip> to skip fields for
> serialization. Besides, although C++ does not have reflection now, some
> frameworks implement reflection on their own through code generation. They
> all support customized metadata. For example, *UPROPERTY
> <https://docs.unrealengine.com/4.27/en-US/ProgrammingAndScripting/GameplayArchitecture/Properties/> *in
> UE and *Q_PROPERTY <https://doc.qt.io/qt-6/properties.html> *in QT. Clang
> and GCC also support an attribute to expose metadata in AST, which is
> [[clang::annotate("")]]; some code generation tools use it to customize
> metadata.
>
> So, in my opinion, we cannot write a serialization library based on P2996
> that is as convenient as those in other languages without a way to allow
> users to customize metadata. I suggest adding a new attribute *[[annotate(constant-expression,
> ...)]] *to allow users to attach metadata to some entries. And, we can
> use reflection to get the annotations of entries.
>
> This topic may be related to the proposal *Attributes Introspection. *And
> the idea is at an early stage, any suggestion is welcome.
>
> ykiko.
> --
> SG7 mailing list
> SG7_at_[hidden]
> https://lists.isocpp.org/mailman/listinfo.cgi/sg7
>
Received on 2024-05-12 19:01:07