Being a power user of this feature, I don’t think the existing syntax is
cumbersome enough to warrant this kind of shortcut. I really like being able to
guard case let .dict(book) = data else {
// bail out
}
guard case let .dict(author) = book["author"] ?? .null else {
// bail out
}
guard case let .integer(age) = author["age"] ?? .null else {
// bail out
}
// now we have the age
or more succinctly
guard case let .dict(book) = data,
case let .dict(author) = book["author"] ?? .null,
case let .integer(age) = author["age"] ?? .null
else {
// bail out
}
// now we have the age
Because it forces me to think about the bailout case(s) and is really not that
much longer than your proposed syntax
guard let book = case? .dict(inputData),
let author = case? .dict(book?["author”]),
let age = case? .integer(author?["age”])
else {
// bail out
}
// now we have the age
~Robert Widmann
> On Sep 26, 2016, at 11:51 AM, Jérôme Duquennoy via swift-evolution
> <[email protected]> wrote:
>
> Summary
> The aim of this proposal is to offer a new syntax to ease some uses of enums
> with payload.
>
> Situation to improve:
> Enums makes it possible to have explicate typing where it was not possible
> before. A classic example of that is filling a dictionary with data coming
> from a file or a stream (json, plist, …) : the types of possible values is
> finite : arrays, dicts, int, double, bool or string for json for exemple.
> An enum can represent this finite range of possible types, its make the code
> and the API more self-documented.
> Then, you have two possibilities to deal with this enum:
> - using switch statements
> - using the if case syntax introduced by swift 2
>
> The drawback is that those two solutions can lead to writing code with high
> visual complexity, even though the logic behind is pretty simple.
>
> Consider this example of a data dictionary, that a web service could have
> returned:
> - book
> - title:
> - author:
> - name: Apple
> - age: 40
>
> We can decode this in a variable of type [String:Value], where Value is:
>
> enum Value {
> case integer(value: Int)
> case string(value: String)
> case dict(value: [String:Value])
> case null
> }
>
> Here is a snippet of code to access the age of the author:
>
> if case .dict(let book) = data {
> if case .dict(let author) = book["author"] ?? .null {
> if case .integer(let age) = author["age"] ?? .null {
> // now we have the age
> }
> }
> }
>
> The multiple indentation levels can rapidly make this code unattractive to
> read, and we need to add a null case to the enum to deal with optional values.
>
> Proposed solution:
> I suggest to add a new syntax, using the case keyword to ease access to the
> payload of such enums :
>
> let payloadContent = case? .enumCase(variable)
>
> The payloadContent variable will be an optional, that can be either nil, or
> contain the payload of enumCase.
> If the payload contains multiple variables, payloadContent will be a tupple.
> This syntax can accommodate an optional variable as an input. If the value of
> variable is nil, then payloadContent will be nil.
> Only enum cases with a payload can be used with this syntax (it would make no
> sens for cases without a payload).
>
> With that syntax, the null case of the enum can be removed, and the code to
> access the age becomes:
>
> let book = case? .dict(inputData)
> let author = case? .dict(book?["author"])
> let age = case? .integer(author?["age"])
>
> Advantages:
> - It leverages the well established notion of optional, and similar logic
> already exists in the language (for the as? operator notably).
> - It does not add a new keyword
> - It promotes the use of enum to enforce explicit typing, which leads to more
> self-documenting code
> - It reduces the complexity of the code in situations such as the one of the
> exemple
>
> Drawbacks:
> - It adds a third use of the case keyword.
> - In the proposed syntax, the variable between parenthesis is not the
> payload, but the variable to decode. This might be disturbing, as it differs
> from the other syntax of enum values.
> - If the payload is an optional, it is not possible to differentiate a
> non-matching case and a matching case a nil payload.
>
> Alternatives:
> - Another syntax without parenthesis could be used to avoid the second
> drawback:
> let payload = case? .enumCase variable
>
> Impact on existing code:
> None, this is adding a new syntax
>
>
> This proposal would have no impact on the ABI, so it probably does not fit
> the stage 1 of swift 4’s roadmap. But I would be glad to have your feedback,
> so that I can have a proposal ready once we enter stage 2.
> So what your thoughts on that proposal ?
>
> Thanks
>
> Jerome
>
> _______________________________________________
> swift-evolution mailing list
> [email protected]
> https://lists.swift.org/mailman/listinfo/swift-evolution
_______________________________________________
swift-evolution mailing list
[email protected]
https://lists.swift.org/mailman/listinfo/swift-evolution