> On 12 Oct 2016, at 21:21, Charles Srstka via swift-evolution 
> <swift-evolution@swift.org> wrote:
> 
>> On Oct 11, 2016, at 8:51 PM, Xiaodi Wu <xiaodi...@gmail.com> wrote:
>> 
>> On Tue, Oct 11, 2016 at 8:21 PM, Charles Srstka via swift-evolution 
>> <swift-evolution@swift.org> wrote:
>>> On Oct 11, 2016, at 4:42 PM, Braeden Profile via swift-evolution 
>>> <swift-evolution@swift.org> wrote:
>>> 
>>> enum RectSize
>>> {
>>>    let height:Int
>>>    let width:Int
>>>    case small(width: 30, height: 30)
>>>    case medium(width: 60, height: 60)
>>>    case large(width: 120, height: 120)
>>> }
>> 
>> I like the concept, but this doesn’t seem as flexible as it could be, and 
>> could get ugly when mixing these defaults with enum associated values. How 
>> about dynamic properties instead? Something like:
>> 
>> enum RectSize {
>>      var height: Int { get }
>>      var width: Int { get }
>> 
>>      case small {
>>              height { return 30 }
>>              width { return 30 }
>>      }
>> 
>>      case medium {
>>              height { return 60 }
>>              width { return 60 }
>>      }
>> 
>>      case large {
>>              height { return 120 }
>>              width { return 120 }
>>      }
>> 
>>      case custom(width: Int, height: Int) {
>>              height { return height }
>>              width { return width }
>>      }
>> }
>> 
>> I'd be interested in expanding raw values to accommodate other types, but 
>> computed properties are already possible:
>> 
>> ```
>> enum RectSize {
>>     case small, medium, large
>> 
>>     var height: Int {
>>         switch self {
>>         case .small:
>>             return 30
>>         case .medium:
>>             return 60
>>         case .large:
>>             return 120
>>         }
>>     }
>>     
>>     var width: Int {
>>         return height
>>     }
>> } 
>> ```
>> 
>> There have been off-and-on proposals to change the syntax from what it is 
>> currently, but none have been deemed a significant enough advantage to merit 
>> a change--even before source-breaking changes in Swift 3 were over. Keeping 
>> in mind that sugar is the lowest priority for Swift 4 (and not in scope for 
>> the current phase), what's the advantage of your proposed syntax for 
>> computed properties over the existing one?
> 
> It’s *possible*, but the syntax is incredibly verbose, unwieldy, and ugly. 
> Imagine an enum with lots of cases and lots of properties—and before you say 
> this is contrived, this already currently happens quite a lot with error 
> enums (pardon the badly written error messages; this is only for example):
> 
> enum FileError: Error, LocalizedError {
>     case notFound(url: URL)
>     case accessDenied(url: URL)
>     case incorrectFormat(url: URL)
>     case ioError(url: URL)
>     // ... imagine there are another 20 or so of these ...
>     
>     // Now, implement LocalizedError:
>     
>     var errorDescription: String? {
>         switch self {
>         case let .notFound(url: url):
>             return "Could not access the file \(url.lastPathComponent) 
> because it could not be found."
>         case let .accessDenied(url: url):
>             return "Could not access the file \(url.lastPathComponent) 
> because access was denied."
>         case let .incorrectFormat(url: url):
>             return "Could not access the file \(url.lastPathComponent) 
> because it was not in the expected format."
>         case let .ioError(url: url):
>             return "Could not access the file \(url.lastPathComponent) 
> because an I/O error occurred."
>         // ... etc ...
>         }
>     }
>     
>     var failureReason: String? {
>         switch self {
>         case let .notFound(url: url):
>             return "The file \(url.lastPathComponent) could not be found."
>         case let .accessDenied(url: url):
>             return "We do not have permission to view the file 
> \(url.lastPathComponent)"
>         case let .incorrectFormat(url: url):
>             return "The file \(url.lastPathComponent) was not in the expected 
> format."
>         case let .ioError(url: url):
>             return "An I/O error occurred while accessing the file 
> \(url.lastPathComponent)."
>         // ... etc ...
>         }
>     }
>     
>     var recoverySuggestion: String? {
>         switch self {
>         case .notFound:
>             return "Please locate the correct file and try again."
>         case .accessDenied:
>             return "You can change the file's permissions using the Finder's 
> Get Info window."
>         case .incorrectFormat:
>             return "The file may have become corrupt."
>         case .ioError:
>             return "Dear Lord, the hard drive may be failing."
>         // ... etc ...
>         }
>     }
>     
>     var helpAnchor: String? {
>         switch self {
>         case .notFound:
>             return "notFound"
>         case .accessDenied:
>             return "accessDenied"
>         case .incorrectFormat:
>             return "incorrectFormat"
>         case .ioError:
>             return "ioError"
>         // ... etc ...
>         }
>     }
>     
>     // Each of these errors references a file URL, so I may want a property 
> for that too
>     
>     var url: URL {
>         switch self {
>         case let .notFound(url: url):
>             return url
>         case let .accessDenied(url: url):
>             return url
>         case let .incorrectFormat(url: url):
>             return url
>         case let .ioError(url: url):
>             return url
>         // ... etc ...
>         }
>     }
> }
> 
> Look how ugly this is. Switch statements everywhere, related values separated 
> by really large amounts of space (and even more so if this error had more 
> cases, or if I’d implemented other error protocols like RecoverableError, 
> CustomNSError, etc.).
> 
> With the improved syntax, this could look something like this instead:
> 
> enum FileError: Error, LocalizedError {
>     var url: URL { get }
>     
>     case notFound(url: URL) {
>         errorDescription = "Could not access the file 
> \(url.lastPathComponent) because it could not be found."
>         failureReason = "The file \(url.lastPathComponent) could not be 
> found."
>         recoverySuggestion = "Please locate the correct file and try again."
>         helpAnchor = "notFound"
>         url = url
>     }
>     
>     case accessDenied(url: URL) {
>         errorDescription = "Could not access the file 
> \(url.lastPathComponent) because access was denied."
>         failureReason = "We do not have permission to view the file 
> \(url.lastPathComponent)"
>         recoverySuggestion = "You can change the file's permissions using the 
> Finder's Get Info window."
>         helpAnchor = "accessDenied"
>         url = url
>     }
>     
>     case incorrectFormat(url: URL) {
>         errorDescription = "Could not access the file 
> \(url.lastPathComponent) because it was not in the expected format."
>         failureReason = "The file \(url.lastPathComponent) was not in the 
> expected format."
>         recoverySuggestion = "The file may have become corrupt."
>         helpAnchor = "incorrectFormat"
>         url = url
>     }
>     
>     case ioError(url: URL) {
>         errorDescription = "Could not access the file 
> \(url.lastPathComponent) because an I/O error occurred."
>         failureReason = "An I/O error occurred while accessing the file 
> \(url.lastPathComponent)."
>         recoverySuggestion = "Dear Lord, the hard drive may be failing."
>         helpAnchor = "ioError"
>         url = url
>     }
>     
>     // ... etc ...
> }
> 
> I don’t think it can be denied that the second is orders of magnitude easier 
> to read and comprehend.
> 

Amen!
I implemented a client-server interface once with enum’s, and while that was 
conceptually easy to understand it became a nightmare because of exactly what 
you show in this post.
In the end it became so difficult to maintain that I ditched the entire 
implementation and went back to a class based implementation.
I realize that this is “syntactic sugar”, but it DID make the use of enums 
impossible in at least one case (anecdotal "evidence”).

Rien.

> Charles
> 
> _______________________________________________
> 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

Reply via email to