Re: [swift-evolution] Evaluating the case of an enum with associated values as a bool
> On Dec 21, 2017, at 10:59 AM, Dave Abrahams <dabrah...@apple.com> wrote: > > > >> On Dec 21, 2017, at 10:19 AM, Ethan Diamond <ethanjdiam...@gmail.com >> <mailto:ethanjdiam...@gmail.com>> wrote: >> >> Just to clarify, Dave - >> >> What happens there if one case has associated values > >> and one has an associated value thats an optional? >> >> Enum A { >>case x(String?) >>case y >> } >> >> let a = A.x(nil) > > A.x is String?? This was assigning .x to a, not evaluating a synthesized value > >> a.y // What's the result? > > nil as Optional > >> a.x // Would produce a double optional, which are clumsy to nil check > > They’re a fact of life. If that’s a problem, we should consider fixing it, > but it’s orthogonal to this one. > >> >> I'm not a fan of solving this via synthesis in general. We have metatypes >> for classes/structs/protocols, which are useful in all sorts of situations. >> Cases are essentially "types" of enums. Why not have case metatypes? They're >> useful for the same reasons class types are, and there's already precedence >> in the language for syntax. > > You mean “precedent?” OK, but I don’t see how it helps with any of the same > problems as synthesized properties for cases do. > I’m not really sure what the problems synthesized properties are trying to solve are. Chris brought them up as a possible solution to my pain point, which they only solve partially. Checking for a case I don’t know up front (for example, comparing the cases of two values) still isn’t covered. >> >> >> >> On Thu, Dec 21, 2017 at 7:14 AM Dave Abrahams <dabrah...@apple.com >> <mailto:dabrah...@apple.com>> wrote: >> IIRC what we discussed was synthesizing members of type Optional >> which could then be checked against nil. >> >> if _ = x.failure { ... } >> if x.failure != nil { ... } >> if let r = x.success {...} >> >> IMO synthesizing predicates would be a huge missed opportunity by comparison >> >> Sent from my iPhone >> >> On Dec 20, 2017, at 1:31 PM, Chris Lattner via swift-evolution >> <swift-evolution@swift.org <mailto:swift-evolution@swift.org>> wrote: >> >>> In the past, we’ve discussed synthesizing predicate members onto enums. >>> E.g. given: >>> >>> enum E { >>> case X >>> case Y(Int) >>> } >>> >>> you’d get something like: >>> >>> extension E { >>> func isX() -> Bool { return self == .X } >>> func getY() -> Int? { … } >>> } >>> >>> which would solve the client side of this nicely. >>> >>> -Chris >>> >>> >>> >>>> On Dec 20, 2017, at 11:24 AM, Ethan Diamond via swift-evolution >>>> <swift-evolution@swift.org <mailto:swift-evolution@swift.org>> wrote: >>>> >>>> Sorry all for attaching the original post to the Non-Exhaustive enums >>>> thread. I"m moving it down to it's own thread. >>>> >>>> My understanding is I'm not allowed to write up a proposal unless I have >>>> the time to implement it. Is that still true? This is a major pain point >>>> for me to avoid having to write things like this: >>>> >>>> if case .search = presenter.state { return true } else { return false } >>>> >>>> Side note: Thanks Kevin, didn't know you could nest enums in switches like >>>> that. Super helpful! >>>> >>>> -- >>>> I thought I would add another case that isn’t possible with current syntax >>>> (so far as I’m aware). You can’t negate the comparison to do something >>>> for all cases except a particular case. You have to have an empty if >>>> block and use the else block, or have an empty case in a switch statement >>>> and use the default. >>>> >>>> enum Enum { >>>> case a(param: String) >>>> case b(param: String) >>>> case c(param: String) >>>> } >>>> >>>> let enumeration: Enum = .a(param: "Hi") >>>> >>>> if !(case .a = enumeration) { >>>> // Do something >>>> } >>>> >>>> — Charles >>>> >>>> > On Dec 20, 2017, at 9:55 AM, Kevin Nattinger via swift-evolution
Re: [swift-evolution] Evaluating the case of an enum with associated values as a bool
Is there a reason the team wants to do synthesis instead of other options? If that’s no longer assignment, it’s going to break a lot of code. Sent from my iPhone > On Dec 23, 2017, at 1:19 PM, Dave Abrahams <dabrah...@apple.com> wrote: > > > > Sent from my iPhone > >> On Dec 21, 2017, at 2:33 PM, Ethan Diamond <ethan.j.diam...@gmail.com> wrote: >> >> >>> On Dec 21, 2017, at 10:59 AM, Dave Abrahams <dabrah...@apple.com> wrote: >>> >>> >>> >>>> On Dec 21, 2017, at 10:19 AM, Ethan Diamond <ethanjdiam...@gmail.com> >>>> wrote: >>>> >>>> Just to clarify, Dave - >>>> >>>> What happens there if one case has associated values >>> >>>> and one has an associated value thats an optional? >>>> >>>> Enum A { >>>>case x(String?) >>>>case y >>>> } >>>> >>>> let a = A.x(nil) >>> >>> A.x is String?? >> >> This was assigning .x to a, not evaluating a synthesized value > > And I was making an assertion, not asking a question >> >>> >>>> a.y // What's the result? >>> >>> nil as Optional >>> >>>> a.x // Would produce a double optional, which are clumsy to nil check >>> >>> They’re a fact of life. If that’s a problem, we should consider fixing it, >>> but it’s orthogonal to this one. >>> >>>> >>>> I'm not a fan of solving this via synthesis in general. We have metatypes >>>> for classes/structs/protocols, which are useful in all sorts of >>>> situations. Cases are essentially "types" of enums. Why not have case >>>> metatypes? They're useful for the same reasons class types are, and >>>> there's already precedence in the language for syntax. >>> >>> You mean “precedent?” OK, but I don’t see how it helps with any of the >>> same problems as synthesized properties for cases do. >>> >> >> I’m not really sure what the problems synthesized properties are trying to >> solve are. Chris brought them up as a possible solution to my pain point, >> which they only solve partially. Checking for a case I don’t know up front >> (for example, comparing the cases of two values) still isn’t covered. >> >>>> >>>> >>>> >>>>> On Thu, Dec 21, 2017 at 7:14 AM Dave Abrahams <dabrah...@apple.com> wrote: >>>>> IIRC what we discussed was synthesizing members of type >>>>> Optional which could then be checked against nil. >>>>> >>>>> if _ = x.failure { ... } >>>>> if x.failure != nil { ... } >>>>> if let r = x.success {...} >>>>> >>>>> IMO synthesizing predicates would be a huge missed opportunity by >>>>> comparison >>>>> >>>>> Sent from my iPhone >>>>> >>>>>> On Dec 20, 2017, at 1:31 PM, Chris Lattner via swift-evolution >>>>>> <swift-evolution@swift.org> wrote: >>>>>> >>>>>> In the past, we’ve discussed synthesizing predicate members onto enums. >>>>>> E.g. given: >>>>>> >>>>>> enum E { >>>>>> case X >>>>>> case Y(Int) >>>>>> } >>>>>> >>>>>> you’d get something like: >>>>>> >>>>>> extension E { >>>>>> func isX() -> Bool { return self == .X } >>>>>> func getY() -> Int? { … } >>>>>> } >>>>>> >>>>>> which would solve the client side of this nicely. >>>>>> >>>>>> -Chris >>>>>> >>>>>> >>>>>> >>>>>>> On Dec 20, 2017, at 11:24 AM, Ethan Diamond via swift-evolution >>>>>>> <swift-evolution@swift.org> wrote: >>>>>>> >>>>>>> Sorry all for attaching the original post to the Non-Exhaustive enums >>>>>>> thread. I"m moving it down to it's own thread. >>>>>>> >>>>>>> My understanding is I'm not allowed to write up a proposal unless I >>>>>>> have the time to implement it. Is that still true? This is a major pain >>>>>>> point for me to avoid having to
Re: [swift-evolution] Evaluating the case of an enum with associated values as a bool
Just to clarify, Dave - What happens there if one case has associated values and one has an associated value thats an optional? Enum A { case x(String?) case y } let a = A.x(nil) a.y // What's the result? a.x // Would produce a double optional, which are clumsy to nil check I'm not a fan of solving this via synthesis in general. We have metatypes for classes/structs/protocols, which are useful in all sorts of situations. Cases are essentially "types" of enums. Why not have case metatypes? They're useful for the same reasons class types are, and there's already precedence in the language for syntax. On Thu, Dec 21, 2017 at 7:14 AM Dave Abrahams <dabrah...@apple.com> wrote: > IIRC what we discussed was synthesizing members of type Optional > which could then be checked against nil. > > if _ = x.failure { ... } > if x.failure != nil { ... } > if let r = x.success {...} > > IMO synthesizing predicates would be a huge missed opportunity by > comparison > > Sent from my iPhone > > On Dec 20, 2017, at 1:31 PM, Chris Lattner via swift-evolution < > swift-evolution@swift.org> wrote: > > In the past, we’ve discussed synthesizing predicate members onto enums. > E.g. given: > > enum E { > case X > case Y(Int) > } > > you’d get something like: > > extension E { > func isX() -> Bool { return self == .X } > func getY() -> Int? { … } > } > > which would solve the client side of this nicely. > > -Chris > > > > On Dec 20, 2017, at 11:24 AM, Ethan Diamond via swift-evolution < > swift-evolution@swift.org> wrote: > > Sorry all for attaching the original post to the Non-Exhaustive enums > thread. I"m moving it down to it's own thread. > > My understanding is I'm not allowed to write up a proposal unless I have > the time to implement it. Is that still true? This is a major pain point > for me to avoid having to write things like this: > > if case .search = presenter.state { return true } else { return false } > Side note: Thanks Kevin, didn't know you could nest enums in switches like > that. Super helpful! > > -- > > I thought I would add another case that isn’t possible with current syntax > (so far as I’m aware). You can’t negate the comparison to do something for > all cases except a particular case. You have to have an empty if block and > use the else block, or have an empty case in a switch statement and use the > default. > > enum Enum { > case a(param: String) > case b(param: String) > case c(param: String) > } > > let enumeration: Enum = .a(param: "Hi") > > if !(case .a = enumeration) { > // Do something > } > > — Charles > > >* On Dec 20, 2017, at 9:55 AM, Kevin Nattinger via swift-evolution > > ><https://lists.swift.org/mailman/listinfo/swift-evolution>> wrote: > *> >* I agree this would be useful. At the moment I have to hack around it > with things like `var isFoo: Bool { if case .foo = self …`* with cases I > commonly need, but this is definitely a feature that has come up before and I > support. It is potentially related to getting the values through an accessor, > which has also come up several times. > *> >* Sidenote, your `switch` example is actually trivial with existing > syntax: > *> >* switch enumeration { > *>* case .a(.c(let param)): // or just .a(.c) if you don't need the value > *>* print(param) > *>* default: > *>* break > *>* } > *> >* I use this from time to time switching over, e.g., optional enums. > *> >* *: ugliest syntax ever, and it can't even be used as a standalone > expression. > *> > >>* On Dec 20, 2017, at 8:44 AM, Ethan Diamond via swift-evolution > <https://lists.swift.org/mailman/listinfo/swift-evolution> > <mailto:swift-evolution at swift.org > <https://lists.swift.org/mailman/listinfo/swift-evolution>>> wrote: > *>> >>* Hello everyone, > *>> >>* One major pain point I've run into with Swift is the inability to > evaluate the case of an enum that has associated values in a way that just > returns a bool. We've been given the ability in a switch statement: > *>> >>* enum Enum { > *>>*case a(param: String) > *>>*case b(param: String) > *>>* } > *>> >>* let enumeration: Enum = a(param: "Hi") > *>>* switch enumeration { > *>>* case a: > *>>* // Do something > *>>* case b: > *>>* // Do something > *>>* } > *>> >>* We'e been given the ability in the context of an
Re: [swift-evolution] Evaluating the case of an enum with associated values as a bool
It feels like it solves my current problem in a way that's almost as undesirable as the current solution. Say I have: Enum A { case x(String?) case y(String) } Right now I have code like this peppered throughout my code, which I think we can agree is pretty undesirable: if let case .x = value { return true } else { return false } I actually think that new syntax would be worse. It's not obvious what this does: if let string = value.getX() { return string != nil } else { return false } Even aside from readability, it strikes me as very weird that we have clean syntax for cases that ignore associated values inside of switch, if and guard statements, but outside of them we need to always write code around the associated value even when the associated values don't matter to what we're trying to do. I'm not going to pretend it's something I hit every day, but it's something I do *fairly* often, and it always feels like I'm fighting the language to do it. Having an isX() would be a big improvement, and I think we'd happily take it. That being said, any of these are the code I would ideally want to write: let a: A = .x("String") a.matches(.x) // true a.matches(.x(_)) // true a.matches(.x("Taco") // false or case(of: a) == .x // true (my personal favorite) or case a == .x // true On Wed, Dec 20, 2017 at 3:11 PM Chris Lattner <clatt...@nondot.org> wrote: > On Dec 20, 2017, at 2:12 PM, Ethan Diamond <ethanjdiam...@gmail.com> > wrote: > > Would that synthesize an isY() even though .Y has an associated value > there? > > > I’m not aware of a concrete design for this idea. The details would > definitely need to be figured out, but I don’t see why a double optional is > itself a problem. > > -Chris > > > enum E { > case X > case Y(Int?) > } > > If I had to run that through getY() -> Int??, it still wouldn't be quite > what I was looking for with regards to intent. If you are planning an doing > an isY though, that would work for most cases where you're evaluating for a > given enum and know what it is beforehand. Even so that wouldn't work for a > case, for example, where I'm trying to see if two enums are the same case, > and don't necessarily care if they're equal. > > let value1 = E.Y(1) > let value2 = E.Y(2) > > value1 == value2 // false > value1 [is the same case as] value 2 // how do I get this? > > This would be useful, say, if I was trying to generate a diff of two > arrays of enums, which I occasionally do for table / collection views to > figure out inserts/removals/updates. > > I don't necessarily know if it's feasible, but it would be really great to > have something like a Case metatype, the same way we have type(of: ). It > would be great to have a case(of: ) that we can evaluate against the > shorthand like we do in switch statements. > > Ex: > > case(of: value1) == .Y // true > case(of: value1) == .X // false > case(of: value1) == case(of: value2) // true > > > > On Wed, Dec 20, 2017 at 1:31 PM Chris Lattner <clatt...@nondot.org> wrote: > >> In the past, we’ve discussed synthesizing predicate members onto enums. >> E.g. given: >> >> enum E { >> case X >> case Y(Int) >> } >> >> you’d get something like: >> >> extension E { >> func isX() -> Bool { return self == .X } >> func getY() -> Int? { … } >> } >> >> which would solve the client side of this nicely. >> >> -Chris >> >> >> >> On Dec 20, 2017, at 11:24 AM, Ethan Diamond via swift-evolution < >> swift-evolution@swift.org> wrote: >> >> Sorry all for attaching the original post to the Non-Exhaustive enums >> thread. I"m moving it down to it's own thread. >> >> My understanding is I'm not allowed to write up a proposal unless I have >> the time to implement it. Is that still true? This is a major pain point >> for me to avoid having to write things like this: >> >> if case .search = presenter.state { return true } else { return false } >> Side note: Thanks Kevin, didn't know you could nest enums in switches >> like that. Super helpful! >> >> -- >> >> I thought I would add another case that isn’t possible with current syntax >> (so far as I’m aware). You can’t negate the comparison to do something for >> all cases except a particular case. You have to have an empty if block and >> use the else block, or have an empty case in a switch statement and use the >> default. >> >> enum Enum { >> case a(param: String) >> case b(param: String) >> case c(param: String) >&
Re: [swift-evolution] Evaluating the case of an enum with associated values as a bool
Would that synthesize an isY() even though .Y has an associated value there? enum E { case X case Y(Int?) } If I had to run that through getY() -> Int??, it still wouldn't be quite what I was looking for with regards to intent. If you are planning an doing an isY though, that would work for most cases where you're evaluating for a given enum and know what it is beforehand. Even so that wouldn't work for a case, for example, where I'm trying to see if two enums are the same case, and don't necessarily care if they're equal. let value1 = E.Y(1) let value2 = E.Y(2) value1 == value2 // false value1 [is the same case as] value 2 // how do I get this? This would be useful, say, if I was trying to generate a diff of two arrays of enums, which I occasionally do for table / collection views to figure out inserts/removals/updates. I don't necessarily know if it's feasible, but it would be really great to have something like a Case metatype, the same way we have type(of: ). It would be great to have a case(of: ) that we can evaluate against the shorthand like we do in switch statements. Ex: case(of: value1) == .Y // true case(of: value1) == .X // false case(of: value1) == case(of: value2) // true On Wed, Dec 20, 2017 at 1:31 PM Chris Lattner <clatt...@nondot.org> wrote: > In the past, we’ve discussed synthesizing predicate members onto enums. > E.g. given: > > enum E { > case X > case Y(Int) > } > > you’d get something like: > > extension E { > func isX() -> Bool { return self == .X } > func getY() -> Int? { … } > } > > which would solve the client side of this nicely. > > -Chris > > > > On Dec 20, 2017, at 11:24 AM, Ethan Diamond via swift-evolution < > swift-evolution@swift.org> wrote: > > Sorry all for attaching the original post to the Non-Exhaustive enums > thread. I"m moving it down to it's own thread. > > My understanding is I'm not allowed to write up a proposal unless I have > the time to implement it. Is that still true? This is a major pain point > for me to avoid having to write things like this: > > if case .search = presenter.state { return true } else { return false } > Side note: Thanks Kevin, didn't know you could nest enums in switches like > that. Super helpful! > > -- > > I thought I would add another case that isn’t possible with current syntax > (so far as I’m aware). You can’t negate the comparison to do something for > all cases except a particular case. You have to have an empty if block and > use the else block, or have an empty case in a switch statement and use the > default. > > enum Enum { > case a(param: String) > case b(param: String) > case c(param: String) > } > > let enumeration: Enum = .a(param: "Hi") > > if !(case .a = enumeration) { > // Do something > } > > — Charles > > >* On Dec 20, 2017, at 9:55 AM, Kevin Nattinger via swift-evolution > > ><https://lists.swift.org/mailman/listinfo/swift-evolution>> wrote: > *> >* I agree this would be useful. At the moment I have to hack around it > with things like `var isFoo: Bool { if case .foo = self …`* with cases I > commonly need, but this is definitely a feature that has come up before and I > support. It is potentially related to getting the values through an accessor, > which has also come up several times. > *> >* Sidenote, your `switch` example is actually trivial with existing > syntax: > *> >* switch enumeration { > *>* case .a(.c(let param)): // or just .a(.c) if you don't need the value > *>* print(param) > *>* default: > *>* break > *>* } > *> >* I use this from time to time switching over, e.g., optional enums. > *> >* *: ugliest syntax ever, and it can't even be used as a standalone > expression. > *> > >>* On Dec 20, 2017, at 8:44 AM, Ethan Diamond via swift-evolution > <https://lists.swift.org/mailman/listinfo/swift-evolution> > <mailto:swift-evolution at swift.org > <https://lists.swift.org/mailman/listinfo/swift-evolution>>> wrote: > *>> >>* Hello everyone, > *>> >>* One major pain point I've run into with Swift is the inability to > evaluate the case of an enum that has associated values in a way that just > returns a bool. We've been given the ability in a switch statement: > *>> >>* enum Enum { > *>>*case a(param: String) > *>>*case b(param: String) > *>>* } > *>> >>* let enumeration: Enum = a(param: "Hi") > *>>* switch enumeration { > *>>* case a: > *>>* // Do something > *>>*
[swift-evolution] Evaluating the case of an enum with associated values as a bool
Sorry all for attaching the original post to the Non-Exhaustive enums thread. I"m moving it down to it's own thread. My understanding is I'm not allowed to write up a proposal unless I have the time to implement it. Is that still true? This is a major pain point for me to avoid having to write things like this: if case .search = presenter.state { return true } else { return false } Side note: Thanks Kevin, didn't know you could nest enums in switches like that. Super helpful! -- I thought I would add another case that isn’t possible with current syntax (so far as I’m aware). You can’t negate the comparison to do something for all cases except a particular case. You have to have an empty if block and use the else block, or have an empty case in a switch statement and use the default. enum Enum { case a(param: String) case b(param: String) case c(param: String) } let enumeration: Enum = .a(param: "Hi") if !(case .a = enumeration) { // Do something } — Charles >* On Dec 20, 2017, at 9:55 AM, Kevin Nattinger via swift-evolution ><https://lists.swift.org/mailman/listinfo/swift-evolution>> wrote: *> >* I agree this would be useful. At the moment I have to hack around it with things like `var isFoo: Bool { if case .foo = self …`* with cases I commonly need, but this is definitely a feature that has come up before and I support. It is potentially related to getting the values through an accessor, which has also come up several times. *> >* Sidenote, your `switch` example is actually trivial with existing syntax: *> >* switch enumeration { *>* case .a(.c(let param)): // or just .a(.c) if you don't need the value *>* print(param) *>* default: *>* break *>* } *> >* I use this from time to time switching over, e.g., optional enums. *> >* *: ugliest syntax ever, and it can't even be used as a standalone expression. *> > >>* On Dec 20, 2017, at 8:44 AM, Ethan Diamond via swift-evolution https://lists.swift.org/mailman/listinfo/swift-evolution> <mailto:swift-evolution at swift.org <https://lists.swift.org/mailman/listinfo/swift-evolution>>> wrote: *>> >>* Hello everyone, *>> >>* One major pain point I've run into with Swift is the inability to evaluate the case of an enum that has associated values in a way that just returns a bool. We've been given the ability in a switch statement: *>> >>* enum Enum { *>>*case a(param: String) *>>*case b(param: String) *>>* } *>> >>* let enumeration: Enum = a(param: "Hi") *>>* switch enumeration { *>>* case a: *>>* // Do something *>>* case b: *>>* // Do something *>>* } *>> >>* We'e been given the ability in the context of an if statement: *>> >>* enum Enum { *>>*case a(param: String) *>>*case b(param: String) *>>* } *>> >>* let enumeration: Enum = a(param: "Hi") *>> >>* if case .a = enumeration { *>>* // Do something *>>* } *>> >>* But without a basic was of getting a bool for if an enum is a given case, here's a list of things I can't do: *>> >>* Where statements: *>> >>* enum Enum { *>>*case a(param: Enum2) *>>*case b(param: Enum2) *>>* } *>> >>* enum Enum2 { *>>* case c(param: String) *>>* case d(param: String) *>>* } *>> >>* let enumeration: Enum = a(param: "Hi") *>>* switch enumeration { *>>* case a(let inner) where [INNER CASE IS .c] *>>* } *>> >>* - *>> >>* Filter an array for a certain case: *>> >>* Expertly explained by Erica Sadun here: http://ericasadun.com/2017/01/31/challenge-filtering-associated-value-enumeration-arrays/ <http://ericasadun.com/2017/01/31/challenge-filtering-associated-value-enumeration-arrays/> <http://ericasadun.com/2017/01/31/challenge-filtering-associated-value-enumeration-arrays/ <http://ericasadun.com/2017/01/31/challenge-filtering-associated-value-enumeration-arrays/>> *>> >>* - *>> >>* Nicely set a UIButton to hidden if an enum is a certain case: *>> >>* enum State { *>>* case `default` *>>* case searching(results: [Result]) *>>* } *>> >>* myButton.isHidden = [STATE IS .searching] *>> >>* - *>> >>* I've run into this issue a ton of times because I tend to represent my views a State enums. I haven't seen anything on the board for plans for solving this issue, thought. Has there been any discussion about addressing it? Ideally I'd be able to do this: *>> >>* enum Enum { *>>*case a(param: Str
[swift-evolution] Evaluating the case of an enum with associated values as a bool
Hello everyone, One major pain point I've run into with Swift is the inability to evaluate the case of an enum that has associated values in a way that just returns a bool. We've been given the ability in a switch statement: enum Enum { case a(param: String) case b(param: String) } let enumeration: Enum = a(param: "Hi") switch enumeration { case a: // Do something case b: // Do something } We'e been given the ability in the context of an if statement: enum Enum { case a(param: String) case b(param: String) } let enumeration: Enum = a(param: "Hi") if case .a = enumeration { // Do something } But without a basic was of getting a bool for if an enum is a given case, here's a list of things I can't do: *Where statements:* enum Enum { case a(param: Enum2) case b(param: Enum2) } enum Enum2 { case c(param: String) case d(param: String) } let enumeration: Enum = a(param: "Hi") switch enumeration { case a(let inner) where [INNER CASE IS .c] } - *Filter an array for a certain case:* Expertly explained by Erica Sadun here: http://ericasadun.com/2017/01/31/challenge-filtering-associated-value-enumeration-arrays/ - *Nicely set a UIButton to hidden if an enum is a certain case:* enum State { case `default` case searching(results: [Result]) } myButton.isHidden = [STATE IS .searching] - I've run into this issue a ton of times because I tend to represent my views a State enums. I haven't seen anything on the board for plans for solving this issue, thought. Has there been any discussion about addressing it? Ideally I'd be able to do this: enum Enum { case a(param: String) case b(param: String) } let enumeration: Enum = a(param: "Hi") case .a = enumeration // Bool case .a(let param) = enumeration // Bool, assigns "Hi" to "param" Thanks! Ethan ___ swift-evolution mailing list swift-evolution@swift.org https://lists.swift.org/mailman/listinfo/swift-evolution
[swift-evolution] Closure Syntax
I realize this is on the commonly rejected list, but I really find closure syntax to be one of the more unintuitive and unreadable parts of Swift so I'd like to try to influence it. "Clarity at the point of use" is one of the main stated goals of Swift, and the fact that http://goshdarnclosuresyntax.com/ exists shows me that it's not just me that thinks the syntax could be improved. I believe that we can get very close to the same results in line length and expressiveness while making the language much more readable and clear. Let's start with a few use cases to illustrate what I mean when I say that reading closure syntax is difficult. Most programmers scan left to right, so when I see this property declaration: var thing: Int My brain reads that as a property of a class that's an integer. Unless of course there's this: var thing: Int -> Int Boom, context switch. If you've read "Int" than any following syntax should be a modifier on Int. For example, Int? works great, because in my head it's still an Integer, just an optional form of that Integer. While it's not a huge change in that example, lets take a more complicated one: var thing: (String -> (), Int, (Int, Int) -> Bool)) -> Bool Reading that left to right requires all sorts of context switching in my brain. I can't even tell at first glance how many params are in that closure. Reading left to right, you read "First parameter, string, no wait, closure that takes string, and returns void. Second param, Int. Third param, tuple with two ints, no wait, closure that takes two ints and returns bool." I just doesn't have much clarity. I believe it's already been proposed, but I don't feel there's a strong enough difference between a closure and a function to justify a different syntax. Let's replace my examples above with anonymous function syntax. var thing: func (Int) -> Int Reading left to right, it reads the way that I think about it "A function that takes an integer and returns an integer." var thing: func(func (String), Int, func (Int, Int) -> Bool) -> Bool Again, reading left to right this is a win. "Thing is an anonymous function. First param, a function that takes a string. Second param, Int. Third param, a function that takes two ints and returns bool." It reads like people think. Another strength is it lets us both use the same syntax for closures as we would expect, while letting us use just about all of the same shorthands we gain with closures. We could call normally like this, with the return type implied when async is called: func async(callback: func (Bool) -> Bool)) async(func (successful: Bool) { return !successful }); We could still permit this: func async(callback: func ()) async { //Do callback stuff here } We could still permit this: func sort(sortfunc: func(Int, Int) -> Bool) sort { $0 > $1 } We could add this: let greaterThan: func (number: Int) -> Bool = { number > 5 } There would also be a few small wins, such as no longer needing "()" to represent a void return, since any function without a return type would imply a void return. I understand that a big part of the decision for current closure syntax is to help the compiler, but I believe by doing so you're going against the main principles you laid out in your api design guidelines ( https://swift.org/documentation/api-design-guidelines.html). Current closure syntax is not clear and breaks precedent of all other function like declarations having the parameters listed outside of the curly braces. Thanks for listening, and great job on Swift so far. ___ swift-evolution mailing list swift-evolution@swift.org https://lists.swift.org/mailman/listinfo/swift-evolution