digitalmars.D - Define an order for allMembers traits
- Andrey Zherikov (39/39) Aug 23 2023 D doc for for `__traits(allMembers, ...)`
- Adam D Ruppe (3/5) Aug 23 2023 What do you do with the order of declaration?
- Andrey Zherikov (29/34) Aug 23 2023 I'm developing a [library to parse command line
- Stefan Koch (9/45) Aug 23 2023 My 10 cents on this are:
- Alexandru Ermicioi (8/12) Aug 23 2023 No lexical, please. It would be worse, than order in which
- Adam D Ruppe (7/21) Aug 23 2023 tbh I actually prefer this code to the alternative
- Andrey Zherikov (3/5) Aug 23 2023 I don't see that the order of tupleof is specified for structs
- John Colvin (4/40) Aug 23 2023 Just sort allMembers by .offsetof? You might need a small amount
- Adam D Ruppe (6/8) Aug 23 2023 Adds quite a bit of potential complication - what if two things
- Richard (Rikki) Andrew Cattermole (15/15) Aug 23 2023 Another way to do this (which should be defined):
- Paul Backus (6/18) Aug 23 2023 For this use case, you should use `.tupleof` instead of
- Andrey Zherikov (5/9) Aug 23 2023 This link says "The order of the fields in the tuple matches the
- Paul Backus (6/16) Aug 23 2023 The spec isn't totally clear, but I believe the intent is to say
- Timon Gehr (5/16) Aug 23 2023 Well, it refers to the class version and I think it is clear that it
- Walter Bright (5/7) Aug 23 2023 Yes. It is written the way it is because I was writing a lot of text in ...
D doc for for `__traits(allMembers, ...)` [says](https://dlang.org/spec/traits.html#allMembers) that "the order in which the strings appear in the result is not defined". Is it possible to define an order at least for some cases (I'm looking for structs actually)? I think having guaranteed order for simple cases in beneficial: ```d struct S { int a,b; string c,d; } assert([ __traits(allMembers, S) ] == [ "a","b","c","d" ]); ``` This will especially help in my use case where I need to know the order in which struct members are declared. Right now I'm using UDA with index to explicitly set an order: ```d struct S { UDA(1) int a; UDA(2) int b; UDA(3) string c; UDA(4) string d; } ``` Possible solution would be to use `__LINE__` but it won't work in this case: ```d struct S { UDA int a; UDA int b; } ``` The only solution that might work is to use `__traits(getLocation, ...)` which complicates introspection a lot: instead of simple usage of `__traits(allMembers, ...)` I'll have to sort all members by location and only then iterate over them.
Aug 23 2023
On Wednesday, 23 August 2023 at 12:32:58 UTC, Andrey Zherikov wrote:Is it possible to define an order at least for some cases (I'm looking for structs actually)?What do you do with the order of declaration?
Aug 23 2023
On Wednesday, 23 August 2023 at 12:39:09 UTC, Adam D Ruppe wrote:On Wednesday, 23 August 2023 at 12:32:58 UTC, Andrey Zherikov wrote:I'm developing a [library to parse command line arguments](https://github.com/andrey-zherikov/argparse). One type of arguments is positional argument which means that they have a position in command line. As of now (because the order of `allMembers` is not defined), these arguments are attributed the following way by explicitly providing the order: ```d struct Params { PositionalArgument(0) string firstName; PositionalArgument(1) string middleName; PositionalArgument(2) string lastName; } ``` If `allMembers` guarantees the order to be the same as the members are declared then the code above can be simplified to this: ```d struct Params { PositionalArgument string firstName, middleName, lastName; } ```Is it possible to define an order at least for some cases (I'm looking for structs actually)?What do you do with the order of declaration?
Aug 23 2023
On Wednesday, 23 August 2023 at 13:53:30 UTC, Andrey Zherikov wrote:On Wednesday, 23 August 2023 at 12:39:09 UTC, Adam D Ruppe wrote:My 10 cents on this are: In the general case we cannot guarantee the order of __traits(allMembers) as they might be generated by meta-programming which does not have an obvious execution order. So the question is we guarantee lexical order in the cases where no meta programming is used to introduce members? I think we can do that.On Wednesday, 23 August 2023 at 12:32:58 UTC, Andrey Zherikov wrote:I'm developing a [library to parse command line arguments](https://github.com/andrey-zherikov/argparse). One type of arguments is positional argument which means that they have a position in command line. As of now (because the order of `allMembers` is not defined), these arguments are attributed the following way by explicitly providing the order: ```d struct Params { PositionalArgument(0) string firstName; PositionalArgument(1) string middleName; PositionalArgument(2) string lastName; } ``` If `allMembers` guarantees the order to be the same as the members are declared then the code above can be simplified to this: ```d struct Params { PositionalArgument string firstName, middleName, lastName; } ```Is it possible to define an order at least for some cases (I'm looking for structs actually)?What do you do with the order of declaration?
Aug 23 2023
On Wednesday, 23 August 2023 at 14:24:46 UTC, Stefan Koch wrote:... So the question is we guarantee lexical order in the cases where no meta programming is used to introduce members? I think we can do that.No lexical, please. It would be worse, than order in which elements are declared. At least with the later, you could also use it for some meaningful order, such as first declared takes priority for some action, or etc. Having it all sorted lexical would hinder it. Besides, lexical ordering can also be done already at compile time.
Aug 23 2023
On Wednesday, 23 August 2023 at 13:53:30 UTC, Andrey Zherikov wrote:```d struct Params { PositionalArgument(0) string firstName; PositionalArgument(1) string middleName; PositionalArgument(2) string lastName; } ```tbh I actually prefer this code to the alternativeIf `allMembers` guarantees the order to be the same as the members are declared then the code above can be simplified to this:but yeah, what others say about the tuple thing is prolly the best thing by spec tho in practice allMembers is in order but relying on that might lead to troube some random day
Aug 23 2023
On Wednesday, 23 August 2023 at 16:52:36 UTC, Adam D Ruppe wrote:but yeah, what others say about the tuple thing is prolly the best thing by specI don't see that the order of tupleof is specified for structs there.
Aug 23 2023
On Wednesday, 23 August 2023 at 13:53:30 UTC, Andrey Zherikov wrote:On Wednesday, 23 August 2023 at 12:39:09 UTC, Adam D Ruppe wrote:Just sort allMembers by .offsetof? You might need a small amount of compile time gymnastics but it’s doable.On Wednesday, 23 August 2023 at 12:32:58 UTC, Andrey Zherikov wrote:I'm developing a [library to parse command line arguments](https://github.com/andrey-zherikov/argparse). One type of arguments is positional argument which means that they have a position in command line. As of now (because the order of `allMembers` is not defined), these arguments are attributed the following way by explicitly providing the order: ```d struct Params { PositionalArgument(0) string firstName; PositionalArgument(1) string middleName; PositionalArgument(2) string lastName; } ``` If `allMembers` guarantees the order to be the same as the members are declared then the code above can be simplified to this: ```d struct Params { PositionalArgument string firstName, middleName, lastName; } ```Is it possible to define an order at least for some cases (I'm looking for structs actually)?What do you do with the order of declaration?
Aug 23 2023
On Thursday, 24 August 2023 at 00:11:07 UTC, John Colvin wrote:Just sort allMembers by .offsetof? You might need a small amount of compile time gymnastics but it’s doable.Adds quite a bit of potential complication - what if two things have the same offset of? What if they don't have one? Doing this without care can bloat compile times too... but yeah, it was my first thought too tbh, with the appropriate filters you can make that work.
Aug 23 2023
Another way to do this (which should be defined): ```d void main() { S s; static foreach(f; s.tupleof) { pragma(msg, __traits(identifier, f)); } } struct S { int a, b; union { string c, d; } } ```
Aug 23 2023
On Wednesday, 23 August 2023 at 12:32:58 UTC, Andrey Zherikov wrote:This will especially help in my use case where I need to know the order in which struct members are declared. Right now I'm using UDA with index to explicitly set an order: ```d struct S { UDA(1) int a; UDA(2) int b; UDA(3) string c; UDA(4) string d; } ```For this use case, you should use `.tupleof` instead of `__traits(allMembers)`, which [is guaranteed by the spec to give the fields in declaration order][1]. [1]: https://dlang.org/spec/class.html#class_properties
Aug 23 2023
On Wednesday, 23 August 2023 at 15:32:02 UTC, Paul Backus wrote:For this use case, you should use `.tupleof` instead of `__traits(allMembers)`, which [is guaranteed by the spec to give the fields in declaration order][1]. [1]: https://dlang.org/spec/class.html#class_propertiesThis link says "The order of the fields in the tuple matches the order in which the fields are declared" for the classes. I don't see such statement for structs [here](https://dlang.org/spec/struct.html#struct_instance_properties).
Aug 23 2023
On Wednesday, 23 August 2023 at 16:28:27 UTC, Andrey Zherikov wrote:On Wednesday, 23 August 2023 at 15:32:02 UTC, Paul Backus wrote:The spec isn't totally clear, but I believe the intent is to say that it works the same way for structs unless otherwise stated. Certainly, in practice, the fields are always in declaration order.For this use case, you should use `.tupleof` instead of `__traits(allMembers)`, which [is guaranteed by the spec to give the fields in declaration order][1]. [1]: https://dlang.org/spec/class.html#class_propertiesThis link says "The order of the fields in the tuple matches the order in which the fields are declared" for the classes. I don't see such statement for structs [here](https://dlang.org/spec/struct.html#struct_instance_properties).
Aug 23 2023
On 8/23/23 18:28, Andrey Zherikov wrote:On Wednesday, 23 August 2023 at 15:32:02 UTC, Paul Backus wrote:Well, it refers to the class version and I think it is clear that it must be ordered. Anyway, if you don't trust this for some reason, you can always just sort by "offsetof". (Provided you don't want to use empty static arrays.)For this use case, you should use `.tupleof` instead of `__traits(allMembers)`, which [is guaranteed by the spec to give the fields in declaration order][1]. [1]: https://dlang.org/spec/class.html#class_propertiesThis link says "The order of the fields in the tuple matches the order in which the fields are declared" for the classes. I don't see such statement for structs [here](https://dlang.org/spec/struct.html#struct_instance_properties).
Aug 23 2023
On 8/23/2023 2:17 PM, Timon Gehr wrote:Well, it refers to the class version and I think it is clear that it must be ordered.Yes. It is written the way it is because I was writing a lot of text in the spec and didn't want to repeat things. Another problem with repetition is the texts will inevitably diverge, and then the poor reader wonders why they are different.
Aug 23 2023