Re: [swift-users] Dictionary with optional values

2016-05-19 Thread Jeremy Pereira via swift-users

> On 18 May 2016, at 11:56, Artyom Goncharov via swift-users 
>  wrote:
> 
> Hi, here is the playground snippet:
> 
> var noOptDict = ["one": 1, "two": 2, "three": 3 ]
> noOptDict["one"] = nil
> noOptDict // “one” is gone
> 
> var optDict: [String: Int?] = ["one": 1, "two": 2, "three": nil]
> optDict["one"] = nil
> optDict // “one” is gone but “three” is still there
> 
> So the first dict instance works as it should, the second using opt values 
> allows to store nil but deletes the key when you assign nil. Is it bug, 
> feature, or both?
> 


It’s correct behaviour, albeit confusing.

The type of a dictionary subscript is Optional where V is the value type. If 
V is itself Optional the the type of the subscript is Optional 
(T?? for shorthand).

Normally, when you assign a value in a context where an optional is required, 
the compiler implicitly wraps the value as an optional. i.e.

let foo: Int? = 2
let bar: Int? = nil

is compiled as if you wrote 

let foo:Int? = Optional.Some(2)
let bar: Int? = Optional.None


When you have a nested optional type combined with the implicit conversion, the 
meaning of nil becomes ambiguous since it could either be the .None value of 
the outer type or a .Some value of the outer type wrapping the .None of the 
inner type.

let foo: Int?? = nil

could be

let foo: Int?? = Optional.Some(Optional.None)

or

let foo: Int?? = Optional.None

depending on where you stick the implicit wrapping. The Swift compiler chooses 
the latter.

You need to force the compiler to choose the former. The most terse way I have 
found to do this so far is

   optDict["one"] = Int?.None



> Best wishes,
> Artyom
> ___
> 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] Dictionary with optional values

2016-05-19 Thread Jens Alfke via swift-users

> On May 18, 2016, at 7:35 PM, Nathan Day  wrote:
> 
> In objective-c I have come across something like this a lot where a 
> NSDictionary has been created from JSON an a NSNull is used to represent an 
> actual null in the source JSON versus the absence of the key

Yeah, this comes from JavaScript, which weirdly has both ‘null’ and ‘undefined’ 
values; they’re kind of similar but not the same, and the latter is more like 
what we think of as null/nil in Swift or Obj-C. I think this was a bad design, 
and unfortunately it crept into JSON, which was based on JavaScript literals.

—Jens___
swift-users mailing list
swift-users@swift.org
https://lists.swift.org/mailman/listinfo/swift-users


Re: [swift-users] Dictionary with optional values

2016-05-18 Thread Nathan Day via swift-users
In objective-c I have come across something like this a lot where a 
NSDictionary has been created from JSON an a NSNull is used to represent an 
actual null in the source JSON versus the absence of the key, most of the time 
I have had to just convert the NSNull to a nil, but I did have a situation 
where I had to treat the two differently with the absence of key falling back 
to a default value but NSNull meaning explicitly null, in swift you could have 
an actual nil in the dictionary.

Sent from my iPhone

> On 19 May 2016, at 6:16 AM, Jens Alfke via swift-users 
>  wrote:
> 
> Thinking about it, I can’t see much use for a dictionary of optionals. What’s 
> the difference between “x has no value” and “x has a value of nil”? I guess 
> it’s that when you iterate the keys you see x. This seems like a tricky use 
> that could easily confuse someone reading the code (who could be you, a year 
> later!) Personally I’d prefer a different, clearer solution, unless this was 
> something performance-critical that led to faster code. In which case I’d add 
> lots of comments!
___
swift-users mailing list
swift-users@swift.org
https://lists.swift.org/mailman/listinfo/swift-users


Re: [swift-users] Dictionary with optional values

2016-05-18 Thread Jordan Rose via swift-users

> On May 18, 2016, at 09:38, Ray Fix via swift-users  
> wrote:
> 
> 
>> On May 18, 2016, at 3:56 AM, Artyom Goncharov via swift-users 
>>  wrote:
>> 
>> var noOptDict = ["one": 1, "two": 2, "three": 3 ]
>> noOptDict["one"] = nil
> 
> Wow, interesting.  To me this was surprising behavior too.
> 
> The comment for Dictionary subscript  says:
> 
>/// Access the value associated with the given key.
>///
>/// Reading a key that is not present in `self` yields `nil`.
>/// Writing `nil` as the value for a given key erases that key from
>/// `self`.
> 
> Which is exactly what it is doing.  As the Zhaoxin said, you can use 
> updateValue (and removeValueForKey) to get better results when dealing with 
> optional dictionary values.

There’s a bit more discussion of this on the Apple Swift blog: 
https://developer.apple.com/swift/blog/?id=12 


Jordan

___
swift-users mailing list
swift-users@swift.org
https://lists.swift.org/mailman/listinfo/swift-users


Re: [swift-users] Dictionary with optional values

2016-05-18 Thread Marco S Hyman via swift-users

> On May 18, 2016, at 11:03 AM, Artyom Goncharov via swift-users 
>  wrote:
> 
> Yes, of course I can use API method but this kind of behaviour for subscript 
> operator seems inconsistent(or even magical) to me because it is possible to 
> initialise a dictionary with nil without casting it. Though nil is a special 
> case it is still a value in the set of all values of a T? type, am I wrong?

There are a few ways to assign nil to a dictionary entry.  First of all

dictionary[“key”] = nil

always removes “key" from dictionary.  To assign a nil value use one of:

dictionary[“key”] = Optional(nil)
dictionary[“key”] = .Some(nil)
dictionary[“key”]? = nil

That last only works if “key” already exists in the dictionary, i.e. you are 
replacing the existing value.  The first two will add a dictionary entry if 
necessary.

I suspect now that you’ve been bitten by this you will remember it forever :)

Marc
___
swift-users mailing list
swift-users@swift.org
https://lists.swift.org/mailman/listinfo/swift-users


Re: [swift-users] Dictionary with optional values

2016-05-18 Thread Jens Alfke via swift-users

> On May 18, 2016, at 11:03 AM, Artyom Goncharov via swift-users 
>  wrote:
> 
> Yes, of course I can use API method but this kind of behaviour for subscript 
> operator seems inconsistent(or even magical) to me because it is possible to 
> initialise a dictionary with nil without casting it. Though nil is a special 
> case it is still a value in the set of all values of a T? type, am I wrong?

It’s an unfortunate ambiguity, one that comes up in any dictionary API that 
potentially allows nil to be stored as a value. Does a RHS of nil mean to 
remove the key/value pair, or to store a nil as the value?

In particular, the C++ STL goes through horrible contortions to get around 
this, which is part of what makes it so awful and verbose to use. :-P

The intuitive (and most commonly useful) interpretation of “dict[x] = nil” is 
to remove the key, which is what Swift does. If you’ve created a dictionary of 
optionals and need to store a null, you have to add a bit of verbosity to make 
your intention clear. I think that’s fine: it goes along with Alan Kay’s maxim 
that “simple things should be simple, and complex things should be doable.”

(Thinking about it, I can’t see much use for a dictionary of optionals. What’s 
the difference between “x has no value” and “x has a value of nil”? I guess 
it’s that when you iterate the keys you see x. This seems like a tricky use 
that could easily confuse someone reading the code (who could be you, a year 
later!) Personally I’d prefer a different, clearer solution, unless this was 
something performance-critical that led to faster code. In which case I’d add 
lots of comments!)

—Jens
___
swift-users mailing list
swift-users@swift.org
https://lists.swift.org/mailman/listinfo/swift-users


[swift-users] Dictionary with optional values

2016-05-18 Thread Artyom Goncharov via swift-users
Yes, of course I can use API method but this kind of behaviour for subscript 
operator seems inconsistent(or even magical) to me because it is possible to 
initialise a dictionary with nil without casting it. Though nil is a special 
case it is still a value in the set of all values of a T? type, am I wrong?

> On 18 May 2016, at 18:38, Ray Fix via swift-users <swift-users@swift.org> 
> wrote:
> 
> 
>> On May 18, 2016, at 3:56 AM, Artyom Goncharov via swift-users 
>> <swift-users@swift.org> wrote:
>> 
>> var noOptDict = ["one": 1, "two": 2, "three": 3 ]
>> noOptDict["one"] = nil
> 
> Wow, interesting.  To me this was surprising behavior too.
> 
> The comment for Dictionary subscript  says:
> 
>   /// Access the value associated with the given key.
>   ///
>   /// Reading a key that is not present in `self` yields `nil`.
>   /// Writing `nil` as the value for a given key erases that key from
>   /// `self`.
> 
> Which is exactly what it is doing.  As the Zhaoxin said, you can use 
> updateValue (and removeValueForKey) to get better results when dealing with 
> optional dictionary values.
> 
> Ray
> 
> ___
> 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] Dictionary with optional values

2016-05-18 Thread David Sweeris via swift-users
I'm not in front of Xcode, so I can't confirm this, but I suspect that 
`optDict["one"] = nil as! Int?` will set "one" to nil, rather than removing 
"one".

Whatever the rules for inferring the type of `nil` when an 
Optional is involved are, it seems like it always 
infers the one I don't want.

Hope that helps.

- Dave Sweeris

> On May 18, 2016, at 05:56, Artyom Goncharov via swift-users 
>  wrote:
> 
> Hi, here is the playground snippet:
> 
> var noOptDict = ["one": 1, "two": 2, "three": 3 ]
> noOptDict["one"] = nil
> noOptDict // “one” is gone
> 
> var optDict: [String: Int?] = ["one": 1, "two": 2, "three": nil]
> optDict["one"] = nil
> optDict // “one” is gone but “three” is still there
> 
> So the first dict instance works as it should, the second using opt values 
> allows to store nil but deletes the key when you assign nil. Is it bug, 
> feature, or both?
> 
> Best wishes,
> Artyom
> ___
> 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] Dictionary with optional values

2016-05-18 Thread Artyom Goncharov via swift-users
Hi, here is the playground snippet:

var noOptDict = ["one": 1, "two": 2, "three": 3 ]
noOptDict["one"] = nil
noOptDict // “one” is gone

var optDict: [String: Int?] = ["one": 1, "two": 2, "three": nil]
optDict["one"] = nil
optDict // “one” is gone but “three” is still there

So the first dict instance works as it should, the second using opt values 
allows to store nil but deletes the key when you assign nil. Is it bug, 
feature, or both?

Best wishes,
Artyom
___
swift-users mailing list
swift-users@swift.org
https://lists.swift.org/mailman/listinfo/swift-users