Recent

Author Topic: Feature Request: Extending enumerators and hierarchies  (Read 4314 times)

EganSolo

  • Sr. Member
  • ****
  • Posts: 398
Feature Request: Extending enumerators and hierarchies
« on: August 06, 2025, 05:44:33 am »
Two feature requests that don't break backward compatibility:

1. Extending enumerated types: Currently, we can restrict enumerated types. It would be handy to extend them:
Code: Pascal  [Select][+][-]
  1. Type
  2.    WorkingDays   =  (Monday, Tuesday, Wednesday, Thursday, Friday);
  3.    DaysOfTheWeek =  (WorkingDays, Saturday, Sunday);
  4.  

The compiler already flags duplicated enumerated types. In this case, it would recognize DaysOfTheWeek as an extension of WorkingDays and would then internally redeclare WorkingDays as a restriction of DaysOfTheWeek. That's an oversimplification, of course, but you get the idea. Consider this more elaborate example:

Code: Pascal  [Select][+][-]
  1. Type
  2.    WorkingDays   =  (Monday, Tuesday, Wednesday, Thursday, Friday);
  3.    DaysOfTheWeek =  (WorkingDays, Saturday, Sunday);
  4.    SpecialDays   =  (WorkingDays, Birthday, AnniversaryDay);
  5.  

Admittedly, this is forced, but it highlights the possible complication: Monday is now an item of type WorkingDays, DaysOfTheWeek and SpecialDays. Nevertheless, that's no different than what happens for instances of classes in a hierarchy.

Speaking of Hierarchy, the next feature is a generalization of the previous request:

Code: Pascal  [Select][+][-]
  1.  RootHierarchy   = (DaysOfTheWeek, MonthsOfTheYear);
  2.  DaysOfTheWeek   = (Monday, Tuesday, Wednesday, Thursday, Friday, Saturday, Sunday);
  3.  MonthsOfTheYear = (January, February, March, April, May, June, July, August, September, October, November, December);
  4.  

A hierarchy leverages enumeration to implement a simplified ontology. It allows a rapid grouping of things somewhat orthogonal to the more rigid inheritance mechanism.

What do you guys think?

MarkMLl

  • Hero Member
  • *****
  • Posts: 8574
Re: Feature Request: Extending enumerators and hierarchies
« Reply #1 on: August 06, 2025, 08:50:15 am »
1. Extending enumerated types: Currently, we can restrict enumerated types. It would be handy to extend them:

I definitely agree with that one, it's something I raised years ago in the context of

i) A class (emulating a piece of hardware) could return certain states which were defined as an enumeration (device not ready, device busy and so on).

ii) A subclass (emulating a more complex piece of hardware) could return extra states (beginning of medium, end of medium etc.).

To some extent, it's possible to work around the lack of this by defining numeric bases for subranges. However I consider that at best to be a kludge.

MarkMLl
MT+86 & Turbo Pascal v1 on CCP/M-86, multitasking with LAN & graphics in 128Kb.
Logitech, TopSpeed & FTL Modula-2 on bare metal (Z80, '286 protected mode).
Pet hate: people who boast about the size and sophistication of their computer.
GitHub repositories: https://github.com/MarkMLl?tab=repositories

gues1

  • Guest
Re: Feature Request: Extending enumerators and hierarchies
« Reply #2 on: August 06, 2025, 09:55:18 am »
I think, my half cent, that this is dangerous and can lead to various attribution issues.
In your example:

Code: Pascal  [Select][+][-]
  1. Type
  2.    WorkingDays   =  (Monday, Tuesday, Wednesday, Thursday, Friday);
  3.    DaysOfTheWeek =  (WorkingDays, Saturday, Sunday);
  4.    SpecialDays   =  (WorkingDays, Birthday, AnniversaryDay);
  5.  

How can be interpreted this:

Code: Pascal  [Select][+][-]
  1. const
  2. W = WorkingDays; //DaysOfTheWeek or SpecialDays ?

By now the physical implementation of the enumerated type is on value (position too) and this can be (... IT IS) useful to save that value and reload it, and for compatibility with something else.

Again, have different enums with the same meaning is not something good.

But the idea on "hierarchy leverages enumeration" is something to think about.

EganSolo

  • Sr. Member
  • ****
  • Posts: 398
Re: Feature Request: Extending enumerators and hierarchies
« Reply #3 on: August 06, 2025, 10:08:24 am »
Quote
How can be interpreted this:
    const
    W = WorkingDays; //DaysOfTheWeek or SpecialDays ?

Excellent point. As with other ambiguous declarations, disambiguation would be required. So, the compiler would flag that as an error and we would redeclare it as:

Code: Pascal  [Select][+][-]
  1. const
  2.   W : DaysOfTheWeek = WorkingDays;
  3.  

That's one solution that's already in use elsewhere. For instance, if you have two functions foobar in unit1 and unit2, you might need to specify which one you want to use by prefixing them with the unit name as in Unit1.foobar or Unit2.footbar. In general, I think that ambiguity that can be removed with existing mechanisms should not be ignored. Nevertheless, I agree with you that this feature introduces ambiguity.

Thaddy

  • Hero Member
  • *****
  • Posts: 19408
  • Glad to be alive.
Re: Feature Request: Extending enumerators and hierarchies
« Reply #4 on: August 06, 2025, 10:13:44 am »
With properly defined set of enumeration this can already be achieved? and a set is an enumerated type as well.
As long there is an enumeration that contains all possible values it is quite easy to do that with set operators.
Since a subrange can be declared as const this effectively looks like what you want to achieve.
Crude example:
Code: Pascal  [Select][+][-]
  1. {$mode objfpc}
  2. type
  3.   day = (monday, tuesday, wednesday, thursday,friday,saturday,sunday);
  4.   days = set of day;
  5. const //<--- becomes an enumeration because of const.
  6.   weekenddays:days = [saturday,sunday];
  7.   workdays:days = [monday,tuesday,wednesday,thursday,friday];
  8. var
  9.   x:day;
  10. begin
  11.   writeln('What are my days off this week:');
  12.   for x in weekenddays do writeln(x);
  13.   writeln('What are my workdays this week:');
  14.   for x in workdays do writeln(x);
  15.   readln;
  16. end.
« Last Edit: August 06, 2025, 11:59:46 am by Thaddy »
Any "programmer" that knows only one programming language is not a programmer

Thaddy

  • Hero Member
  • *****
  • Posts: 19408
  • Glad to be alive.
Re: Feature Request: Extending enumerators and hierarchies
« Reply #5 on: August 06, 2025, 10:15:53 am »
Code: Pascal  [Select][+][-]
  1. const
  2.   W : DaysOfTheWeek = WorkingDays;
  3.  
No problem. Posts crossed, but my example refutes this. It is already possible by declaring a set of enumeration to create new enumerations  declared const and the enumeration itself contains all possible values for the domain.
« Last Edit: August 06, 2025, 11:57:25 am by Thaddy »
Any "programmer" that knows only one programming language is not a programmer

ASerge

  • Hero Member
  • *****
  • Posts: 2510
Re: Feature Request: Extending enumerators and hierarchies
« Reply #6 on: August 06, 2025, 08:30:46 pm »
The compiler already flags duplicated enumerated types.
Code: Pascal  [Select][+][-]
  1. {$SCOPEDENUMS ON}

EganSolo

  • Sr. Member
  • ****
  • Posts: 398
Re: Feature Request: Extending enumerators and hierarchies
« Reply #7 on: August 07, 2025, 09:45:36 pm »
Thaddy,
 I love the ingenuity of your solution, but help me understand how it addresses this use case, which is what I was hoping to achieve by extending enumerations:

Code: Pascal  [Select][+][-]
  1. Unit Unit1;
  2. //assume this unit is written by author1
  3. Interface
  4. uses Classes, SysUtils;
  5. Type
  6.   WeekDay = (Monday, Tuesday, Wednesday, Thursday, Friday);
  7. Implementation
  8. End.
  9.  

I write my unit and do this:
Code: Pascal  [Select][+][-]
  1. Unit MyUnit;
  2. Interface
  3. uses Classes, SysUtils, Unit1;
  4. Type
  5.   DaysOfTheWeek = (DayOfTheWeek, Saturday, Sunday);
  6. Implementation
  7. End.
  8.  

Could you still solve for this using constant sets?

Thaddy

  • Hero Member
  • *****
  • Posts: 19408
  • Glad to be alive.
Re: Feature Request: Extending enumerators and hierarchies
« Reply #8 on: August 08, 2025, 07:27:00 pm »
Yes, I already did....Other example:
Code: Pascal  [Select][+][-]
  1. {$mode objfpc}
  2. type
  3.   // full enum
  4.    day= (monday,tuesday,wednesday,thursday,friday,saturday,sunday);
  5.    days = set of day;
  6. const
  7.    workdays:days = [monday,tuesday, wednesday, thursday, friday];
  8.    weekend:days  = [saturday, sunday];
  9. var
  10.   thisweek:days = [];
  11.   d:day;
  12. begin
  13.    thisweek := thisweek + workdays;
  14.    include(thisweek,saturday);// overtime
  15.    exclude(thisweek, wednesday);//day off.
  16.    for d in thisweek do
  17.       writeln(d);
  18.   readln;
  19. end.
Outputs:
Code: [Select]
monday
tuesday
thursday
friday
saturday
You only have to know how sets really work. ;D
« Last Edit: August 08, 2025, 07:37:19 pm by Thaddy »
Any "programmer" that knows only one programming language is not a programmer

EganSolo

  • Sr. Member
  • ****
  • Posts: 398
Re: Feature Request: Extending enumerators and hierarchies
« Reply #9 on: August 09, 2025, 03:23:39 am »
Your example started with a full enum.

Mine started with a partial one: In my example the author of Unit1 defined __what he thought was a full enum__ and I want to extend it, without changing his code.

Don't you think you're solving a different use case?

Thaddy

  • Hero Member
  • *****
  • Posts: 19408
  • Glad to be alive.
Re: Feature Request: Extending enumerators and hierarchies
« Reply #10 on: August 09, 2025, 09:17:28 pm »
That will likely never be possible or adds multiple passes to the compiler to resolve (not going to happen). Otherwise it requires compile-time sizes to be manipulated at runtime (likely not going to happen).
What I tried to explain is that the full set of possibilities, the enum to choose from, need to be known at compile time and any subset you like can be declared as const.

Since anything you showed is compile-time anyway.....means by definition the full enum is already known...
So, no, I am solving the same case, just with some intricacies you forgot about?
« Last Edit: August 09, 2025, 09:28:49 pm by Thaddy »
Any "programmer" that knows only one programming language is not a programmer

EganSolo

  • Sr. Member
  • ****
  • Posts: 398
Re: Feature Request: Extending enumerators and hierarchies
« Reply #11 on: August 10, 2025, 11:45:58 pm »
Hi Thaddy:

  Admittedly, the simplistic example I gave listed the enumerated types, however, it's not that difficult to imagine an example where Unit1 is in a vendor's package that preclude a change to its code. I don't think my example is contrived, and extended enumerated types is a really useful feature.

  You bring up a good point: adding multiple compilation passes is a no-no. Nevertheless, I fail to see why that would be required. Forward compiling is sufficient to recognize extended enumeration much like it recognizes classes that inherits from already defined classes. Furthermore, disambiguating an enumerated item to determine its provenance would be done by crawling a dependency chain among enumerated types, the same way we do it when we locate a declared attributes in a class.

Thaddy

  • Hero Member
  • *****
  • Posts: 19408
  • Glad to be alive.
Re: Feature Request: Extending enumerators and hierarchies
« Reply #12 on: August 11, 2025, 05:35:05 pm »
When you propose external libraries the solution is:
Code: Pascal  [Select][+][-]
  1. {$mode objfpc}
  2. type
  3.   Tbyte = set of 0..255;// max set
  4. const
  5.   bb: Tbyte = [0..255];
  6.   cc: TByte = [201,202,203];
  7. var
  8.   b:byte;
  9. begin
  10.   for b in bb do writeln(b);
  11.   writeln;
  12.   for b in cc do writeln(b);
  13. end.
Which proves that any subset of high(enum) can be expressed as a subset.
Where you go wrong is named enums... that is not possible.(unless you cast)
Enums can contain gaps, where a gap is valid for the enum but has no name attached.
Then it would fail miserably.
( I provided at patch, once, to only allow named elements in a named enum range , but that was refused: although the patch was correct, querying the name slows downs the code a lot, which is not the intention of enums. )
   
« Last Edit: August 12, 2025, 05:06:34 pm by Thaddy »
Any "programmer" that knows only one programming language is not a programmer

EganSolo

  • Sr. Member
  • ****
  • Posts: 398
Re: Feature Request: Extending enumerators and hierarchies
« Reply #13 on: August 13, 2025, 02:22:51 am »
I sense that this discussion veered from my initial ask.
I'm not interested in what hack I might choose to implement something like an enumerated type extension. My question was whether that would be a feature worth having or not.

Thaddy, you explained that it could be done with sets. Still, I'm afraid your explanation hinges on knowing the whole domain of enumerated types at compile time for all the units and packages involved in the project, which is impractical for reasons I've outlined: if I'm including a commercial package that I don't want to touch, that solution breaks.

Using integers as an approximation to enumerated types is, again, self-defeating.

So, I'd like to reorient this conversation to this initial ask: Are extended enumerated types a good thing and should we have them in the language? The how is an implementation question worth having after we've answered this question.

Thaddy

  • Hero Member
  • *****
  • Posts: 19408
  • Glad to be alive.
Re: Feature Request: Extending enumerators and hierarchies
« Reply #14 on: August 13, 2025, 05:47:21 am »
You can't do what you want, that is unless there is an underlying structure, may be hidden, that expresses the full range.
Any other thing would not be an enum.
I fear you don't grasp that a third party provided enum also has indices starting from 0. Concatinating with you own enum that also starts from index 0 leads to duplicates or makes the resulting enum worthless because one of the enums must shift their values. Do you understand that part? I am not veering away from your original idea, I am merely pointing out it can not be done in a meaningful way.
suppose my enum is:
Code: Pascal  [Select][+][-]
  1. myenum = (one,two,three);
And some external code provides an enum
Code: Pascal  [Select][+][-]
  1. theirenum = (four, five,six);
how would you merge them without loosing their value or changing their meaning?
Because Ord(one) = 0 and ord(four) is also 0, you can't make that 4, because then the meaning of the enum has changed and code would not work as expected. E.g., toggling a switch based on enum, what I use a lot for IoT. will fail if the external enum would be merged into your own. one <> four but both originally are Ord(one)  =  0 and ord(four) = 0.
It would toggle the wrong switch. Enums, by definition, do not allow duplicates.

That leaves two solutions:
Use sets where the full enum is known.
Or create an overlay like so:
Code: Pascal  [Select][+][-]
  1. type
  2.   myenum = (one,two,three);
  3.   theirenum = (four,five,six);
  4. var
  5.   ours:myenum;
  6.   theirs: theirenum absolute ours;
  7. begin
  8.   writeln(Ord(two) = Ord(five));// correct
  9.   // writeln(two = five);       // error
  10. end.
That at least leaves the original ordinal values intact so you do not create accidents.

Another example:
Code: Pascal  [Select][+][-]
  1. {$mode objfpc}{$scopedenums on}
  2. uses typinfo,rtti;
  3. type
  4.   myenum = (one,two,three);
  5.   theirenum = (four,five,six);
  6.   // what is asked is myenum+theirenum := combinedenum as expression
  7.   // if that were possible the index would change and
  8.   // the original meaning is lost.
  9.   // so we redefine it with the same names.
  10.   combinedenum = (one,two,three,four,five,six);
  11. var
  12.   ours:myenum;
  13.   theirs: theirenum absolute ours;
  14. begin
  15.   writeln(ord(myenum.two));       // 1
  16.   writeln(ord(theirenum.five));   // 1
  17.   writeln(ord(combinedenum.five));// 4 // <--meaning is lost, index is now 4.
  18. end.
That is why it is a bad idea. Renders enums useless.
The primary goal of enums is to provide an index based on readable names.


« Last Edit: August 13, 2025, 08:28:26 am by Thaddy »
Any "programmer" that knows only one programming language is not a programmer

 

TinyPortal © 2005-2018