Scoped enums and inferred types

classic Classic list List threaded Threaded
28 messages Options
12
Reply | Threaded
Open this post in threaded view
|

Scoped enums and inferred types

Ryan Joseph
I just learned FPC has scoped enums, which is nice, but they lack what you could call “relative inference” based on the type being passed. In the example below the parameter “t” is TMyType but passing “A” doesn’t work. Doesn’t the compiler know the type and can infer “A” is relative to the scoped enum? I understand there’s a possibility for name conflicts but you could just use the full name in that case.

Is this a missing feature or do you need to enable it or something?

{$scopedenums on}
type
        TMyType = (A, B, C);
{$scopedenums off}

procedure DoThis (t: TMyType);
begin
end;

DoThis(A);


Regards,
        Ryan Joseph

_______________________________________________
fpc-pascal maillist  -  [hidden email]
http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal
Reply | Threaded
Open this post in threaded view
|

Re: Scoped enums and inferred types

Michael Van Canneyt


On Wed, 21 Feb 2018, Ryan Joseph wrote:

> I just learned FPC has scoped enums, which is nice, but they lack what you could call “relative inference” based on the type being passed. In the example below the parameter “t” is TMyType but passing “A” doesn’t work. Doesn’t the compiler know the type and can infer “A” is relative to the scoped enum? I understand there’s a possibility for name conflicts but you could just use the full name in that case.
>
> Is this a missing feature or do you need to enable it or something?
>
> {$scopedenums on}
> type
> TMyType = (A, B, C);
> {$scopedenums off}
>
> procedure DoThis (t: TMyType);
> begin
> end;
>
> DoThis(A);
The whole point of scoped enums is to force you to write TMyType.A
everywhere.
So this is "as designed". If you want to be able to write A, don't use
scoped enums.

Michael.
_______________________________________________
fpc-pascal maillist  -  [hidden email]
http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal
Reply | Threaded
Open this post in threaded view
|

Re: Scoped enums and inferred types

Free Pascal - General mailing list
Am 21.02.2018 04:09 schrieb "Ryan Joseph" <[hidden email]>:
Is this a missing feature or do you need to enable it or something?

There is none. 

The compiler does not know the type of the parameter, because overload selection occurs only after all parameters have been parsed. So during parsing the compiler would not know from which enum type to select the enum value. Not to mention unsolvable overloads if there would be two enums with the same value and the same name of the routine. 

This also would have the possibility to lead to confusion for the user (e.g. same case as above or add a variable with the same name into the mix). 

Regards, 
Sven 

_______________________________________________
fpc-pascal maillist  -  [hidden email]
http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal
Reply | Threaded
Open this post in threaded view
|

Re: Scoped enums and inferred types

Ryan Joseph
In reply to this post by Michael Van Canneyt


> On Feb 21, 2018, at 1:54 PM, Michael Van Canneyt <[hidden email]> wrote:
>
> So this is "as designed". If you want to be able to write A, don't use
> scoped enums.

I got the idea from Swift (one of the things it does right) and it’s really nice to be able say "this = .value” instead of NSSomeLongNameOfSomethingValueKey. It only works with assignments but it really cleans up code. The reasons I suggested it was because some of my function calls were just getting stupid long and annoying to type plus difficult to remember (that’s important for programmers!) so the compiler could certainly help here.

Regards,
        Ryan Joseph

_______________________________________________
fpc-pascal maillist  -  [hidden email]
http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal
Reply | Threaded
Open this post in threaded view
|

Re: Scoped enums and inferred types

Ryan Joseph
In reply to this post by Free Pascal - General mailing list


> On Feb 21, 2018, at 2:01 PM, Sven Barth via fpc-pascal <[hidden email]> wrote:
>
> The compiler does not know the type of the parameter, because overload selection occurs only after all parameters have been parsed. So during parsing the compiler would not know from which enum type to select the enum value. Not to mention unsolvable overloads if there would be two enums with the same value and the same name of the routine.

So it’s a limitation of overloading? I mentioned I saw the idea from Swift (https://developer.apple.com/library/content/documentation/Swift/Conceptual/Swift_Programming_Language/Enumerations.html) but I don’t know if they have overloaded functions. That’s too bad, it would be a nice feature. Thanks.

Regards,
        Ryan Joseph

_______________________________________________
fpc-pascal maillist  -  [hidden email]
http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal
Reply | Threaded
Open this post in threaded view
|

Re: Scoped enums and inferred types

Michael Van Canneyt
In reply to this post by Ryan Joseph


On Wed, 21 Feb 2018, Ryan Joseph wrote:

>
>
>> On Feb 21, 2018, at 1:54 PM, Michael Van Canneyt <[hidden email]> wrote:
>>
>> So this is "as designed". If you want to be able to write A, don't use
>> scoped enums.
>
> I got the idea from Swift (one of the things it does right) and it’s
> really nice to be able say "this = .value” instead of
> NSSomeLongNameOfSomethingValueKey.  It only works with assignments but it
> really cleans up code.  The reasons I suggested it was because some of my
> function calls were just getting stupid long and annoying to type plus
> difficult to remember (that’s important for programmers!) so the compiler
> could certainly help here.
The job of the compiler is to create correct code.
Not to ensure you write readable code. Every feature that is introduced
offers more scope for abuse (generics jump to mind).

Only you can make sure your code is readable.

I think often the cure is often worse than the problem.
Simply don't use scoped enums if you want to type less.

Michael.
_______________________________________________
fpc-pascal maillist  -  [hidden email]
http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal
Reply | Threaded
Open this post in threaded view
|

Re: Scoped enums and inferred types

Ryan Joseph


> On Feb 21, 2018, at 2:57 PM, Michael Van Canneyt <[hidden email]> wrote:
>
> The job of the compiler is to create correct code. Not to ensure you write readable code. Every feature that is introduced
> offers more scope for abuse (generics jump to mind).

I think you may change your mind if you had to type NSSomeLongNameOfSomethingValueKey all day instead of .Value. Remembering prefix names is a waste of my time if the compiler can do it for me. I wonder how many hours total in my life I’ve spent writing lists of constants with prefixes and then typing them back out in function calls.

Regards,
        Ryan Joseph

_______________________________________________
fpc-pascal maillist  -  [hidden email]
http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal
Reply | Threaded
Open this post in threaded view
|

Re: Scoped enums and inferred types

Mattias Gaertner
In reply to this post by Ryan Joseph
On Wed, 21 Feb 2018 09:38:17 +0700
Ryan Joseph <[hidden email]> wrote:

>[...]Doesn’t the compiler know the type and can infer “A” is relative to the scoped enum? I understand there’s a possibility for name conflicts but you could just use the full name in that case.

I think this would be confusing:

{$scopedenums on}
type
        TMyType = (A, B, C);
{$scopedenums off}
var
  A: integer;
 
procedure DoThis (t: TMyType; i: integer);
begin
end;
 
DoThis(A,A);

Mattias
_______________________________________________
fpc-pascal maillist  -  [hidden email]
http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal
Reply | Threaded
Open this post in threaded view
|

Re: Scoped enums and inferred types

Ryan Joseph


> On Feb 21, 2018, at 3:45 PM, Mattias Gaertner <[hidden email]> wrote:
>
> I think this would be confusing:
>
> {$scopedenums on}
> type
> TMyType = (A, B, C);
> {$scopedenums off}
> var
>  A: integer;
>
> procedure DoThis (t: TMyType; i: integer);
> begin
> end;
>
> DoThis(A,A);

yes it would be. :) Swift lets you opt out if you want so you can still do DoThis(TMyType.A, A) in that case but more specifically Swift keeps the . prefix so it would be DoThis(.A, A). Not always what you want but in some cases it’s really handy. In many API’s there’s a constant plague of long enum names all starting with the same prefix so shortening them to the logical suffix when possible just make sense.

Here’s something that’s all too common in code. There’s obviously some redundancy here we could optimize out. The only reason we keep the prefix is for name space integrity but logically in code what I’m really thinking about is the suffix so it makes sense that if the compiler could infer this it would save me time.

type
        TTileSortingFlag = ( kTileSortingStatic,
                                kTileSortingRamp,
                                kTileSortingIgnore,
                                kTileSortingParticle,
                                kTileSortingFloor,
                                kTileSortingFlat,
                                kTileSortingContainer,
                                kTileSortingOnRamp,
                                kTileSortingBufferStatic,
                                kTileSortingBufferDynamic
                                );


Regards,
        Ryan Joseph

_______________________________________________
fpc-pascal maillist  -  [hidden email]
http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal
Reply | Threaded
Open this post in threaded view
|

Re: Scoped enums and inferred types

Mattias Gaertner
On Wed, 21 Feb 2018 15:58:12 +0700
Ryan Joseph <[hidden email]> wrote:

>[...]
> type
> TTileSortingFlag = ( kTileSortingStatic,
> kTileSortingRamp,
> kTileSortingIgnore,
> kTileSortingParticle,
> kTileSortingFloor,
> kTileSortingFlat,
> kTileSortingContainer,
> kTileSortingOnRamp,
> kTileSortingBufferStatic,
> kTileSortingBufferDynamic
> );

I doubt that many would be using scopedenums for that.

Mattias
_______________________________________________
fpc-pascal maillist  -  [hidden email]
http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal
Reply | Threaded
Open this post in threaded view
|

Re: Scoped enums and inferred types

Ryan Joseph


> On Feb 21, 2018, at 4:09 PM, Mattias Gaertner <[hidden email]> wrote:
>
> I doubt that many would be using scopedenums for that.

why not? Scoped enums did clean that up a little but still lots of extra typing during assignments and parameters.

That compared to the previous is a still win though (less code is always a good thing).

{$scopedenums on}
type
        TTileSortingFlag = ( Static,
                                Ramp,
                                Ignore,
                                Particle,
                                Floor,
                                Flat,
                                Container,
                                OnRamp,
                                BufferStatic,
                                BufferDynamic
                                );
{$scopedenums off}


Regards,
        Ryan Joseph

_______________________________________________
fpc-pascal maillist  -  [hidden email]
http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal
Reply | Threaded
Open this post in threaded view
|

Re: Scoped enums and inferred types

Michael Van Canneyt


On Wed, 21 Feb 2018, Ryan Joseph wrote:

>
>
>> On Feb 21, 2018, at 4:09 PM, Mattias Gaertner <[hidden email]> wrote:
>>
>> I doubt that many would be using scopedenums for that.
>
> why not? Scoped enums did clean that up a little but still lots of extra typing during assignments and parameters.
>
> That compared to the previous is a still win though (less code is always a good thing).
>
> {$scopedenums on}
> type
> TTileSortingFlag = ( Static,
> Ramp,
> Ignore,
> Particle,
> Floor,
> Flat,
> Container,
> OnRamp,
> BufferStatic,
> BufferDynamic
> );
> {$scopedenums off}

And if you use
  type
        TTileSortingFlag = (    tsfStatic,
                                tsfRamp,
                                tsfIgnore,
                                tsfParticle,
  etc. );

You don't need scoped enums at all and the problem goes away.

You create a problem, and then you demand that the compiler introduces
tricks to solve the problem you created. Where is the logic in that ?

Don't create the problem to begin with, and we can all spend our time on
something more useful.

Michael.
_______________________________________________
fpc-pascal maillist  -  [hidden email]
http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal
Reply | Threaded
Open this post in threaded view
|

Re: Scoped enums and inferred types

Martok
In reply to this post by Mattias Gaertner
> I doubt that many would be using scopedenums for that.
Isn't that what they're for?

{$SCOPEDENUMS ON}
type
  TTileSortingFlag = (Static,
                      Ramp,
                      Ignore,
                      Particle,
                      Floor,
                      Flat,
                      Container,
                      OnRamp,
                      BufferStatic,
                      BufferDynamic
                      );

As a side note, Ryan: if you need to interoperate with other languages, using
enums is dangerous. FPC has different enum storage semantics from most other
compilers, and will happily drop you into "undefined" behaviour.
Example from C# syntax:
   enum Day : byte {Sat=1, Sun, Mon, Tue, Wed, Thu, Fri};
is _not_ translated as
   {$PACKENUM 1}
   Day = (Sat=1, Sun, Mon, Tue, Wed, Thu, Fri);
Instead, write
   {$PACKENUM 1}
   Day = (_low=low(Byte), Sat=1, Sun, Mon, Tue, Wed, Thu, Fri, _hi=high(Byte));


Regards,
Martok

_______________________________________________
fpc-pascal maillist  -  [hidden email]
http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal
Reply | Threaded
Open this post in threaded view
|

Re: Scoped enums and inferred types

Mattias Gaertner
In reply to this post by Ryan Joseph
On Wed, 21 Feb 2018 16:14:13 +0700
Ryan Joseph <[hidden email]> wrote:

>[...]
> {$scopedenums on}
> type
> TTileSortingFlag = ( Static,
> Ramp,
> Ignore,
> Particle,
> Floor,
> Flat,
> Container,
> OnRamp,
> BufferStatic,
> BufferDynamic
> );
> {$scopedenums off}

I misunderstood you. I thought you wanted to use scopedenums with the
prior version.

Mattias
_______________________________________________
fpc-pascal maillist  -  [hidden email]
http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal
Reply | Threaded
Open this post in threaded view
|

Re: Scoped enums and inferred types

Michael Van Canneyt
In reply to this post by Martok


On Wed, 21 Feb 2018, Martok wrote:

>> I doubt that many would be using scopedenums for that.
> Isn't that what they're for?
>
> {$SCOPEDENUMS ON}
> type
>  TTileSortingFlag = (Static,
>                      Ramp,
>                      Ignore,
>                      Particle,
>                      Floor,
>                      Flat,
>                      Container,
>                      OnRamp,
>                      BufferStatic,
>                      BufferDynamic
>                      );
>
> As a side note, Ryan: if you need to interoperate with other languages, using
> enums is dangerous. FPC has different enum storage semantics from most other
> compilers, and will happily drop you into "undefined" behaviour.

I was waiting for this reply from you. You didn't disappoint ;)

Michael.
_______________________________________________
fpc-pascal maillist  -  [hidden email]
http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal
Reply | Threaded
Open this post in threaded view
|

Re: Scoped enums and inferred types

Free Pascal - General mailing list
In reply to this post by Ryan Joseph
Am 21.02.2018 09:48 schrieb "Ryan Joseph" <[hidden email]>:


> On Feb 21, 2018, at 2:57 PM, Michael Van Canneyt <[hidden email]> wrote:
>
> The job of the compiler is to create correct code. Not to ensure you write readable code. Every feature that is introduced
> offers more scope for abuse (generics jump to mind).

I think you may change your mind if you had to type NSSomeLongNameOfSomethingValueKey all day instead of .Value. Remembering prefix names is a waste of my time if the compiler can do it for me. I wonder how many hours total in my life I’ve spent writing lists of constants with prefixes and then typing them back out in function calls.

I simply rely on my IDE (Lazarus, Visual Studio)  to complete long identifier names for me so that I don't have to. *shrugs*

Regards, 
Sven 

_______________________________________________
fpc-pascal maillist  -  [hidden email]
http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal
Reply | Threaded
Open this post in threaded view
|

Re: Scoped enums and inferred types

Michael Van Canneyt


On Wed, 21 Feb 2018, Sven Barth via fpc-pascal wrote:

> Am 21.02.2018 09:48 schrieb "Ryan Joseph" <[hidden email]>:
>
>
>
>> On Feb 21, 2018, at 2:57 PM, Michael Van Canneyt <[hidden email]>
> wrote:
>>
>> The job of the compiler is to create correct code. Not to ensure you
> write readable code. Every feature that is introduced
>> offers more scope for abuse (generics jump to mind).
>
> I think you may change your mind if you had to type
> NSSomeLongNameOfSomethingValueKey all day instead of .Value. Remembering
> prefix names is a waste of my time if the compiler can do it for me.
> I wonder how many hours total in my life I’ve spent writing lists of
> constants with prefixes and then typing them back out in function calls.
>
>
> I simply rely on my IDE (Lazarus, Visual Studio)  to complete long
> identifier names for me so that I don't have to. *shrugs*
My point exactly. Not the job of the compiler.

Michael.
_______________________________________________
fpc-pascal maillist  -  [hidden email]
http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal
Reply | Threaded
Open this post in threaded view
|

Re: Scoped enums and inferred types

wkitty42
In reply to this post by Free Pascal - General mailing list
On 02/21/2018 05:16 AM, Sven Barth via fpc-pascal wrote:
> I simply rely on my IDE (Lazarus, Visual Studio)  to complete long identifier
>  names for me so that I don't have to. *shrugs*

exactly my thoughts, too...


--
  NOTE: No off-list assistance is given without prior approval.
        *Please keep mailing list traffic on the list unless*
        *a signed and pre-paid contract is in effect with us.*
_______________________________________________
fpc-pascal maillist  -  [hidden email]
http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal
Reply | Threaded
Open this post in threaded view
|

Re: Scoped enums and inferred types

russeld
In reply to this post by Ryan Joseph
Pascal allows type declarations at the procedure level, so you could use type
aliases to reduce your typing and still have code completion:

procedure foo();
type
  SVK = NSSomeLongNameOfSomethingValueKey;
var
  a: SVK;
begin
  a := SVK.some_key_value;
end;

If you tried to use SVK elsewhere an error would be raised

Regards
Russ

   



--
Sent from: http://free-pascal-general.1045716.n5.nabble.com/
_______________________________________________
fpc-pascal maillist  -  [hidden email]
http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal
Reply | Threaded
Open this post in threaded view
|

Re: Scoped enums and inferred types

Martok
In reply to this post by Michael Van Canneyt
Am 21.02.2018 um 10:45 schrieb Michael Van Canneyt:
> I was waiting for this reply from you. You didn't disappoint ;)
Got an image to maintain ;-)

Took me long enough to come up with that actually fairly simple workaround,
might as well save others the trouble.

That stuff is like "bad keming", I just can't un-see it.
In related news: the example program for #32743 is undefined with more than 10
arguments in fpc and does, in fact, generate slightly wonky code that falls
apart at 255 arguments.


Regards,
Martok

_______________________________________________
fpc-pascal maillist  -  [hidden email]
http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal
12