Jean-Daniel, I agree with the first part of your assessment fully, which in my opinion is actually why I think the Kotlin style combined with the Swift style would pull in the best of both worlds and create a complete solution. I do share some of your reservation in the second part of your assessment, which is why I'm a little hesitant on the proposal, but as I've described before I think it would help expressiveness.
On Sun, Nov 13, 2016 at 11:16 AM Jean-Daniel <[email protected]> wrote: > Le 13 nov. 2016 à 03:37, Dennis Lysenko via swift-evolution < > [email protected]> a écrit : > > That's a good point in Jay's example and from what I can tell a good way > to address it, Haravikk. > > I've done some work in a language that only provides type narrowing for > immutable types (that'd be Kotlin as I've mentioned before) and whenever > I've used it it feels like the only thing it's really been missing is the > "if let" construct allowing you to bind and unwrap mutable values, which > leads me to think that synergistically, in Swift, this would be fantastic. > The main benefit probably is that it would allow code to read much better. > > > IMHO, the Kotlin solution is flaw. The fact that type narrowing does not > works for var and that there is no simple way to unwrap optional just force > the developer either to introduce local variable, or to use the force > unwrap operator. > Moreover, introducing a unwrap syntax (if let) like in swift would just > result in having 2 different and inconsistent way to do the same thing. > > I think the "type stack" phrasing in the proposal is throwing some people > for a loop making them think it'll have way more mental overhead than it > actually does in practice...really, in practice, I've used this either (a) > for checking nullity or (b) for checking for a specific subclass. There's > little to no mental overhead in either of those cases, as your "type stack" > is simply 2-long (this was an Int? outside of this conditional block, and > it's an Int inside. This was a UIViewController outside of this conditional > block, and it's a UINavigationController inside.) > > While it may not be a panacea that allows new applications that no one > could have thought of, I have no doubt that it would greatly improve the > experience of coding in the language by, as you said, allowing more > flexibility in expressiveness. Regardless of one's opinion on the efficacy > of this feature as a whole, there *are* frequent situations where this > feature leads to substantially better-reading code. The "unwrap" keyword > proposed in another thread, critically, solves only *half* of the > problems that this proposal solves (as far as I could tell from reading a > few emails in the chain, it left the subclass inference completely > untouched). Ability to say "if (controller is SongSelectionViewController) > { controller.search(for: "mozart") }" is mentally freeing and helps me stay > in coder zen. > > IMO, it would effectively be the cream cheese icing on the top of the > carrot cake of Swift's unwrapping and type inference features. A good > tasteful cream cheese icing always improves a carrot cake. > > The question then becomes, is it really worth the implementation time? > This is something that, presumably, someone from the Swift team would need > to be involved in answering. > > On Fri, Nov 11, 2016 at 10:52 AM Haravikk via swift-evolution < > [email protected]> wrote: > > > On 10 Nov 2016, at 21:42, Jay Abbott <[email protected]> wrote: > > Consider this code: > > struct Pet { > let name: String > weak var owner: Person? > > init(name: String, owner: Person?) { > self.name = name > self.owner = owner > owner?.pet = self > } > > mutating func transferOwnership(to newOwner: Person) { > let previousOwner = owner > owner = newOwner > newOwner.pet = self > if(previousOwner != nil) { > previousOwner!.pet = nil > } > } > > func feed() { > } > } > class Person { > let name: String > var pet: Pet? > > init(name: String) { > self.name = name > } > > func givePetAway(to someone: Person) { > if pet != nil { > pet!.transferOwnership(to: someone) > //pet!.feed() > } > } > } > let bert = Person(name: "Bert")let ernie = Person(name: "Ernie")var elmo = > Pet(name: "Elmo", owner: nil) > > elmo.transferOwnership(to: bert)print("Bert's pet is \(bert.pet) - Ernie's > pet is \(ernie.pet)") > > bert.givePetAway(to: ernie)print("Bert's pet is \(bert.pet) - Ernie's pet is > \(ernie.pet)") > > This works as expected, but if you uncomment pet!.feed() in > givePetAway(to:) it will crash, because the mutating function modifies > the two-way relationship between pet and owner. > > In the code I use if pet != nil to demonstrate, in your proposal for > unwrap, if I used it to unwrap pet (a value-type, but accessed through > self so it can be modified after unwrapping because it’s not nil at the > moment) the compiler would assume I could use it and pet.feed() would > crash, just as pet!.feed() does now. In your proposal for type narrowing, > it would be the same problem. This is like your foo.value example from > the proposal. > > I don’t think you can get around the fact that the compiler can’t > guarantee a type-narrowed or even unwrapped mutable value, which is why if > let works as it does with an immutable snapshot. > > However, type narrowing for immutable values would still be good. > > This isn't a problem of mutability, it's a problem due to the use of a > reference type (Person); this is what the classes and concurrency section > is supposed to be describing, but perhaps I haven't made it clear enough. > So in the example you've given self.pet can't be unwrapped because self is > a reference type, thus you need to either use force unwrapping either with > the unwrap! keyword or direct force unwrapping like you've used (since > behind the scenes it's the same thing). > > You are right though that the resulting error isn't necessarily a > concurrency issue, so I'll make a note of this for the proposed new error, > and also clarify that the reference type restriction doesn't just apply to > the property itself, but also to whatever it belongs to (and so-on up the > chain, so if any part of foo.bar.a.b.c is a reference type it can't be soft > unwrapped). > _______________________________________________ > 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 > > >
_______________________________________________ swift-evolution mailing list [email protected] https://lists.swift.org/mailman/listinfo/swift-evolution
