I agree with the argument about use of "where", not replacing the raw value and having some kind of initialization block. But I cannot see why "accessors" concept is any better than stored properties to solve the particular problem. The "accessors" concept has much wider scope than enums and is a separate proposal.
On Sat, May 28, 2016 at 11:39 PM, Brent Royal-Gordon <[email protected]> wrote: >>> - Abusing rawValue is just that: an abuse. >> >> My original proposal does not replace rawValue and is compatible with it. > > `rawValue` has a different purpose from how you're using it. It's supposed to > allow you to convert your type to some other *equivalent* type, like an > equivalent integer or string. Moreover, it's supposed to allow you to > *reconstruct* the instance from the raw value—remember, `RawRepresentable` > has an `init(rawValue:)` requirement. > > It is *not* supposed to be an ancillary bag of information on the side. > You're cramming a square peg into a round hole here. > > (Also, if you use `rawValue` for an ancillary bag of information, that means > you *can't* use it on the same type for its intended purpose. For instance, > you would not be able to assign numbers to your Planet enum's cases to help > you serialize them or bridge them to Objective-C. That's not good.) > >>> - Using `where` just doesn't match the use of `where` elsewhere in the >>> language; everywhere else, it's some kind of condition. >> >> It is also used in generic type constraints. Plus it reads like human >> language: `case mercury where (mass: 3.303e+23, radius: 2.4397e6)` > > But a generic constraint is also a type of condition: it specifies types > which are permitted and divides them from types that are not. > > This is *not* a condition. It's not anything like a condition. It's simply > not consistent with anything else in the language. > >>> - Dictionaries are the most straightforward way to handle this with the >>> current language, but their lack of exhaustiveness checking is a problem. >> >> Dictionaries can be used as workaround, but they cannot (lack of >> exhaustiveness) solve the problem. > > I agree that they're a halfway solution. > > If `ValuesEnumerable` were to be accepted (and to have a generic requirement > for its `allValues` property), you could write a Dictionary-like type which > ensured at initialization time that it was exhaustive. That's not as good as > compile time, but it's not bad—sort of a three-quarters solution. > > struct ExhaustiveDictionary<Key: Hashable, Value where Key: > ValuesEnumerable>: Collection, DictionaryLiteralConvertible { > private var dictionary: [Key: Value] > > init(dictionaryLiteral elements: (Key, Value)...) { > dictionary = [:] > for (k, v) in elements { > dictionary[k] = v > } > > if dictionary.count != Key.allValues.count { > let missingKeys = Key.allValues.filter { > dictionary[$0] == nil } > preconditionFailure("ExhaustiveDictionary is > missing elements from \(Key.self): \(missingKeys)") > } > } > > var startIndex: Dictionary.Index { > return dictionary.startIndex > } > var endIndex: Dictionary.Index { > return dictionary.endIndex > } > subscript(index: Dictionary.Index) -> (Key, Value) { > return dictionary[index] > } > func index(after i: Dictionary.Index) -> Dictionary.Index { > return dictionary.index(after: i) > } > > subscript(key: Key) -> Value { > get { return dictionary[key]! } > set { dictionary[key] = newValue } > } > } > >>> What I would do is borrow the "accessors" concept from the property >>> behaviors proposal and extend it so that it supported both functions and >>> variables. >> >> Wouldn't accessor just be a redundant keyword here? Currently enums do >> not support stored properties, so I guess there is no extra need to >> mark properties with any special keyword. > > The keyword is mainly to indicate the unusual syntax at the definition site, > where you only have to specify the name of the accessor you're defining, not > a `func` or `var` keyword, a return type, or even parameter names. (Like > `willSet`, there's a default parameter name you can use.) Secondarily, > though, I think it's helpful to indicate very explicitly that this is not an > ordinary method or property definition, even if the compiler could perhaps > sort things out without it. `accessor` is something a user can Google if > they've never seen it before. > >> Property accessors might work for enums with associated values, but >> not so well without them. > > The two have nothing to do with each other. I showed your planets example, > which has no associated values but uses accessors just fine. > > -- > Brent Royal-Gordon > Architechies > _______________________________________________ swift-evolution mailing list [email protected] https://lists.swift.org/mailman/listinfo/swift-evolution
