Name collisions in scoped enums

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

Name collisions in scoped enums

Free Pascal - General mailing list
I've been using scoped enums and noticed that I'm getting collisions with reserved keywords. Shouldn't these be allowed in scoped enums since they are required to be referenced using their type name as a prefix?


{$mode objfpc}

program test;

{$scopedenums on}

// error: Syntax error, "identifier" expected but "FILE" found
type
  TSet = set of ( File, Array );

begin

end.

Regards,
        Ryan Joseph

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

Re: Name collisions in scoped enums

Free Pascal - General mailing list
Am 04.05.2020 um 05:06 schrieb Ryan Joseph via fpc-pascal:
> I've been using scoped enums and noticed that I'm getting collisions with reserved keywords. Shouldn't these be allowed in scoped enums since they are required to be referenced using their type name as a prefix?

No, keywords have a higher priority than identifiers, their context
doesn't matter (e.g. you can't have a method named "File" either though
one could apply the same reasoning here). If you want to use keywords
you have to escape them using "&".

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

Re: Name collisions in scoped enums

Free Pascal - General mailing list
                                       

> On May 4, 2020, at 12:40 PM, Sven Barth <[hidden email]> wrote:
>
> No, keywords have a higher priority than identifiers, their context doesn't matter (e.g. you can't have a method named "File" either though one could apply the same reasoning here). If you want to use keywords you have to escape them using "&".

Methods could be called without a prefix and scoped enums must under all circumstances use their prefix right? I thought that made them unique in this regard. It would be nice to have those names freed up also if it was safe.

Regards,
        Ryan Joseph

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

Re: Name collisions in scoped enums

Michael Van Canneyt


On Mon, 4 May 2020, Ryan Joseph via fpc-pascal wrote:

>
>
>> On May 4, 2020, at 12:40 PM, Sven Barth <[hidden email]> wrote:
>>
>> No, keywords have a higher priority than identifiers, their context doesn't matter (e.g. you can't have a method named "File" either though one could apply the same reasoning here). If you want to use keywords you have to escape them using "&".
>
> Methods could be called without a prefix and scoped enums must under all circumstances use their prefix right?
> I thought that made them unique in this regard. It would be nice to have those names freed up also if it was safe.

Methods can't be keywords either, unless prefixed with &.

It's not safe to change this, that's why a keyword is a keyword:
it supersedes all identifiers, it is part of the language.

If you really must use keywords, just use (&File,&Array), that's what the & is for.

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

Re: Name collisions in scoped enums

Free Pascal - General mailing list


> On May 4, 2020, at 2:12 PM, Michael Van Canneyt <[hidden email]> wrote:
>
> Methods can't be keywords either, unless prefixed with &.
>
> It's not safe to change this, that's why a keyword is a keyword: it supersedes all identifiers, it is part of the language.

Yes but methods can be used without their class prefix so they aren't comparable as identifiers the same way scoped enums are, because scoped enums require the prefix to be valid at all. Always, that's fine, I just wanted to make sure this wasn't an omission by accident.

Speaking of that I just remembered something else. In Swift I liked that they allowed scoped enums to be used without their prefix in the instance that they are assigned to a compatible type, or in the correct context.

For example if you have an enum
 
TNames = (A, B, C);

and a function
       
SayNames(names: TNames);

you can call it as SayNames([A, B]); and this is valid because of the context.

Is that possible to implement in scoped enums? It's a nice time saver to not have to deal with the prefix when the context is correct but you still get the namespace protection in the rest of the program.

Regards,
        Ryan Joseph

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

Re: Name collisions in scoped enums

Michael Van Canneyt


On Mon, 4 May 2020, Ryan Joseph via fpc-pascal wrote:

>
>
>> On May 4, 2020, at 2:12 PM, Michael Van Canneyt <[hidden email]> wrote:
>>
>> Methods can't be keywords either, unless prefixed with &.
>>
>> It's not safe to change this, that's why a keyword is a keyword: it supersedes all identifiers, it is part of the language.
>
> Yes but methods can be used without their class prefix so they aren't comparable as identifiers the same way scoped enums are,
> because scoped enums require the prefix to be valid at all. Always, that's fine, I just wanted to make sure this wasn't an omission by accident.
>
> Speaking of that I just remembered something else.  In Swift I liked that
> they allowed scoped enums to be used without their prefix in the instance
> that they are assigned to a compatible type, or in the correct context.
>
> For example if you have an enum
>
> TNames = (A, B, C);
>
> and a function
>
> SayNames(names: TNames);
>
> you can call it as SayNames([A, B]); and this is valid because of the context.
>
> Is that possible to implement in scoped enums? It's a nice time saver to not have to deal with the prefix when the context is correct but you still get the namespace protection in the rest of the program.

That is how enums work by default in Pascal.

If you don't force scoped enums, you can still scope them.

if you use
$scopedenums on
then you simply force the use instead of having it optional.

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

Re: Name collisions in scoped enums

Free Pascal - General mailing list
In reply to this post by Free Pascal - General mailing list
Ryan Joseph via fpc-pascal <[hidden email]> schrieb am Mo., 4. Mai 2020, 18:58:


> On May 4, 2020, at 2:12 PM, Michael Van Canneyt <[hidden email]> wrote:
>
> Methods can't be keywords either, unless prefixed with &.
>
> It's not safe to change this, that's why a keyword is a keyword: it supersedes all identifiers, it is part of the language.

Yes but methods can be used without their class prefix so they aren't comparable as identifiers the same way scoped enums are, because scoped enums require the prefix to be valid at all. Always, that's fine, I just wanted to make sure this wasn't an omission by accident.

Keywords have a higher precedence and are handled in the scanner. This will not be changed. 


Speaking of that I just remembered something else. In Swift I liked that they allowed scoped enums to be used without their prefix in the instance that they are assigned to a compatible type, or in the correct context.

For example if you have an enum

TNames = (A, B, C);

and a function

SayNames(names: TNames);

you can call it as SayNames([A, B]); and this is valid because of the context.

Is that possible to implement in scoped enums? It's a nice time saver to not have to deal with the prefix when the context is correct but you still get the namespace protection in the rest of the program.

No, because there could be a method A that returns a TName. 

Regards, 
Sven 

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

Re: Name collisions in scoped enums

Free Pascal - General mailing list
In reply to this post by Michael Van Canneyt
       

> On May 4, 2020, at 10:44 PM, Michael Van Canneyt <[hidden email]> wrote:
>
> That is how enums work by default in Pascal.
>
> If you don't force scoped enums, you can still scope them.
>
> if you use
> $scopedenums on then you simply force the use instead of having it optional.

But the names collide then, that's the whole point. We want to protect against name collisions and we don't want to type long prefix names every time. Scoped enums fixes half of that by formalizing the prefix syntax but you still need to type it even when it could be inferred by context.

Swift figured out how to do this and so should Pascal imo.


From https://docs.swift.org/swift-book/LanguageGuide/Enumerations.html:

Each enumeration definition defines a new type. Like other types in Swift, their names (such as CompassPoint and Planet) start with a capital letter. Give enumeration types singular rather than plural names, so that they read as self-evident:

        • var directionToHead = CompassPoint.west

The type of directionToHead is inferred when it’s initialized with one of the possible values of CompassPoint. Once directionToHead is declared as a CompassPoint, you can set it to a different CompassPoint value using a shorter dot syntax:

        • directionToHead = .east

Regards,
        Ryan Joseph

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

Re: Name collisions in scoped enums

Free Pascal - General mailing list
Am 05.05.2020 um 04:16 schrieb Ryan Joseph via fpc-pascal:

>
>
>> On May 4, 2020, at 10:44 PM, Michael Van Canneyt <[hidden email]> wrote:
>>
>> That is how enums work by default in Pascal.
>>
>> If you don't force scoped enums, you can still scope them.
>>
>> if you use
>> $scopedenums on then you simply force the use instead of having it optional.
> But the names collide then, that's the whole point. We want to protect against name collisions and we don't want to type long prefix names every time. Scoped enums fixes half of that by formalizing the prefix syntax but you still need to type it even when it could be inferred by context.
>
> Swift figured out how to do this and so should Pascal imo.

Surprise: Pascal is /not/ about writing less. Pascal is about writing
correct code.

Take this:

=== code begin ===

{$ScopedEnums On}

type
   TTest = (
     Value1,
     Value2
   );
   TTests = set of TTest;

procedure Something(aArg: array of LongInt); begin end;
procedure Something(aArg: TTests); begin end;

var
   Value1: LongInt;
begin
   Something([Value1]);
end.

=== code end ===

Right now it's clear what procedure is called, namely the one with the
open array. If we'd allow scoped enums without their enum type then this
would result in a "can't decide which method to call". This example
might appear constructed, but imagine these to procedures coming from
two different, unrelated units.

But there is another reason why what you suggest is even /impossible/:
The parser does not know what is called until it has completely parsed
the call and then has done its overload solution. Thus it /can not/ find
a scoped enum value without its type name (such enum values are not
visible in the unit's symtable after all!). And the compiler is not
allowed to just pick a function and hope for the best as that might lead
to the wrong one (think about the example above or one where you have
two different enums with the same value).

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

Re: Name collisions in scoped enums

Free Pascal - General mailing list


> On May 5, 2020, at 12:19 PM, Sven Barth <[hidden email]> wrote:
>
> Right now it's clear what procedure is called, namely the one with the open array. If we'd allow scoped enums without their enum type then this would result in a "can't decide which method to call". This example might appear constructed, but imagine these to procedures coming from two different, unrelated units.

I wonder how Swift accomplished this then. Anyways, I thought it was a nice feature in Swift but it's not important at all.

Regards,
        Ryan Joseph

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

Re: Name collisions in scoped enums

Bjarne Bäckström
In reply to this post by Free Pascal - General mailing list


> 5 maj 2020 kl. 07:19 skrev Sven Barth via fpc-pascal <[hidden email]>:
>
> Am 05.05.2020 um 04:16 schrieb Ryan Joseph via fpc-pascal:
>>
>>
>>> On May 4, 2020, at 10:44 PM, Michael Van Canneyt <[hidden email]> wrote:
>>>
>>> That is how enums work by default in Pascal.
>>>
>>> If you don't force scoped enums, you can still scope them.
>>>
>>> if you use
>>> $scopedenums on then you simply force the use instead of having it optional.
>> But the names collide then, that's the whole point. We want to protect against name collisions and we don't want to type long prefix names every time. Scoped enums fixes half of that by formalizing the prefix syntax but you still need to type it even when it could be inferred by context.
>>
>> Swift figured out how to do this and so should Pascal imo.
>
> Surprise: Pascal is /not/ about writing less. Pascal is about writing correct code.

Couldn't agree more!

/Bjarne.

(back to lurking)

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