Date: Tue, 29 Nov 2022 10:48:12 -0600
Yeah, type aliases are what I always end up going with, it's just
exceptionally non-ideal, especially if I decide to add more parameters. And
if I need/want some parameters to be optional or I want to add a type
that could be user defined, I'd have to make those template aliases. I will
also have to write nearly N many more aliases (where N is the size of the
other enum), if I add more values.
Macros seem like a good answer at first until you try to actually write the
macro generator for these and realize you're using nearly all the wild
macro hacks in the book and it only gets mildly better if you decide to
take on another dependency and use boost pp. I also theoretically would
want to give the enumerators special values instead of just 0 through N-1,
and that makes it even more complicated.
Another problem is that using macros to generate the N*M aliases I
hypothetically want means I have to essentially bundle both enumerations in
the macro logic, as well as the using statements. This also means I'd have
to use some forward declarations to make sure that my ABC::Color class
knows about the enums or that my aliases know about my Color class
(depending on where I place the macro). Not the end of the world, but just
more clutter.
But the real problem is that, while this appears to be a "simple" N*M
permutation generator, it actually isn't. Not every permutation makes
sense. Color_RGBA_332, for example, makes no sense, and that essentially
means I can't use a macro generator unless I want to break up my enums and
radically change my design. These aren't incredibly large enums, so writing
out the valid permutations by hand is fine, but it's not hard to see how
this could become a very suboptimal/error-prone experience if these enums
were larger or if there were more enums in play. I'm already going to have
to make template specializations for these, so ideally I could just lean on
those to throw a compile error for unimplemented permutations and not have
to redundantly type out all of the valid permutations and hope I got them
all or that I didn't make a typo along the way.
So, while I understand some of the reasons given for why we might not want
to do this, hopefully now you can at least appreciate the pain and my
motivation for wanting something like this in the language in some form or
another. I also don't think this is as niche as you might think it is. This
is not the first time I have stumbled into this mess and wanted some way
out, nor am I the only person who has.
Thanks,
Ryan Klaus
On Mon, Nov 28, 2022 at 12:10 PM Arthur O'Dwyer <arthur.j.odwyer_at_[hidden]>
wrote:
> On Mon, Nov 28, 2022 at 12:50 PM Ryan Klaus <rfklaus117_at_[hidden]> wrote:
>
>> Yeah, I knew it would be scary, but I braved it anyway because this has
>> been a recurring pain point for me and has often made me reach for less
>> satisfying alternatives or ones with other draw-backs that I'm not willing
>> to incur (macros limit the design/readability in other ways, among other
>> problems).
>>
>
> I think macros are a perfect solution to *your specific problem here*.
> There may be other situations where macros would cause problems, but this
> doesn't seem to be one of them.
>
>
>> [...]
>> I'm not sure what problem your last example is trying to demonstrate
>> though. I'm not sure if there is supposed to be an implied attribute on S?
>> I definitely wouldn't want enumeration values to be automatically
>> deduced without explicit say-so, which is why I proposed the "context"
>> attribute.
>> Regardless, the point that Peter brought up about ignorable attributes
>> (nice article on that, by the way!) is a good one and alone makes this a
>> less than solid proposal barring some alternative syntax.
>>
>
> Ah, I had completely missed that you were proposing this as only an opt-in
> syntax. That makes your proposed solution
> - much less risky in terms of changing existing semantics, and
> - much more well-specified in terms of what semantics you're actually
> proposing, but
> - much *much* more of a niche case, because now it requires the *library
> author* to use some special syntax, and if the library author *knew*
> about this problem, they'd simply not introduce the problem to begin with.
>
> For example, a library author who foresaw this use-case and wanted to make
> the syntax shorter could simply do
>
> namespace ABC {
> using Color_RGBA_8888 = Color<ColorComponents::RGBA,
> ColorComponentLayout::_8888>;
> }
>
> and then the use-case for the client becomes simply
>
> auto color = ABC::Color_RGBA_8888;
>
> This works already in C++11; no need for any attributes or macros or
> anything. (Although macros could still be helpful to generate all of the
> Color_X_Y type aliases, depending on how many of them there were.)
>
> A library author who doesn't foresee this use-case simply won't use your
> attribute, and then (as far as I can tell, now) you're simply proposing
> that there should be *nothing* the client can do at all (besides add
> their own macro or type alias).
>
> It's also worth noting that this is an O(1) problem. The client will write
> namespace My {
> using Color_RGBA_8888 = ABC::Color<ABC::ColorComponents::RGBA,
> ABC::ColorComponentLayout::_8888>;
> }
> in only one place in their entire codebase, so making this line a few
> characters shorter doesn't really buy us anything that's worth changing a
> whole language over.
>
> –Arthur
>
>>
exceptionally non-ideal, especially if I decide to add more parameters. And
if I need/want some parameters to be optional or I want to add a type
that could be user defined, I'd have to make those template aliases. I will
also have to write nearly N many more aliases (where N is the size of the
other enum), if I add more values.
Macros seem like a good answer at first until you try to actually write the
macro generator for these and realize you're using nearly all the wild
macro hacks in the book and it only gets mildly better if you decide to
take on another dependency and use boost pp. I also theoretically would
want to give the enumerators special values instead of just 0 through N-1,
and that makes it even more complicated.
Another problem is that using macros to generate the N*M aliases I
hypothetically want means I have to essentially bundle both enumerations in
the macro logic, as well as the using statements. This also means I'd have
to use some forward declarations to make sure that my ABC::Color class
knows about the enums or that my aliases know about my Color class
(depending on where I place the macro). Not the end of the world, but just
more clutter.
But the real problem is that, while this appears to be a "simple" N*M
permutation generator, it actually isn't. Not every permutation makes
sense. Color_RGBA_332, for example, makes no sense, and that essentially
means I can't use a macro generator unless I want to break up my enums and
radically change my design. These aren't incredibly large enums, so writing
out the valid permutations by hand is fine, but it's not hard to see how
this could become a very suboptimal/error-prone experience if these enums
were larger or if there were more enums in play. I'm already going to have
to make template specializations for these, so ideally I could just lean on
those to throw a compile error for unimplemented permutations and not have
to redundantly type out all of the valid permutations and hope I got them
all or that I didn't make a typo along the way.
So, while I understand some of the reasons given for why we might not want
to do this, hopefully now you can at least appreciate the pain and my
motivation for wanting something like this in the language in some form or
another. I also don't think this is as niche as you might think it is. This
is not the first time I have stumbled into this mess and wanted some way
out, nor am I the only person who has.
Thanks,
Ryan Klaus
On Mon, Nov 28, 2022 at 12:10 PM Arthur O'Dwyer <arthur.j.odwyer_at_[hidden]>
wrote:
> On Mon, Nov 28, 2022 at 12:50 PM Ryan Klaus <rfklaus117_at_[hidden]> wrote:
>
>> Yeah, I knew it would be scary, but I braved it anyway because this has
>> been a recurring pain point for me and has often made me reach for less
>> satisfying alternatives or ones with other draw-backs that I'm not willing
>> to incur (macros limit the design/readability in other ways, among other
>> problems).
>>
>
> I think macros are a perfect solution to *your specific problem here*.
> There may be other situations where macros would cause problems, but this
> doesn't seem to be one of them.
>
>
>> [...]
>> I'm not sure what problem your last example is trying to demonstrate
>> though. I'm not sure if there is supposed to be an implied attribute on S?
>> I definitely wouldn't want enumeration values to be automatically
>> deduced without explicit say-so, which is why I proposed the "context"
>> attribute.
>> Regardless, the point that Peter brought up about ignorable attributes
>> (nice article on that, by the way!) is a good one and alone makes this a
>> less than solid proposal barring some alternative syntax.
>>
>
> Ah, I had completely missed that you were proposing this as only an opt-in
> syntax. That makes your proposed solution
> - much less risky in terms of changing existing semantics, and
> - much more well-specified in terms of what semantics you're actually
> proposing, but
> - much *much* more of a niche case, because now it requires the *library
> author* to use some special syntax, and if the library author *knew*
> about this problem, they'd simply not introduce the problem to begin with.
>
> For example, a library author who foresaw this use-case and wanted to make
> the syntax shorter could simply do
>
> namespace ABC {
> using Color_RGBA_8888 = Color<ColorComponents::RGBA,
> ColorComponentLayout::_8888>;
> }
>
> and then the use-case for the client becomes simply
>
> auto color = ABC::Color_RGBA_8888;
>
> This works already in C++11; no need for any attributes or macros or
> anything. (Although macros could still be helpful to generate all of the
> Color_X_Y type aliases, depending on how many of them there were.)
>
> A library author who doesn't foresee this use-case simply won't use your
> attribute, and then (as far as I can tell, now) you're simply proposing
> that there should be *nothing* the client can do at all (besides add
> their own macro or type alias).
>
> It's also worth noting that this is an O(1) problem. The client will write
> namespace My {
> using Color_RGBA_8888 = ABC::Color<ABC::ColorComponents::RGBA,
> ABC::ColorComponentLayout::_8888>;
> }
> in only one place in their entire codebase, so making this line a few
> characters shorter doesn't really buy us anything that's worth changing a
> whole language over.
>
> –Arthur
>
>>
Received on 2022-11-29 16:48:25