Recent

Author Topic: question about an enumeration within another enumeration  (Read 1981 times)

440bx

  • Hero Member
  • *****
  • Posts: 1994
question about an enumeration within another enumeration
« on: July 28, 2020, 09:06:03 pm »
Hello,

I'd like to have an enumeration be a "superset" of another enumeration.  For instance:
Code: Pascal  [Select][+][-]
  1. type
  2.   TENUMERATION_A = (a, b, c);
  3.  
  4.   TENUMERATION_B =
  5.   (
  6.     a, b, c,       { TENUMERATION_A                  }
  7.  
  8.     k, l, m        { enumeration A plus other values }
  9.   );
  10.  
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][+][-]
  1. type
  2.   TENUMERATION_A = (a, b, c);
  3.  
  4.   TENUMERATION_B =
  5.   (
  6.     TENUMERATION_A,
  7.  
  8.     k, l, m           { enumeration A plus other values }
  9.   );
  10.  

Thank you for your help.
FPC v3.0.4 and Lazarus 1.8.2 on Windows 7 64bit.

Blaazen

  • Hero Member
  • *****
  • Posts: 2913
  • POKE 54296,15
    • Eye-Candy Controls
Re: question about an enumeration within another enumeration
« Reply #1 on: July 28, 2020, 09:32:28 pm »
The only way is probably enum+range:
Code: Pascal  [Select][+][-]
  1. type
  2.   TEA = (a, b, c, d, e, f);
  3.   TEB = a..c;
Lazarus 2.1.0 r63881 FPC 3.3.1 r40507 x86_64-linux-qt Chakra, Qt 4.8.7/5.13.2, Plasma 5.17.3
Lazarus 1.8.2 r57369 FPC 3.0.4 i386-win32-win32/win64 Wine 3.21

Try Eye-Candy Controls: https://sourceforge.net/projects/eccontrols/files/

MarkMLl

  • Hero Member
  • *****
  • Posts: 1219
Re: question about an enumeration within another enumeration
« Reply #2 on: July 28, 2020, 10:11:01 pm »
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).

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
Turbo Pascal v1 on CCP/M-86, multitasking with LAN and graphics in 128Kb.
Pet hate: people who boast about the size and sophistication of their computer.

howardpc

  • Hero Member
  • *****
  • Posts: 3519
Re: question about an enumeration within another enumeration
« Reply #3 on: July 28, 2020, 10:31:10 pm »
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][+][-]
  1.   TFormBorderStyle = (bsNone, bsSingle, bsSizeable, bsDialog, bsToolWindow, bsSizeToolWin);
  2.   TBorderStyle = bsNone..bsSingle;
       

ASBzone

  • Sr. Member
  • ****
  • Posts: 461
  • Automation leads to relaxation...
    • Free BrainWaveCC Console Utilities
Re: question about an enumeration within another enumeration
« Reply #4 on: July 28, 2020, 10:46:53 pm »
It would absolutely be a nice to have feature...
-ASB: https://www.BrainWaveCC.com

Lazarus v2.0.11 r63516 / FPC v3.2.1-r46879 (via FpcUpDeluxe) -- Windows 64-bit install w/32-bit cross-compile
Primary System: Windows 10 Pro x64, Version 2004 (Build 19041.508)
Other Systems: Windows 10 Pro x64, Version 2004 or greater

MarkMLl

  • Hero Member
  • *****
  • Posts: 1219
Re: question about an enumeration within another enumeration
« Reply #5 on: July 28, 2020, 11:05:00 pm »
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
Turbo Pascal v1 on CCP/M-86, multitasking with LAN and graphics in 128Kb.
Pet hate: people who boast about the size and sophistication of their computer.

ASBzone

  • Sr. Member
  • ****
  • Posts: 461
  • Automation leads to relaxation...
    • Free BrainWaveCC Console Utilities
Re: question about an enumeration within another enumeration
« Reply #6 on: July 29, 2020, 12:21:30 am »
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.

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][+][-]
  1. type
  2.   TSmallEnum = (Mary, Jane, Sue);
  3.   TLargeEnum = TSmallEnum + (Bob, Larry, Michael, Sally, Cheryl);
  4.  

...would be expanded by the compiler as:

Code: Pascal  [Select][+][-]
  1. type
  2.   TSmallEnum = (Mary, Jane, Sue);
  3.   TLargeEnum = (Mary, Jane, Sue, Bob, Larry, Michael, Sally, Cheryl);
  4.  

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][+][-]
  1. type
  2.   TLargeEnum = (Mary, Jane, Sue, Bob, Larry, Michael, Sally, Cheryl);
  3.   TSmallEnum = Mary..Sue;
  4.  

This way, the compiler gets most of what it wants, and the developers gets the benefits he or she wants too.
-ASB: https://www.BrainWaveCC.com

Lazarus v2.0.11 r63516 / FPC v3.2.1-r46879 (via FpcUpDeluxe) -- Windows 64-bit install w/32-bit cross-compile
Primary System: Windows 10 Pro x64, Version 2004 (Build 19041.508)
Other Systems: Windows 10 Pro x64, Version 2004 or greater

440bx

  • Hero Member
  • *****
  • Posts: 1994
Re: question about an enumeration within another enumeration
« Reply #7 on: July 29, 2020, 12:34:10 am »
@Blaazen

That's nice.  Thank you for suggesting it.  Unfortunately, it doesn't get close enough.

Blaazen'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][+][-]
  1. type
  2.   TSmallEnum = (Mary, Jane, Sue);
  3.   TLargeEnum = TSmallEnum + (Bob, Larry, Michael, Sally, Cheryl);
  4.  
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.

FPC v3.0.4 and Lazarus 1.8.2 on Windows 7 64bit.

jamie

  • Hero Member
  • *****
  • Posts: 3523
Re: question about an enumeration within another enumeration
« Reply #8 on: July 29, 2020, 01:55:59 am »
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.
The only true wisdom is knowing you know nothing

MarkMLl

  • Hero Member
  • *****
  • Posts: 1219
Re: question about an enumeration within another enumeration
« Reply #9 on: July 29, 2020, 08:58:13 am »
Why 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
Turbo Pascal v1 on CCP/M-86, multitasking with LAN and graphics in 128Kb.
Pet hate: people who boast about the size and sophistication of their computer.

marcov

  • Global Moderator
  • Hero Member
  • *****
  • Posts: 8725
  • FPC developer.
Re: question about an enumeration within another enumeration
« Reply #10 on: July 29, 2020, 09:06:27 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][+][-]
  1. type
  2.   TSmallEnum = (Mary, Jane, Sue);
  3.   TSmallEnum2 = (Kate);
  4.   TLargeEnum = TSmallEnum +  TSmallEnum2 + (Bob, Larry, Michael, Sally, Cheryl);
  5.  


This is all logical with "+" semantics

PascalDragon

  • Hero Member
  • *****
  • Posts: 2119
  • Compiler Developer
Re: question about an enumeration within another enumeration
« Reply #11 on: July 29, 2020, 09:42:14 am »
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][+][-]
  1. type
  2.   TSmallEnum = (Mary, Jane, Sue);
  3.   TLargeEnum = TSmallEnum + (Bob, Larry, Michael, Sally, Cheryl);
  4.  

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

  • Hero Member
  • *****
  • Posts: 3519
Re: question about an enumeration within another enumeration
« Reply #12 on: July 29, 2020, 10:00:25 am »
You can of course always typecast enums, and perpetrate this sort of silliness:
Code: Pascal  [Select][+][-]
  1. program EnumTypecast;
  2.  
  3. type
  4.  
  5.   TWeekendDays = (weFri, weSat, weSun);
  6.  
  7.   TWeekDays = (Mon=-4, Tue, Wed, Thu, Fri, Sat, Sun);
  8.  
  9. var
  10.   weekend: TWeekendDays;
  11.  
  12. begin
  13.   for weekend in TWeekendDays do
  14.     Write(TWeekDays(weekend), ' ');
  15.   ReadLn;
  16. end.

MarkMLl

  • Hero Member
  • *****
  • Posts: 1219
Re: question about an enumeration within another enumeration
« Reply #13 on: July 29, 2020, 10:18:58 am »
Because 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

Turbo Pascal v1 on CCP/M-86, multitasking with LAN and graphics in 128Kb.
Pet hate: people who boast about the size and sophistication of their computer.

MarkMLl

  • Hero Member
  • *****
  • Posts: 1219
Re: question about an enumeration within another enumeration
« Reply #14 on: July 29, 2020, 10:21:28 am »
You 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
Turbo Pascal v1 on CCP/M-86, multitasking with LAN and graphics in 128Kb.
Pet hate: people who boast about the size and sophistication of their computer.

 

TinyPortal © 2005-2018