Re: [swift-users] Intended behavior or bug in Dictionary's new subscript(_:default:)?
> On Jun 17, 2017, at 21:12, Ben Cohen via swift-users> wrote: > > In order for this defaulting subscript technique to work as intended, the > subscript { get } needs to be called, then the mutation happens, then the > subscript { set } writes the mutated value back, including adding it for the > first time it the default was needed. > > Reference types, not being value types, skip the write-back part, because > they shouldn’t need writing back – they should just get amended in place, > because they’re reference types. > > Except this particular technique is relying on it. > > This is probably worth a bug report, though I’m not sure if there’s an easy > fix. The alternative is that Dictionary.subscript(_: default:) be made a > mutating get that sets the default if not present, even without the set. > There’s downsides to this though: you would no longer be able to use this > defaulting subscript with immutable dictionaries, and getting a default value > would add it which might be very unexpected. We could say "extension Dictionary where Value: class", but that'll only fix it when the compiler knows `Value` has reference semantics (and lead to even more confusion when used in generic functions without the "T: class" part). Could we check if `Value: class` within the existing setter? Or if that's what we already do to skip the write-back, skip the skipping when one of the values is nil? - Dave Sweeris ___ swift-users mailing list swift-users@swift.org https://lists.swift.org/mailman/listinfo/swift-users
Re: [swift-users] Intended behavior or bug in Dictionary's new subscript(_:default:)?
https://bugs.swift.org/browse/SR-5250 On Sun, Jun 18, 2017 at 6:12 AM, Ben Cohenwrote: > In order for this defaulting subscript technique to work as intended, the > subscript { get } needs to be called, then the mutation happens, then the > subscript { set } writes the mutated value back, including adding it for > the first time it the default was needed. > > Reference types, not being value types, skip the write-back part, because > they shouldn’t need writing back – they should just get amended in place, > because they’re reference types. > > Except this particular technique is relying on it. > > This is probably worth a bug report, though I’m not sure if there’s an > easy fix. The alternative is that Dictionary.subscript(_: default:) be made > a mutating get that sets the default if not present, even without the set. > There’s downsides to this though: you would no longer be able to use this > defaulting subscript with immutable dictionaries, and getting a default > value would add it which might be very unexpected. > > > On Jun 16, 2017, at 1:40 PM, Jens Persson via swift-users < > swift-users@swift.org> wrote: > > > > // Swift 4, Xcode 9 beta 1, default toolchain > > > > import Foundation > > > > var d1 = [Int : String]() > > d1[1, default: .init()].append("a") > > d1[2, default: .init()].append("b") > > d1[3, default: .init()].append("c") > > d1[1, default: .init()].append("d") > > print(d1) // [2: "b", 3: "c", 1: "ad"] as expected. > > > > var d2 = [Int : NSMutableString]() > > d2[1, default: .init()].append("a") > > d2[2, default: .init()].append("b") > > d2[3, default: .init()].append("c") > > d2[1, default: .init()].append("d") > > print(d2) // [:] but why? > > > > I know that NSMutableString is a reference type and String is a value > type and that the default argument is an @autoclosure. I also know that the > newly created NSMutableString instance is just released immediately after > the append call, without being stored and retained in the Dictionary's > storage. > > > > Is this the intended behavior and if so, please let me better understand > how/why. > > > > /Jens > > > > ___ > > swift-users mailing list > > swift-users@swift.org > > https://lists.swift.org/mailman/listinfo/swift-users > > ___ swift-users mailing list swift-users@swift.org https://lists.swift.org/mailman/listinfo/swift-users
Re: [swift-users] Intended behavior or bug in Dictionary's new subscript(_:default:)?
In order for this defaulting subscript technique to work as intended, the subscript { get } needs to be called, then the mutation happens, then the subscript { set } writes the mutated value back, including adding it for the first time it the default was needed. Reference types, not being value types, skip the write-back part, because they shouldn’t need writing back – they should just get amended in place, because they’re reference types. Except this particular technique is relying on it. This is probably worth a bug report, though I’m not sure if there’s an easy fix. The alternative is that Dictionary.subscript(_: default:) be made a mutating get that sets the default if not present, even without the set. There’s downsides to this though: you would no longer be able to use this defaulting subscript with immutable dictionaries, and getting a default value would add it which might be very unexpected. > On Jun 16, 2017, at 1:40 PM, Jens Persson via swift-users >wrote: > > // Swift 4, Xcode 9 beta 1, default toolchain > > import Foundation > > var d1 = [Int : String]() > d1[1, default: .init()].append("a") > d1[2, default: .init()].append("b") > d1[3, default: .init()].append("c") > d1[1, default: .init()].append("d") > print(d1) // [2: "b", 3: "c", 1: "ad"] as expected. > > var d2 = [Int : NSMutableString]() > d2[1, default: .init()].append("a") > d2[2, default: .init()].append("b") > d2[3, default: .init()].append("c") > d2[1, default: .init()].append("d") > print(d2) // [:] but why? > > I know that NSMutableString is a reference type and String is a value type > and that the default argument is an @autoclosure. I also know that the newly > created NSMutableString instance is just released immediately after the > append call, without being stored and retained in the Dictionary's storage. > > Is this the intended behavior and if so, please let me better understand > how/why. > > /Jens > > ___ > swift-users mailing list > swift-users@swift.org > https://lists.swift.org/mailman/listinfo/swift-users ___ swift-users mailing list swift-users@swift.org https://lists.swift.org/mailman/listinfo/swift-users
[swift-users] Intended behavior or bug in Dictionary's new subscript(_:default:)?
// Swift 4, Xcode 9 beta 1, default toolchain import Foundation var d1 = [Int : String]() d1[1, default: .init()].append("a") d1[2, default: .init()].append("b") d1[3, default: .init()].append("c") d1[1, default: .init()].append("d") print(d1) // [2: "b", 3: "c", 1: "ad"] as expected. var d2 = [Int : NSMutableString]() d2[1, default: .init()].append("a") d2[2, default: .init()].append("b") d2[3, default: .init()].append("c") d2[1, default: .init()].append("d") print(d2) // [:] but why? I know that NSMutableString is a reference type and String is a value type and that the default argument is an @autoclosure. I also know that the newly created NSMutableString instance is just released immediately after the append call, without being stored and retained in the Dictionary's storage. Is this the intended behavior and if so, please let me better understand how/why. /Jens ___ swift-users mailing list swift-users@swift.org https://lists.swift.org/mailman/listinfo/swift-users