question about an enumeration within another enumeration lazarus / 62-General ---------------------------------------------------------------------- 440bx · 2020-07-28 19:06 Hello, I'd like to have an enumeration be a "superset" of another enumeration.  For instance:Code: Pascal  [Select][+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i type  TENUMERATION_A = (a, b, c);   TENUMERATION_B =  (    a, b, c,       { TENUMERATION_A                  }     k, l, m        { enumeration A plus other values }  ); ENUMERATION_B is a superset of ENUMERATION_A. Is there a way to define ENUMERATION_B as consisting of all the elements in ENUMERATION_A plus a few other elements without having to re-state the elements of ENUMERATION_A in ENUMERATION_B ?  (this is undesirable because it is easy to change ENUMERATION_A and forget to make the same change in ENUMERATION_B). Essentially, something along the lines of : Code: Pascal  [Select][+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i type  TENUMERATION_A = (a, b, c);   TENUMERATION_B =  (    TENUMERATION_A,     k, l, m           { enumeration A plus other values }  );  Thank you for your help. ---------------------------------------------------------------------- Blaazen · 2020-07-28 19:32 The only way is probably enum+range: Code: Pascal  [Select][+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i type  TEA = (a, b, c, d, e, f);  TEB = a..c; ---------------------------------------------------------------------- MarkMLl · 2020-07-28 20:11 Quote from: 440bx on July 28, 2020, 09:06:03 pmIs there a way to define ENUMERATION_B as consisting of all the elements in ENUMERATION_A plus a few other elements without having to re-state the elements of ENUMERATION_A in ENUMERATION_B ?  (this is undesirable because it is easy to change ENUMERATION_A and forget to make the same change in ENUMERATION_B). Ouch. It's something I've asked (in the ML) in the past, my application being e.g. a class to represent a storage device and a subclass to represent a storage device with a write-protect switch. I think that the answer I got involved shuffling feet and shifty expressions... it was agreed that something like that could be useful, but there was no real way of doing it. I think the consensus was that the best way was to fully-populate the enumeration, then to use subsets... but I can't remember quite where that got to in terms of range checking etc. It might be that since the original discussion- which I think was in around 2013/4- things have changed. MarkMLl ---------------------------------------------------------------------- howardpc · 2020-07-28 20:31 Blaazen's suggestion is the only way I know currently to get close to what you want. In fact the LCL uses this technique in several places, e.g. (from Controls): Code: Pascal  [Select][+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i   TFormBorderStyle = (bsNone, bsSingle, bsSizeable, bsDialog, bsToolWindow, bsSizeToolWin);  TBorderStyle = bsNone..bsSingle; ---------------------------------------------------------------------- ASBzone · 2020-07-28 20:46 It would absolutely be a nice to have feature... ---------------------------------------------------------------------- MarkMLl · 2020-07-28 21:05 It would probably be possible to have some convoluted OO-based solution, but this isn't LISP and IMO it's wrong to try to sugar-coat linguistic shortcomings using runtime complexity. I suppose that another approach would be to have a build-time operation merge subrange types into a master type, which was not normally visible as part of the source. I'm pretty sure that e.g. the Linux kernel does that sort of thing, but whether it's desirable from a readability POV is questionable. It might be possible to have some intermediate approach where the parent unit declares the master range as a sequence of obfuscated identifiers, each other unit assigns sensible names as aliases of some of those identifiers and registers the ones it wants, and then there's a sequence of runtime checks for overlaps and gaps. But quite frankly I prefer good language design to excessive use of registration and runtime manipulation. MarkMLl ---------------------------------------------------------------------- ASBzone · 2020-07-28 22:21 Quote from: MarkMLl on July 28, 2020, 11:05:00 pmI suppose that another approach would be to have a build-time operation merge subrange types into a master type, which was not normally visible as part of the source. I'm pretty sure that e.g. the Linux kernel does that sort of thing, but whether it's desirable from a readability POV is questionable. Why would it have to be that complicated? On the back-end, all that is needed is for each instance of an enumerated type to be expanded when it shows up on the right side of an equation within the type declaration. Code: Pascal  [Select][+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i type  TSmallEnum = (Mary, Jane, Sue);  TLargeEnum = TSmallEnum + (Bob, Larry, Michael, Sally, Cheryl);  ...would be expanded by the compiler as: Code: Pascal  [Select][+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i type  TSmallEnum = (Mary, Jane, Sue);  TLargeEnum = (Mary, Jane, Sue, Bob, Larry, Michael, Sally, Cheryl);  And whatever is used by the compiler to allow subsets, could be used to handle supersets. It might involve turning it, behind the scenes, into something more equivalent to: Code: Pascal  [Select][+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i type  TLargeEnum = (Mary, Jane, Sue, Bob, Larry, Michael, Sally, Cheryl);  TSmallEnum = Mary..Sue;  This way, the compiler gets most of what it wants, and the developers gets the benefits he or she wants too. ---------------------------------------------------------------------- 440bx · 2020-07-28 22:34 @Blaazen That's nice.  Thank you for suggesting it.  Unfortunately, it doesn't get close enough. Quote from: howardpc on July 28, 2020, 10:31:10 pmBlaazen's suggestion is the only way I know currently to get close to what you want. I concur.  I could not think of any way to do it.  I figured I'd ask the question just in case someone had figured a way of doing it. @ASBzone Code: Pascal  [Select][+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i type  TSmallEnum = (Mary, Jane, Sue);  TLargeEnum = TSmallEnum + (Bob, Larry, Michael, Sally, Cheryl); That, is _exactly_ what I want. I'm "afraid" of asking for compiler features now (previous experience in that area has not been very "fulfilling") but, that is a really nice feature and one that is really easy to implement.  It would be nice if the FPC priests would give asylum to a heaven forgotten feature. Thank you everyone for the help and input. ---------------------------------------------------------------------- jamie · 2020-07-28 23:55 Looks almost like a function of Bit naming in a record where by you can specify a range of bits with an identifier and the compiler can pick out of a 32 or 64 bit various identifiers which are bit groups.  The Sets basically work on the same level more or less.., at least the idea is the same.   I suppose you could construct a record with these bit files in it.   Just an idea. ---------------------------------------------------------------------- MarkMLl · 2020-07-29 06:58 Quote from: ASBzone on July 29, 2020, 12:21:30 amWhy would it have to be that complicated? Because I'm speculating about what can be currently done, not what could potentially be done by modifying the compiler... and I suspect that the developers would have a lot to be said about adding + etc. into type definitions. MarkMLl ---------------------------------------------------------------------- marcov · 2020-07-29 07:06 Quote from: ASBzone on July 29, 2020, 12:21:30 am Why would it have to be that complicated? Because after 5 seconds somebody tries a few things and posts the following bug Code: Pascal  [Select][+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i type  TSmallEnum = (Mary, Jane, Sue);  TSmallEnum2 = (Kate);  TLargeEnum = TSmallEnum +  TSmallEnum2 + (Bob, Larry, Michael, Sally, Cheryl);  This is all logical with "+" semantics ---------------------------------------------------------------------- PascalDragon · 2020-07-29 07:42 Quote from: ASBzone on July 29, 2020, 12:21:30 amOn the back-end, all that is needed is for each instance of an enumerated type to be expanded when it shows up on the right side of an equation within the type declaration. Code: Pascal  [Select][+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i type  TSmallEnum = (Mary, Jane, Sue);  TLargeEnum = TSmallEnum + (Bob, Larry, Michael, Sally, Cheryl);  And what would the behavior be with $ScopedEnums On? Would it be TLargeEnum.Mary or TSmallEnum.Mary? If the latter would this mean that duplicates are allowed, so that I could have a TSmallEnum.Mary and a TLargeEnum.Mary? What if I mix enums that are declared as $ScopedEnums On and those without? ---------------------------------------------------------------------- howardpc · 2020-07-29 08:00 You can of course always typecast enums, and perpetrate this sort of silliness: Code: Pascal  [Select][+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i program EnumTypecast; type   TWeekendDays = (weFri, weSat, weSun);   TWeekDays = (Mon=-4, Tue, Wed, Thu, Fri, Sat, Sun); var  weekend: TWeekendDays; begin  for weekend in TWeekendDays do    Write(TWeekDays(weekend), ' ');  ReadLn;end. ---------------------------------------------------------------------- MarkMLl · 2020-07-29 08:18 Quote from: marcov on July 29, 2020, 09:06:27 amBecause after 5 seconds somebody tries a few things and posts the following bug I'd already got there. It needs a compile-time extensor notation, not a runtime operator. Some sort of type helper? MarkMLl ---------------------------------------------------------------------- MarkMLl · 2020-07-29 08:21 Quote from: howardpc on July 29, 2020, 10:00:25 amYou can of course always typecast enums, and perpetrate this sort of silliness: Although as I said earlier, that would need a modicum of discipline from the user to ensure that overlaps and gaps were explicitly detected. And I really don't like devolving that kind of check to runtime. MarkMLl ---------------------------------------------------------------------- howardpc · 2020-07-29 08:28 Which is why I called such typecasting silliness. Especially if enums are saved to file and a corrupt file is later read you can immediately get a crash from undefined values, as numerous posts on the ML and this forum in times past testify. ---------------------------------------------------------------------- 440bx · 2020-07-29 08:38 Quote from: PascalDragon on July 29, 2020, 09:42:14 amQuote from: ASBzone on July 29, 2020, 12:21:30 amOn the back-end, all that is needed is for each instance of an enumerated type to be expanded when it shows up on the right side of an equation within the type declaration. Code: Pascal  [Select][+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i type  TSmallEnum = (Mary, Jane, Sue);  TLargeEnum = TSmallEnum + (Bob, Larry, Michael, Sally, Cheryl);  And what would the behavior be with $ScopedEnums On? Would it be TLargeEnum.Mary or TSmallEnum.Mary? If the latter would this mean that duplicates are allowed, so that I could have a TSmallEnum.Mary and a TLargeEnum.Mary? What if I mix enums that are declared as $ScopedEnums On and those without? First, for the record, I am _not_ asking for this feature to be implemented but, I'd like to answer your question. Also first, the use of the "+" sign is not ideal from an implementation viewpoint.  @Marcov pointed out some of the problems and there are more if it were implemented using "+". The answer to your question about the scoped enums is that the compiler should see  TLargeEnum.Mary as being the same constant as TSmallEnum.Mary.  The compiler could be "informed" of that by using an "inheritance" mechanism instead of "+".  Something along the lines of "TLargeEnum(TSmallEnum) = (additional constants here);"  effectively making a TSmallEnum a subset of TLargeEnum (just as an ancestor is always a member of its descendants in OOP). The real problem comes when declaring sets of enumerations built like that.  It would be common for a TSmallEnum to require only 32bits to represent the set but, the larger enum(s) may require more, yet, since one is a subset of the other, the sets should be the same size and the compiler cannot know that at the time it find TSmallEnum.  The inefficient but safe approach would be to make all sets derived from enumerated types accommodate the maximum number of elements (256 at this time) and possibly add the option to calculate the optimal size with a second "pass/compile" (wpo ? - global program optimization) The other way would be to allow a set declaration to be done only on the larger set and emit an error on a set declared for the smaller enum when and if a larger one is found later in the code.  Also, a prophylactic restriction would be to allow only a single inheritance chain since an inheritance tree would really complicate matters for the compiler and be a source of confusion for programmers. ---------------------------------------------------------------------- MarkMLl · 2020-07-29 08:42 Quote from: howardpc on July 29, 2020, 10:28:46 amWhich is why I called such typecasting silliness. Especially if enums are saved to file and a corrupt file is later read you can immediately get a crash from undefined values, as numerous posts on the ML and this forum in times past testify. You could argue against untagged variant records in exactly the same way, and they're been in Pascal (although possibly not Wirth's later languages) ab initio. I was actually trying to be positive back there. I didn't mean "this is a dumb idea", I meant "this is something that could probably be done usefully in the compiler, and having a robust and efficient compilation-time implementation is far superior to the sort of runtime hack beloved of the LISP brigade". MarkMLl ---------------------------------------------------------------------- marcov · 2020-07-29 09:09 Quote from: MarkMLl on July 29, 2020, 10:18:58 amQuote from: marcov on July 29, 2020, 09:06:27 amBecause after 5 seconds somebody tries a few things and posts the following bug I'd already got there. It needs a compile-time extensor notation, not a runtime operator. Some sort of type helper? I meant that you need syntax that is basically a kind of single derivation. So the syntax should reflex that an enum can only use one other enum, and can only append values. Probably also enums that set values by hand should be excluded. ---------------------------------------------------------------------- glorfin · 2020-07-29 10:24 QuoteI'd like to have an enumeration be a "superset" of another enumeration. Maybe sets would serve you better than enumerations? With sets you can easily do such things. ---------------------------------------------------------------------- ASBzone · 2020-07-29 12:38 Quote from: marcov on July 29, 2020, 09:06:27 amQuote from: ASBzone on July 29, 2020, 12:21:30 am Why would it have to be that complicated? Because after 5 seconds somebody tries a few things and posts the following bug Code: Pascal  [Select][+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i type  TSmallEnum = (Mary, Jane, Sue);  TSmallEnum2 = (Kate);  TLargeEnum = TSmallEnum +  TSmallEnum2 + (Bob, Larry, Michael, Sally, Cheryl);  This is all logical with "+" semantics While I like possibilities that this potential feature would bring, and while I am sorta, kinda, defending it at the moment, I want to be clear that the constructs I chose were for effectively conveying the concept, and not laying down the definitive syntax.    I figured that "+" would be problematic (having looked at various threads in the past on various feature requests). The main gist of my comment is this:  The construct is assembled at compile time, and could possibly be done along the lines of what is currently allowed, even if the visual representation the developer uses is different. But I was serious about understanding what the flaws would be, because I know that many seemingly simple requests have significant underlying drawbacks or complexities. If we overlook the "+" debate for a second, I still don't see a problem with the example you gave, which could be converted behind the scenes to: Code: Pascal  [Select][+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i type    TLargeEnum = (Mary, Jane, Sue, Kate, Bob, Larry, Michael, Sally, Cheryl);  TSmallEnum = Mary..Sue;    TSmallEnum2 = Kate..Kate;  Now, I have to address the points that @PascalDragon made... ---------------------------------------------------------------------- ASBzone · 2020-07-29 12:52 Quote from: PascalDragon on July 29, 2020, 09:42:14 amAnd what would the behavior be with $ScopedEnums On? Would it be TLargeEnum.Mary or TSmallEnum.Mary? If the latter would this mean that duplicates are allowed, so that I could have a TSmallEnum.Mary and a TLargeEnum.Mary? What if I mix enums that are declared as $ScopedEnums On and those without? You compiler developers...   Sigh...  (Said affectionately) The easy, but annoying answer would be that those two features are mutually exclusive.  Either you get $EnumSupersets or you get $ScopedEnums. I'm intrigued enough to give it a little more thought this week, but thus far, the issues that you have raised in these few questions are significant enough that I wouldn't want to have to open up the can of worms any further than what has been suggested so far. I think it would be more consistent, if this superset functionality were available at all, that it could not be mixed with $ScopedEnums at all.  Whether that means a total exclusivity (as I said in the sentence above) or just that no enum superset could be part of a scoped enum (while both are active at the same time), would be up for discussion, but in looking at the two features, it seems far more prudent to avoid trying to meld them in any way. (BTW, I appreciate you and @marcov and others responding to my query on this.   The enlightenment is helpful.) ---------------------------------------------------------------------- ASBzone · 2020-07-29 12:59 Quote from: 440bx on July 29, 2020, 10:38:53 amThe answer to your question about the scoped enums is that the compiler should see  TLargeEnum.Mary as being the same constant as TSmallEnum.Mary.  The compiler could be "informed" of that by using an "inheritance" mechanism instead of "+".  Something along the lines of "TLargeEnum(TSmallEnum) = (additional constants here);"  effectively making a TSmallEnum a subset of TLargeEnum (just as an ancestor is always a member of its descendants in OOP). Thanks for this additional perspective.  Do you see this as being a better option than just forbidding that combination (as per my recent post)? ---------------------------------------------------------------------- PascalDragon · 2020-07-29 13:47 Quote from: ASBzone on July 29, 2020, 02:52:02 pmQuote from: PascalDragon on July 29, 2020, 09:42:14 amAnd what would the behavior be with $ScopedEnums On? Would it be TLargeEnum.Mary or TSmallEnum.Mary? If the latter would this mean that duplicates are allowed, so that I could have a TSmallEnum.Mary and a TLargeEnum.Mary? What if I mix enums that are declared as $ScopedEnums On and those without? You compiler developers...   Sigh...  (Said affectionately) It's part of the job description to find the hair in the soup. Not to mention that even if someone else would implement it, I'd still be part of the people who'd need to maintain it...  Quote from: ASBzone on July 29, 2020, 02:38:09 pmIf we overlook the "+" debate for a second, I still don't see a problem with the example you gave, which could be converted behind the scenes to: Code: Pascal  [Select][+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i type    TLargeEnum = (Mary, Jane, Sue, Kate, Bob, Larry, Michael, Sally, Cheryl);  TSmallEnum = Mary..Sue;    TSmallEnum2 = Kate..Kate;  And what if TSmallEnum is declared in a different unit, thus can't be changed in any way? ---------------------------------------------------------------------- 440bx · 2020-07-29 18:39 Quote from: ASBzone on July 29, 2020, 02:59:18 pmThanks for this additional perspective.  Do you see this as being a better option than just forbidding that combination (as per my recent post)? You're welcome and, there are combinations that shouldn't be allowed because they could create lot of confusion. One such would be creating multiple supersets from a root enumeration (a tree).  Allowing that would make it quite unclear what enumerations can be treated as supersets and what enumerations are totally different types unrelated to each other even though they share a common ancestor enumeration.  For instance: Code: Pascal  [Select][+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i TEnumRoot = (a, b, c);TEnumA(TEnumRoot) = (d, e, f);    // a, b, c, d, e, fTEnumB(TEnumRoot) = (x, y, z);    // a, b, c, x, y, z In that case EnumA and EnumB are supersets of EnumRoot but, they are completely different types (they represent a different set of constants.)  It would make things a lot simpler for the compiler and, easier for the programmer to understand, if branches are not allowed (EnumA and EnumB are different branches of EnumRoot.) IOW, enumeration supersets should be single chain and strictly additive.  In the above example, the compiler would report an error when seeing TEnumB because that creates a separate branch, i.e, a completely new type which can be quite confusing for a programmer that needs to maintain that code. Quote from: PascalDragon on July 29, 2020, 03:47:08 pmIt's part of the job description to find the hair in the soup. That would lead to the conclusion that bald programmers write better code since there is a lower probability there will be hairs in the soups they make. Quote from: PascalDragon on July 29, 2020, 03:47:08 pmAnd what if TSmallEnum is declared in a different unit, thus can't be changed in any way? Allowing enumeration supersets to be spread among units is a source of complications but, it is not unreasonable to require that all subsets of the enumeration be declared in the same unit or possibly in the same "type" declaration as is the case for some pointer declarations.  In the case of the same unit, I believe OOP already implements such a restriction using visibility modifiers (though not for enumerations.) Quote from: glorfin on July 29, 2020, 12:24:58 pmMaybe sets would serve you better than enumerations? With sets you can easily do such things. Can't do it with sets because a set doesn't define constants, it depends on its elements having been previously defined.  IOW, a set is always a derived type, it is a set of something and, that something has to be defined first. ---------------------------------------------------------------------- nanobit · 2020-07-29 18:52 Quote from: 440bx on July 29, 2020, 08:39:27 pmIn that case EnumA and EnumB are supersets of EnumRoot but, they are completely different types (they represent a different set of constants.)  Another workaround currently possible: Meets requirements: edit single list and support inheritance. Caveat: child-specific names (d, e, f) are usable outside of child- type. One parent, two children: const   a = 0;   b = a + 1;   c = a + 2;   pLast = c;   d = pLast + 1;   e = d + 1;   f = d + 2;   c1Last = f;   w = pLast + 1;   x = w + 1;   y = w + 2;   z = w + 3;   c2Last = z; type   TParent = a..pLast;   TChild1 = a..c1Last;   TChild2 = a..c2Last; ---------------------------------------------------------------------- ASBzone · 2020-07-29 19:49 Quote from: PascalDragon on July 29, 2020, 03:47:08 pmIt's part of the job description to find the hair in the soup. Not to mention that even if someone else would implement it, I'd still be part of the people who'd need to maintain it... Yeah, I can appreciate the motivation that brings. Quote from: PascalDragon on July 29, 2020, 03:47:08 pmQuote from: ASBzone on July 29, 2020, 02:38:09 pmIf we overlook the "+" debate for a second, I still don't see a problem with the example you gave, which could be converted behind the scenes to: Code: Pascal  [Select][+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i type    TLargeEnum = (Mary, Jane, Sue, Kate, Bob, Larry, Michael, Sally, Cheryl);  TSmallEnum = Mary..Sue;    TSmallEnum2 = Kate..Kate;  And what if TSmallEnum is declared in a different unit, thus can't be changed in any way? Yeah... well... It starts to unravel quite a bit, doesn't it. It's not nearly as useful if it's going to be confined to a single unit, IMO...    (Well, it would still be useful, but it seems like it would be a lot of work to go through to be stuck there.) So, we'd have to keep tabs on all enums, expand smaller ones into larger ones, and then somehow keep track of who is a subset of whom, without going back for a second pass. Hmmm...  Well, it sounded nice before you guys poked my bubble. ---------------------------------------------------------------------- ASBzone · 2020-07-29 19:54 Quote from: 440bx on July 29, 2020, 08:39:27 pmIOW, enumeration supersets should be single chain and strictly additive.  In the above example, the compiler would report an error when seeing TEnumB because that creates a separate branch, i.e, a completely new type which can be quite confusing for a programmer that needs to maintain that code. Agreed. Quote from: 440bx on July 29, 2020, 08:39:27 pmAllowing enumeration supersets to be spread among units is a source of complications but, it is not unreasonable to require that all subsets of the enumeration be declared in the same unit or possibly in the same "type" declaration as is the case for some pointer declarations.  I'm still undecided on if limiting it this way -- which gets past a major hurdle -- doesn't just reduce its value, too. ---------------------------------------------------------------------- 440bx · 2020-07-29 22:08 Quote from: ASBzone on July 29, 2020, 09:54:26 pmQuote from: 440bx on July 29, 2020, 08:39:27 pmAllowing enumeration supersets to be spread among units is a source of complications but, it is not unreasonable to require that all subsets of the enumeration be declared in the same unit or possibly in the same "type" declaration as is the case for some pointer declarations.  I'm still undecided on if limiting it this way -- which gets past a major hurdle -- doesn't just reduce its value, too. In a way, it does reduce its value a little but, at the same time, by requiring that everything be in one place, a programmer who has to maintain the code doesn't have to go to multiple places to figure out all the elements in the enumeration (something I feel is important.) Another important consideration from an implementation viewpoint is that if sets are defined on these enumerations, the compiler has to have a reasonably easy way of figuring out how many bits to allocate for the sets.  Just because of that, I'd be rather tempted to require that all sub-enumerations be in a single type definition thus, not even allowing them to be spread around in a unit. Also, usually, one knows all the values that an enumeration should have but, there are times when it's convenient to "divide" the enumeration into groups.  An analogy is array slices, there are times when it's useful to be able to operate on a slice of it instead of the entire array.  For instance, if an enumeration superset is composed of 3 subsets named, ENUM_ROOT, ENUM_A, ENUM_B then one can do "for i in ENUM_ROOT do ... " or "for i in ENUM_B do ..." and allowing sets on these "named enumeration subsets" would allow something like "if identifier in ENUM_ROOT_SET then..." which would return false even if the identifier is in the larger set but not a member of the root.  Unlike an array slice which can go from any element to any element an enumeration slice would always be from the beginning of the enumeration to the end of the named sub-enumeration.  IOW, from zero (0) (presuming no value has been set manually) to n where n would be determined by which sub-enumeration is used. These things can be "synthesized" currently but, it takes more type definitions which obscures the intention and, depending on how they are synthesized, they also open the possibility that an identifier added later doesn't make it into all those additional type definitions. ---------------------------------------------------------------------- MarkMLl · 2020-07-30 07:03 I wonder whether it's worth pointing out that application code shouldn't be aware of the numerical values or enumerated items, the only thing that really matters is Succ() and Pred(). Succ() of the last item of the foundation enumeration is invalid, leaving the real problem being Pred() of the first item of an extended enumeration where this crosses units. MarkMLl