[swift-evolution] [Discussion] Enum Leading Dot Prefixes

David Waite david at alkaline-solutions.com
Fri Feb 12 10:45:08 CST 2016


I like this, but I think it needs to handle more cases to truly promote consistency.

In static contexts, use of the case is consistent with that of a static variable or function (value directly in scope, so no dot prefix shortcut necessary).

enum Booly {
    case truth
    case falsehood
    
    static let yes = truth
    static let no = falsehood

    static func defaulted() -> Booly {
        return truth
    }

    static func workingAlternative() -> Booly {
        return yes
    }

It is however a special case in the non-static context:

extension Booly {
    func isDefault() -> Bool {
        return self == truth
    }
    
    func brokenYesVersion() -> Bool {
        // return self == yes // Error: Static member 'yes' cannot be used on instance of type 'Booly'
        return self == .yes
    }
}

And case usage is inconsistent in the body of a switch statement. In situations like an OptionSetType implementation, the compiler will complain about use of dot syntax w.r.t. not being an enumeration member. 

import Foundation

let flags:CFStringCompareFlags = [.CompareAnchored]

switch flags {
// case .CompareAnchored: // Error: Enum case 'CompareAnchored' ont found in type 'CFStringCompareFlags'
case CFStringCompareFlags.CompareAnchored:
    print("Anchored")
default:
    ()
}

In the case of enumerations, it will complain about anything from the enumerated type other than the case label!

let b:Booly = .yes

// switch b {
// case yes:  // Error: Use of unresolved identifier ‘yes’
// case .yes: // Error: Enum case 'yes' not found in type 'Booly'
// case Booly.yes: // Error: Enum case 'yes' not found in type 'Booly'
//}

let externalYes = Booly.truth

switch b {
case externalYes:
    print ("finally, yes!")
default:
    ()
}

IMHO, the *only* thing that the compiler should do special with case variable usage is that, when the type beings switched over is an enum and the cases of that enum are all specified as possible cases of the switch, not require the use of a default section.

(playground code copied to https://gist.github.com/dwaite/60c8dc05e498b747d0f2 )

-DW

> On Feb 12, 2016, at 7:23 AM, Daniel Steinberg via swift-evolution <swift-evolution at swift.org> wrote:
> 
> +1 for consistency reasons
> 
>> On Feb 11, 2016, at 10:00 PM, Erica Sadun via swift-evolution <swift-evolution at swift.org <mailto:swift-evolution at swift.org>> wrote:
>> 
>> https://gist.github.com/erica/e0b8a3a22ab716a19db4 <https://gist.github.com/erica/e0b8a3a22ab716a19db4>
>> 
>> Requiring Leading Dot Prefixes for Enum Instance Member Implementations
>> 
>> Proposal: TBD
>> Author(s): Erica Sadun <http://github.com/erica>, Chris Lattner <https://github.com/lattner>
>> Status: TBD
>> Review manager: TBD
>>  <https://gist.github.com/erica/e0b8a3a22ab716a19db4#introduction>Introduction
>> 
>> Enumeration cases are essentially static not instance type members. Unlike static members in structures and classes, enumeration cases can be mentioned in initializers and instance methods without referencing a fully qualified type. This makes little sense. In no other case can an instance implementation directly access a static member. This proposal introduces a rule that requires leading dots or fully qualified references (EnumType.caseMember) to provide a more consistent developer experience to clearly disambiguate static cases from instance members. 
>> 
>>  <https://gist.github.com/erica/e0b8a3a22ab716a19db4#motivation>Motivation
>> 
>> Swift infers the enclosing type for a case on a developer's behalf when the use is unambiguously of a single enumeration type. Inference enables you to craft switch statements like this:
>> 
>> switch Coin() {
>> case .Heads: print("Heads")
>> case .Tails: print("Tails")
>> }
>> A leading dot has become a conventional shorthand for "enumeration case" across the language. When used internally in enum implementations, a leading dot is not required, nor is a type name to access the static case member. The following code is legal in Swift.
>> 
>> enum Coin {
>>     case Heads, Tails
>>     func printMe() {
>>         switch self {
>>         case Heads: print("Heads")  // no leading dot
>>         case .Tails: print("Tails") // leading dot
>>         }
>> 
>>         if self == Heads {          // no leading dot
>>             print("This is a head")
>>         }
>> 
>>         if self == .Tails {         // leading dot
>>             print("This is a tail")
>>         }
>>     }
>> 
>>     init() {
>>         let cointoss = arc4random_uniform(2) == 0
>>         self = cointoss ? .Heads : Tails // mix and match leading dots
>>     }
>> }
>> This quirk produces a language inconsistency that can confuse developers and contravenes the guiding Principle of Least Astonishment. We propose to mandate a leading dot. This will bring case mentions into lock-step with the conventions used to reference them outside of enumeration type implementations.
>> 
>>  <https://gist.github.com/erica/e0b8a3a22ab716a19db4#detail-design>Detail Design
>> 
>> Under this rule, the compiler will require a leading dot for all case members. The change will not affect other static members, which require fully qualified references from instance methods and infer self from static methods.
>> 
>> enum Coin {
>>     case Heads, Tails
>>     static func doSomething() { print("Something") }
>>     static func staticFunc() { doSomething() } // does not require leading dot
>>     static func staticFunc2() { let foo = .Tails } // requires leading dot
>>     func instanceFunc() { self.dynamicType.doSomething() } // requires full qualification
>>     func otherFunc() { if self == .Heads ... } // requires leading dot, also initializers
>> 
>>     /// ...
>> } 
>>  <https://gist.github.com/erica/e0b8a3a22ab716a19db4#alternatives-considered>Alternatives Considered
>> 
>> Other than leaving the status quo, the language could force instance members to refer to cases using a fully qualified type, as with other static members.
>> _______________________________________________
>> swift-evolution mailing list
>> swift-evolution at swift.org <mailto:swift-evolution at swift.org>
>> https://lists.swift.org/mailman/listinfo/swift-evolution
> 
> _______________________________________________
> swift-evolution mailing list
> swift-evolution at swift.org
> https://lists.swift.org/mailman/listinfo/swift-evolution

-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://lists.swift.org/pipermail/swift-evolution/attachments/20160212/a426a9d6/attachment-0001.html>


More information about the swift-evolution mailing list