Re: [swift-users] Intended behavior or bug in Dictionary's new subscript(_:default:)?

2017-06-18 Thread David Sweeris via swift-users

> 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:)?

2017-06-18 Thread Jens Persson via swift-users
https://bugs.swift.org/browse/SR-5250

On Sun, Jun 18, 2017 at 6:12 AM, Ben Cohen  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.
>
> > 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:)?

2017-06-17 Thread Ben Cohen via swift-users
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:)?

2017-06-16 Thread Jens Persson via swift-users
// 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