[Pitch] Allow numerical keywords in member references


(Adrian Zubarev) #1

Hi Swift community, I’d like to pitch this idea again.

Swift already has the pitched feature, but it is exclusive for tuples only. SE–0071 allowed the use of keywords after the . in a member access, except for those keywords that have special meaning by using back-ticks. However, members starting with numbers are not special keywords and as already mentioned, numerical members are already allowed in tuples.

I propose to extend that capability to the whole language and make that behavior consistent. To disambiguate members starting with a number one would need to use back-ticks.

// Enum
enum ErrorCode : String {
     
    case `2345` = "my description for 2345"
    case `123a` = "my description for 123a"
    case `123b` = "my description for 123b"
}

let code = ErrorCode.2345

// Function
func `42foo`(label: Type, `12345`: Type, `0987something`: Type) { … }

// Tuple
(`1`: Int, `2`: Int)
My question is: would that be in scope for Swift 4?

···

--
Adrian Zubarev
Sent with Airmail


(Adrian Zubarev) #2

I forget to mention, this should be also valid:

let `42` = 42

print(`42`)

struct A {
    let `0` = 0
}

let number = A().0

···

--
Adrian Zubarev
Sent with Airmail

Am 9. März 2017 um 08:24:54, Adrian Zubarev (adrian.zubarev@devandartist.com) schrieb:

Hi Swift community, I’d like to pitch this idea again.

Swift already has the pitched feature, but it is exclusive for tuples only. SE–0071 allowed the use of keywords after the . in a member access, except for those keywords that have special meaning by using back-ticks. However, members starting with numbers are not special keywords and as already mentioned, numerical members are already allowed in tuples.

I propose to extend that capability to the whole language and make that behavior consistent. To disambiguate members starting with a number one would need to use back-ticks.

// Enum
enum ErrorCode : String {
      
    case `2345` = "my description for 2345"
    case `123a` = "my description for 123a"
    case `123b` = "my description for 123b"
}

let code = ErrorCode.2345

// Function
func `42foo`(label: Type, `12345`: Type, `0987something`: Type) { … }

// Tuple
(`1`: Int, `2`: Int)
My question is: would that be in scope for Swift 4?

--
Adrian Zubarev
Sent with Airmail


(Slava Pestov) #3

I forget to mention, this should be also valid:

let `42` = 42

print(`42`)

struct A {
    let `0` = 0
}

let number = A().0

-1

This seems really confusing.

extension Int { var `0`: Int { return 0 } }

3.0 // is this a float literal?
3 .0 // member access?
.0 // this is actually a contextual member access, and not a literal ‘0.0’?

I’d prefer if .0, .1, … were reserved for tuple fields; .0 is already not very descriptive, but at the very least if you see it in source code you know you have a tuple type and not something else.

Also the compiler’s name mangling relies on the fact that identifiers never begin with a numeric character or symbol.

Can you give a motivating example where allowing an identifier to start with a number actually helps readability?

Slava

···

On Mar 8, 2017, at 11:33 PM, Adrian Zubarev via swift-evolution <swift-evolution@swift.org> wrote:

--
Adrian Zubarev
Sent with Airmail

Am 9. März 2017 um 08:24:54, Adrian Zubarev (adrian.zubarev@devandartist.com <mailto:adrian.zubarev@devandartist.com>) schrieb:

Hi Swift community, I’d like to pitch this idea again.

Swift already has the pitched feature, but it is exclusive for tuples only. SE–0071 allowed the use of keywords after the . in a member access, except for those keywords that have special meaning by using back-ticks. However, members starting with numbers are not special keywords and as already mentioned, numerical members are already allowed in tuples.

I propose to extend that capability to the whole language and make that behavior consistent. To disambiguate members starting with a number one would need to use back-ticks.

// Enum
enum ErrorCode : String {
      
    case `2345` = "my description for 2345"
    case `123a` = "my description for 123a"
    case `123b` = "my description for 123b"
}

let code = ErrorCode.2345

// Function
func `42foo`(label: Type, `12345`: Type, `0987something`: Type) { … }

// Tuple
(`1`: Int, `2`: Int)
My question is: would that be in scope for Swift 4?

--
Adrian Zubarev
Sent with Airmail

_______________________________________________
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


(Adrian Zubarev) #4

I don’t have more precise examples except something like TCP socket error codes as an enum. The example with the number literal is actually really good, because it also shows the bad sides of the pitch. However we could allow numerical enum cases without any issues right?

···

--
Adrian Zubarev
Sent with Airmail

Am 9. März 2017 um 08:41:13, Slava Pestov (spestov@apple.com) schrieb:

On Mar 8, 2017, at 11:33 PM, Adrian Zubarev via swift-evolution <swift-evolution@swift.org> wrote:

I forget to mention, this should be also valid:

let `42` = 42

print(`42`)

struct A {
    let `0` = 0
}

let number = A().0

-1

This seems really confusing.

extension Int { var `0`: Int { return 0 } }

3.0 // is this a float literal?
3 .0 // member access?
.0 // this is actually a contextual member access, and not a literal ‘0.0’?

I’d prefer if .0, .1, … were reserved for tuple fields; .0 is already not very descriptive, but at the very least if you see it in source code you know you have a tuple type and not something else.

Also the compiler’s name mangling relies on the fact that identifiers never begin with a numeric character or symbol.

Can you give a motivating example where allowing an identifier to start with a number actually helps readability?

Slava

--
Adrian Zubarev
Sent with Airmail

Am 9. März 2017 um 08:24:54, Adrian Zubarev (adrian.zubarev@devandartist.com) schrieb:

Hi Swift community, I’d like to pitch this idea again.

Swift already has the pitched feature, but it is exclusive for tuples only. SE–0071 allowed the use of keywords after the . in a member access, except for those keywords that have special meaning by using back-ticks. However, members starting with numbers are not special keywords and as already mentioned, numerical members are already allowed in tuples.

I propose to extend that capability to the whole language and make that behavior consistent. To disambiguate members starting with a number one would need to use back-ticks.

// Enum
enum ErrorCode : String {
       
    case `2345` = "my description for 2345"
    case `123a` = "my description for 123a"
    case `123b` = "my description for 123b"
}

let code = ErrorCode.2345

// Function
func `42foo`(label: Type, `12345`: Type, `0987something`: Type) { … }

// Tuple
(`1`: Int, `2`: Int)
My question is: would that be in scope for Swift 4?

--
Adrian Zubarev
Sent with Airmail

_______________________________________________
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


(Slava Pestov) #5

I don’t have more precise examples except something like TCP socket error codes as an enum.

I would expect that the error code is available as a computed property of the enum value, perhaps as its raw value or something else. I would not expect it to be part of the enum case *name*. What significance does the numeric code have to the reader of the code, and when do you ever want to permanently freeze error codes in an API like this?

Note that even Unix errno error codes are not standardized across unices or even different architectures running Linux; only their names are.

Slava

···

On Mar 8, 2017, at 11:46 PM, Adrian Zubarev <adrian.zubarev@devandartist.com> wrote:

The example with the number literal is actually really good, because it also shows the bad sides of the pitch. However we could allow numerical enum cases without any issues right?

--
Adrian Zubarev
Sent with Airmail

Am 9. März 2017 um 08:41:13, Slava Pestov (spestov@apple.com <mailto:spestov@apple.com>) schrieb:

On Mar 8, 2017, at 11:33 PM, Adrian Zubarev via swift-evolution <swift-evolution@swift.org <mailto:swift-evolution@swift.org>> wrote:

I forget to mention, this should be also valid:

let `42` = 42

print(`42`)

struct A {
    let `0` = 0
}

let number = A().0

-1

This seems really confusing.

extension Int { var `0`: Int { return 0 } }

3.0 // is this a float literal?
3 .0 // member access?
.0 // this is actually a contextual member access, and not a literal ‘0.0’?

I’d prefer if .0, .1, … were reserved for tuple fields; .0 is already not very descriptive, but at the very least if you see it in source code you know you have a tuple type and not something else.

Also the compiler’s name mangling relies on the fact that identifiers never begin with a numeric character or symbol.

Can you give a motivating example where allowing an identifier to start with a number actually helps readability?

Slava

--
Adrian Zubarev
Sent with Airmail

Am 9. März 2017 um 08:24:54, Adrian Zubarev (adrian.zubarev@devandartist.com <mailto:adrian.zubarev@devandartist.com>) schrieb:

Hi Swift community, I’d like to pitch this idea again.

Swift already has the pitched feature, but it is exclusive for tuples only. SE–0071 allowed the use of keywords after the . in a member access, except for those keywords that have special meaning by using back-ticks. However, members starting with numbers are not special keywords and as already mentioned, numerical members are already allowed in tuples.

I propose to extend that capability to the whole language and make that behavior consistent. To disambiguate members starting with a number one would need to use back-ticks.

// Enum
enum ErrorCode : String {
       
    case `2345` = "my description for 2345"
    case `123a` = "my description for 123a"
    case `123b` = "my description for 123b"
}

let code = ErrorCode.2345

// Function
func `42foo`(label: Type, `12345`: Type, `0987something`: Type) { … }

// Tuple
(`1`: Int, `2`: Int)
My question is: would that be in scope for Swift 4?

--
Adrian Zubarev
Sent with Airmail

_______________________________________________
swift-evolution mailing list
swift-evolution@swift.org <mailto:swift-evolution@swift.org>
https://lists.swift.org/mailman/listinfo/swift-evolution


(Adrian Zubarev) #6

My point would be to have a exact set of possible numerical cases. The issue with numerical cases is that they don’t have to be ordered and they could also be overlapping with other subsystems (by subsystem I mean a subsystem of your particular project).

Even if we had the ability to limit the range of numerical types like Int, we still might not be able to exclude inner values for that range, which makes RawRepresentable not quite efficient to work with. Numerical enum cases on the other hand could solve that issue elegantly.

I see the reason for types other because of FP and integer literals, but I don’t see why we couldn’t have numerical enum cases.

···

--
Adrian Zubarev
Sent with Airmail

Am 9. März 2017 um 08:52:34, Slava Pestov (spestov@apple.com) schrieb:

On Mar 8, 2017, at 11:46 PM, Adrian Zubarev <adrian.zubarev@devandartist.com> wrote:

I don’t have more precise examples except something like TCP socket error codes as an enum.

I would expect that the error code is available as a computed property of the enum value, perhaps as its raw value or something else. I would not expect it to be part of the enum case *name*. What significance does the numeric code have to the reader of the code, and when do you ever want to permanently freeze error codes in an API like this?

Note that even Unix errno error codes are not standardized across unices or even different architectures running Linux; only their names are.

Slava

The example with the number literal is actually really good, because it also shows the bad sides of the pitch. However we could allow numerical enum cases without any issues right?

--
Adrian Zubarev
Sent with Airmail

Am 9. März 2017 um 08:41:13, Slava Pestov (spestov@apple.com) schrieb:

On Mar 8, 2017, at 11:33 PM, Adrian Zubarev via swift-evolution <swift-evolution@swift.org> wrote:

I forget to mention, this should be also valid:

let `42` = 42

print(`42`)

struct A {
    let `0` = 0
}

let number = A().0

-1

This seems really confusing.

extension Int { var `0`: Int { return 0 } }

3.0 // is this a float literal?
3 .0 // member access?
.0 // this is actually a contextual member access, and not a literal ‘0.0’?

I’d prefer if .0, .1, … were reserved for tuple fields; .0 is already not very descriptive, but at the very least if you see it in source code you know you have a tuple type and not something else.

Also the compiler’s name mangling relies on the fact that identifiers never begin with a numeric character or symbol.

Can you give a motivating example where allowing an identifier to start with a number actually helps readability?

Slava

--
Adrian Zubarev
Sent with Airmail

Am 9. März 2017 um 08:24:54, Adrian Zubarev (adrian.zubarev@devandartist.com) schrieb:

Hi Swift community, I’d like to pitch this idea again.

Swift already has the pitched feature, but it is exclusive for tuples only. SE–0071 allowed the use of keywords after the . in a member access, except for those keywords that have special meaning by using back-ticks. However, members starting with numbers are not special keywords and as already mentioned, numerical members are already allowed in tuples.

I propose to extend that capability to the whole language and make that behavior consistent. To disambiguate members starting with a number one would need to use back-ticks.

// Enum
enum ErrorCode : String {
        
    case `2345` = "my description for 2345"
    case `123a` = "my description for 123a"
    case `123b` = "my description for 123b"
}

let code = ErrorCode.2345

// Function
func `42foo`(label: Type, `12345`: Type, `0987something`: Type) { … }

// Tuple
(`1`: Int, `2`: Int)
My question is: would that be in scope for Swift 4?

--
Adrian Zubarev
Sent with Airmail

_______________________________________________
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


(Ross O'Brien) #7

I could see a purpose for identifiers which started numbers but weren't
entirely numerical.
e.g.
enum Dimensions { case `2D`, `3D` }
enum DiceRoll { case d6, `2d6` }
func roll(dice: DiceRoll) -> Int { ... }
roll(.`2d6`)

I'm not sure I see one for identifiers which are entirely numerical.

Ross

···

On Thu, Mar 9, 2017 at 8:05 AM, Adrian Zubarev via swift-evolution < swift-evolution@swift.org> wrote:

My point would be to have a exact set of possible numerical cases. The
issue with numerical cases is that they don’t have to be ordered and they
could also be overlapping with other subsystems (by subsystem I mean a
subsystem of your particular project).

Even if we had the ability to limit the range of numerical types like Int,
we still might not be able to exclude inner values for that range, which
makes RawRepresentable not quite efficient to work with. Numerical enum
cases on the other hand could solve that issue elegantly.

I see the reason for types other because of FP and integer literals, but I
don’t see why we couldn’t have numerical enum cases.

--
Adrian Zubarev
Sent with Airmail

Am 9. März 2017 um 08:52:34, Slava Pestov (spestov@apple.com) schrieb:

On Mar 8, 2017, at 11:46 PM, Adrian Zubarev <adrian.zubarev@devandartist. > > wrote:

I don’t have more precise examples except something like TCP socket error
codes as an enum.

I would expect that the error code is available as a computed property of
the enum value, perhaps as its raw value or something else. I would not
expect it to be part of the enum case *name*. What significance does the
numeric code have to the reader of the code, and when do you ever want to
permanently freeze error codes in an API like this?

Note that even Unix errno error codes are not standardized across unices
or even different architectures running Linux; only their names are.

Slava

The example with the number literal is actually really good, because it
also shows the bad sides of the pitch. However we could allow numerical
enum cases without any issues right?

--
Adrian Zubarev
Sent with Airmail

Am 9. März 2017 um 08:41:13, Slava Pestov (spestov@apple.com) schrieb:

On Mar 8, 2017, at 11:33 PM, Adrian Zubarev via swift-evolution < > swift-evolution@swift.org> wrote:

I forget to mention, this should be also valid:

let `42` = 42

print(`42`)

struct A {
    let `0` = 0
}

let number = A().0

-1

This seems really confusing.

extension Int { var `0`: Int { return 0 } }

3.0 // is this a float literal?
3 .0 // member access?
.0 // this is actually a contextual member access, and not a literal ‘0.0’?

I’d prefer if .0, .1, … were reserved for tuple fields; .0 is already not
very descriptive, but at the very least if you see it in source code you
know you have a tuple type and not something else.

Also the compiler’s name mangling relies on the fact that identifiers
never begin with a numeric character or symbol.

Can you give a motivating example where allowing an identifier to start
with a number actually helps readability?

Slava

--
Adrian Zubarev
Sent with Airmail

Am 9. März 2017 um 08:24:54, Adrian Zubarev (adrian.zubarev@devandartist.
com) schrieb:

Hi Swift community, I’d like to pitch this idea again.

Swift already has the pitched feature, but it is exclusive for tuples only.
*SE–0071* allowed the use of keywords after the . in a member access,
except for those keywords that have special meaning by using back-ticks.
However, members starting with numbers are not special keywords and as
already mentioned, numerical members are already allowed in tuples.

I propose to extend that capability to the whole language and make that
behavior consistent. To disambiguate members starting with a number one
would need to use back-ticks.

// Enum
enum ErrorCode : String {

    case `2345` = "my description for 2345"
    case `123a` = "my description for 123a"
    case `123b` = "my description for 123b"
}

let code = ErrorCode.2345

// Function
func `42foo`(label: Type, `12345`: Type, `0987something`: Type) { … }

// Tuple
(`1`: Int, `2`: Int)

My question is: would that be in scope for Swift 4?

--
Adrian Zubarev
Sent with Airmail

_______________________________________________
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution

_______________________________________________
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


(David Sweeris) #8

That's certainly a much easier sell... How does "_" fit into this? I know `123_456` is a valid integer literal and that `_1` is a valid identifier. I don't know if `_1` is a valid integer literal.

I'd like to support purely numeric identifiers, but I can't think of a way around the ambiguity of `3.0`. Maybe only allow it if the enclosing type isn't ExpressibleByIntegerLiteral? It feels more than a bit odd, though, to have a property name's validity depend on whether or not it's in a ExpressibleByIntegerLiteral type.

- Dave Sweeris

···

On Mar 9, 2017, at 04:40, Ross O'Brien via swift-evolution <swift-evolution@swift.org> wrote:

I could see a purpose for identifiers which started numbers but weren't entirely numerical.
e.g.
enum Dimensions { case `2D`, `3D` }
enum DiceRoll { case d6, `2d6` }
func roll(dice: DiceRoll) -> Int { ... }
roll(.`2d6`)

I'm not sure I see one for identifiers which are entirely numerical.


(Derrick Ho) #9

-1

Something like `42` will make things confusing.

···

On Thu, Mar 9, 2017 at 5:53 PM David Sweeris via swift-evolution < swift-evolution@swift.org> wrote:

On Mar 9, 2017, at 04:40, Ross O'Brien via swift-evolution < > swift-evolution@swift.org> wrote:

I could see a purpose for identifiers which started numbers but weren't
entirely numerical.
e.g.
enum Dimensions { case `2D`, `3D` }
enum DiceRoll { case d6, `2d6` }
func roll(dice: DiceRoll) -> Int { ... }
roll(.`2d6`)

I'm not sure I see one for identifiers which are entirely numerical.

That's certainly a much easier sell... How does "_" fit into this? I know
`123_456` is a valid integer literal and that `_1` is a valid identifier. I
don't know if `_1` is a valid integer literal.

I'd *like* to support purely numeric identifiers, but I can't think of a
way around the ambiguity of `3.0`. Maybe only allow it if the enclosing
type isn't ExpressibleByIntegerLiteral? It feels more than a bit odd,
though, to have a property name's validity depend on whether or not it's in
a ExpressibleByIntegerLiteral type.

- Dave Sweeris

_______________________________________________
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution