Jump to content

Recommended Posts

6 hours ago, Lars Fosdal said:

Well, we have thousands of meaningful and reasonably obvious names (within their context) - but yeah - remembering them gets harder every year.  Age takes its toll. 😛
 

But - Code Insight should work whether you are assigning or passing as a parameter. 
Unfortunately, it has often put the enumerated values a long way down the list of candidates.

We've only started using 10.4.1, so the jury is still out on this issue, but the LSP has been less than rock solid so far. 

Most common mistake I make is when enums start with same prefix, like:
 

TCellType = (ctNA, ct...)
TCommandType = (ctNA, ct..)

 

If they are within visible area of each other in the unit, you can choose different wording, but very easy to forget that ct is already 'used', if they are defined some time apart.

I hope 10.5 will have much much improved LSP.

 

But I must say I kind of like the idea of grouping enums together by content/purpose, within Enums class. Cool solution 🙂

 

Share this post


Link to post
39 minutes ago, Mike Torrettinni said:

Most common mistake I make is when enums start with same prefix, like:
 


TCellType = (ctNA, ct...)
TCommandType = (ctNA, ct..)

 

If they are within visible area of each other in the unit, you can choose different wording, but very easy to forget that ct is already 'used', if they are defined some time apart.

I hope 10.5 will have much much improved LSP.

 

But I must say I kind of like the idea of grouping enums together by content/purpose, within Enums class. Cool solution 🙂

 

This is exactly the issue that scoped enums solves already.

Share this post


Link to post
3 minutes ago, Kryvich said:

@Mike Torrettinni I would use different prefixes if possible.

I do, except when they are in different units or out of view in longer unit, i can make mistake. Of course it makes sense this is not really applicable for projects where only a few enums are defined and you can remember most of them. But i have a lot of them, so the need to organize them could differ in such cases. Not all projects are the same.

Share this post


Link to post
19 minutes ago, Kryvich said:

I would use different prefixes if possible.

That's what scoped enums are meant for

Share this post


Link to post

I know, now it is not fashionable to use prefixes, and they prefer to write TCommandType.NA, or even CommandType.NA like in C#.

Share this post


Link to post

Dropping the T for types in Delphi doesn't quite work for scoped types.
 

program ScopedEnumsWithoutT;

{$APPTYPE CONSOLE}

{$R *.res}

{$ScopedEnums ON}

uses
  System.SysUtils;

type
  CommandType = (NA, Whatever);

type
  TClass = class
  private
    FCommandType: CommandType;
  public
    constructor Create;
    property CommandType: CommandType read FCommandType write FCommandType;
  end;

procedure Test;
begin
  var Instance := TClass.Create;
  try
    Instance.CommandType := CommandType.Whatever; // This is fine
  finally
    Instance.Free;
  end;
end;
{ TClass }

constructor TClass.Create;
begin
  CommandType := ScopedEnumsWithoutT.CommandType.NA;  // When using "unit name space" - this is fine
  CommandType := CommandType.NA;  // [dcc32 Error] : E2018 Record, object or class type required
end;

begin
  try
    Test;
  except
    on E: Exception do
      Writeln(E.ClassName, ': ', E.Message);
  end;
end.

 

Share this post


Link to post

Is NA some kind of reserved word or math function, have you tried with .Whatever too ?

Share this post


Link to post
2 minutes ago, Rollo62 said:

Is NA some kind of reserved word or math function, have you tried with .Whatever too ?

 
 
 

Changing NA to Nada gives same result.

 

But - adding the "unit scope" works. 

  CommandType := ScopedEnumsWithoutT.CommandType.NA;  


 

  • Like 1

Share this post


Link to post
28 minutes ago, Rollo62 said:

Is NA some kind of reserved word or math function, have you tried with .Whatever too ?

No; problem is, that in the example above there is type "CommandType" and property "CommandType", so CommandType.NA is trying to reference property CommandType, which does not have member called NA.

Share this post


Link to post

The enumerated type has been removed in oberon.


When Niklaus Emil Wirth came to us in Tomsk.
We asked him a question, the reason for this was done?
We got an answer about his shortcomings.

 

1. Very often, an enumerated type cannot be extended,
This may be due to the fact that it is from a third party library
and the domain of its values is already sealed.

2. A set of constants can successfully perform the same role.

3. One and the same concept is often used in different classifications, which leads to the growth of similar names with distinguishing prefixes.

4. The prefix is essentially the same vicious Hungarian notation LPStrZ_to_hell

 

For convenient use, a related set of constants can be placed in a module or record.
The record will act as a namespace.
Here we will not be limited to expanding the list of values.
Also, we can always add related methods for working with these values.

 

THTMLType = record
public const
  Template = 0;
  Static = 1;
  Header = 2;
  Custom = 3;
end;

Criticism


The enumeration type is traditional in advanced programming languages, is widely used and is often taken for granted. However, this type is also not without criticism from programming theorists and practitioners. So, when developing the Oberon programming language, enumerated types were included in the list of features that were removed from the language. Niklaus Wirth, the language developer, gave the following reasons:

“In an increasing number of programs, the ill-considered use of enumerations ... leads to a population explosion among types, which, in turn, leads not to clarity of programs, but to verbosity” [1]; 

when an enumeration type is exported by a module (that is, it becomes part of the interface), the general rule is violated - the type export command simultaneously exports all its elements, while for all other types, the type export hides its internal structure;
from the point of view of ensuring readability of programs, nothing prevents you from using just a group of jointly defined named constants instead of an enumerated type, especially when there are language mechanisms such as modules or classes.


On the other hand, for example, in Java, which initially did not contain an enumerated type, this type was subsequently introduced for reasons of not only convenience, but also reliability: the problem of using named constant groups instead of enumerations is that there is no compiler control as to the uniqueness of values constants, and the possibility of random assignment to variables of values that do not correspond to any of these constants.

Edited by Marat1961
  • Like 2

Share this post


Link to post
12 minutes ago, Marat1961 said:

THTMLType = record
public const
  Template = 0;
  Static = 1;
  Header = 2;
  Custom = 3;
end;

 

Interesting. Are you really using this construct instead of enums, in your real code?

Share this post


Link to post
52 minutes ago, Mike Torrettinni said:

Interesting. Are you really using this construct instead of enums, in your real code?

Of course I do.

All programmers, for example, in java-script are forced to use the same approach.

The original K&R C dialect did not have enumeration types, however they were added in the ANSI C standard.

Edited by Marat1961

Share this post


Link to post

For example, we took the direction of the cardinal points
North South West East.
Then he finds out that this is not enough, we decided to add. The question is where to add?
Now what to do with that code that uses only 4 directions?

Share this post


Link to post
Just now, Marat1961 said:

Of course I do.

All programmers, for example, in C ++, are forced to use the same approach.

Aha, cool. I know I can use consts in records, but never thought of this approach to replace enums.

 

I guess this whole topic would be pointless if code completion would work as it should. But I like the different approaches and suggestion, and a little history (I assume the discussion with Niklaus wasn't last week 🙂 ).

 

Share this post


Link to post

And I thought enums and the possibility to build sets of enums is one of those unique features in Delphi that many other languages such as C++ don't have hence you have to and/or with damn bitmasks....

  • Like 1

Share this post


Link to post
1 minute ago, Mike Torrettinni said:

Aha, cool. I know I can use consts in records, but never thought of this approach to replace enums.

Not exactly as only enums replacement, i use it for consts, in that way i have my constants tucked, sorted and scoped, no more global consts all over the place, popping in code complete.

  • Like 1

Share this post


Link to post
52 minutes ago, Stefan Glienke said:

And I thought enums and the possibility to build sets of enums is one of those unique features in Delphi that many other languages such as C++ don't have hence you have to and/or with damn bitmasks....

type
  TMyType = record
  const
    &Template = 0;
    &Static = 1;
    Header = 2;
    Custom = 3;
  type
    TMySetType = set of &Template..Custom;
  end;
Edited by Marat1961

Share this post


Link to post
20 minutes ago, Marat1961 said:

THTMLType = record
public const
  Template = 0;
  Static = 1;
  Header = 2;
  Custom = 3;
end;

MySet = set of (THTMLType.Template .. THTMLType.Custom);

 

If that would compile - and even if it would that would not prevent that set to be assigned [4] to.

Share this post


Link to post
34 minutes ago, David Heffernan said:

As for C ++, I was in a hurry. Although when porting, I very often port as a list of constants.
Wonderful sources for oberon do without enumerated types.

In Java, an enumerated type can be inherited and extended.

Share this post


Link to post
24 minutes ago, Stefan Glienke said:

If that would compile - and even if it would that would not prevent that set to be assigned [4] to.

I corrected the syntax of the example

Share this post


Link to post

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

×