Re: Instantiate NSString from NSURL in Swift

2015-02-26 Thread Charles Srstka
On Feb 23, 2015, at 1:52 PM, Fritz Anderson  wrote:
> 
> On 23 Feb 2015, at 8:18 AM, Juanjo Conti  > wrote:
>> 
>> I'm translating some code from Objective-C to Swift and in the middle of
>> that, i found this problem.
>> 
>> theUrl is an instance of NSURL
>> 
>> theUrl.host?.lowercaseString
>> 
>> compiles ok.
>> 
>> But
>> 
>> NSString(string: theUrl.host?.lowercaseString)
>> don't. It says "Value of optional type 'String?' no unwrapped; did you mean
>> to use '!' or '?'?
>> 
>> If I click to add the fix, then it complains again and suggest to delete
>> the '!' :)
> 
> This is written in haste, and few people are experts…
> 
>theURL.host  may yield nil (host is declared String!, implicitly 
> unwrapped, but optional).
> 
>theURL.host?.lowercaseString  will short-circuit and be evaluated as nil 
> if .host is nil.
> 
>anyString.lowercaseString   may also yield nil; the var is declared 
> String!.
> 
>anyString.lowercaseString!   attempts to unwrap a String that the compiler 
> has implicitly unwrapped already.
> 
> Therefore, because of the short-circuit “?”, the expression 
> theUrl.host?.lowercaseString is of type String?, which may be .None (nil), or 
> .Some(String) (and therefore have to be unwrapped).
> 
> You are passing that optional String as the argument for String(string: {that 
> optional expression}). The argument may be nil; or it may need unwrapping. 
> The initializer _requires_ a non-nil argument. It’s a righteous error.
> 
> The expression
> 
>   NSString(string: foo!)
> 
> is different; by adding the bang you’ve taken responsibility for the 
> parameter’s not being nil.
> 
> Because .lowercaseString returns an implicitly-unwrapped String (String!),
> 
>theURL?.host?.lowercaseString!
> 
> tries to unwrap something that is already, syntactically, an unwrapped String.
> 
> Quincey — my instinct is that the conditional-unwrap chain necessarily forces 
> left-to-right evaluation, tighter than the . operator. The ! would mean, “if 
> you got this far without short-circuiting, and b returns an optional, then 
> unwrap it.” 
> 
> As of today’s Swift 1.2b2, the following in a playground:
> 
>let aURL = NSURL(string: "http://wt9t.com/ ")!
>NSString(string: aURL.host?.lowercaseString)
> 
> complains as you suggest: .host? is potentially nil — that would force the 
> whole expression to be nil, and thus forbidden as a parameter. 
> lowercaseString still gets treated as implicitly unwrapped — so a bang at the 
> end of the whole expression is an attempt to unwrap something the compiler 
> was going to unwrap anyway.

It’s sure great that we have Swift these days to make our coding so much 
easier, isn’t it?

Charles

___

Cocoa-dev mailing list (Cocoa-dev@lists.apple.com)

Please do not post admin requests or moderator comments to the list.
Contact the moderators at cocoa-dev-admins(at)lists.apple.com

Help/Unsubscribe/Update your Subscription:
https://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com

This email sent to arch...@mail-archive.com

Re: Instantiate NSString from NSURL in Swift

2015-02-23 Thread Charles Srstka
On Feb 23, 2015, at 1:52 PM, Fritz Anderson  wrote:
> 
> This is written in haste, and few people are experts…
> 
>theURL.host  may yield nil (host is declared String!, implicitly 
> unwrapped, but optional).
> 
>theURL.host?.lowercaseString  will short-circuit and be evaluated as nil 
> if .host is nil.
> 
>anyString.lowercaseString   may also yield nil; the var is declared 
> String!.
> 
>anyString.lowercaseString!   attempts to unwrap a String that the compiler 
> has implicitly unwrapped already.
> 
> Therefore, because of the short-circuit “?”, the expression 
> theUrl.host?.lowercaseString is of type String?, which may be .None (nil), or 
> .Some(String) (and therefore have to be unwrapped).
> 
> You are passing that optional String as the argument for String(string: {that 
> optional expression}). The argument may be nil; or it may need unwrapping. 
> The initializer _requires_ a non-nil argument. It’s a righteous error.
> 
> The expression
> 
>   NSString(string: foo!)
> 
> is different; by adding the bang you’ve taken responsibility for the 
> parameter’s not being nil.
> 
> Because .lowercaseString returns an implicitly-unwrapped String (String!),
> 
>theURL?.host?.lowercaseString!
> 
> tries to unwrap something that is already, syntactically, an unwrapped String.
> 
> Quincey — my instinct is that the conditional-unwrap chain necessarily forces 
> left-to-right evaluation, tighter than the . operator. The ! would mean, “if 
> you got this far without short-circuiting, and b returns an optional, then 
> unwrap it.” 
> 
> As of today’s Swift 1.2b2, the following in a playground:
> 
>let aURL = NSURL(string: "http://wt9t.com/ ")!
>NSString(string: aURL.host?.lowercaseString)
> 
> complains as you suggest: .host? is potentially nil — that would force the 
> whole expression to be nil, and thus forbidden as a parameter. 
> lowercaseString still gets treated as implicitly unwrapped — so a bang at the 
> end of the whole expression is an attempt to unwrap something the compiler 
> was going to unwrap anyway.

It’s sure great that we have Swift these days to make our coding so much 
easier, isn’t it?

Charles

___

Cocoa-dev mailing list (Cocoa-dev@lists.apple.com)

Please do not post admin requests or moderator comments to the list.
Contact the moderators at cocoa-dev-admins(at)lists.apple.com

Help/Unsubscribe/Update your Subscription:
https://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com

This email sent to arch...@mail-archive.com

Re: Instantiate NSString from NSURL in Swift

2015-02-23 Thread Quincey Morris
On Feb 23, 2015, at 11:52 , Kyle Sluder  wrote:
> 
> So the type of
> foo?.lowercaseString is String?.

Yes, I agree, so the OP’s *original* error message was correct, but the 
question is what is the type of ‘foo?.lowercaseString!’, and that depends on 
the precedence of the “!” operator. 

The actual error messages seem to indicate it’s associating tightly with 
‘lowercaseString’, in which case the source code is incorrect and the error 
messages are all correct.

> And either way, the fixit diagnostic is broken.

Yes, I agree with that, too. If the tight association of “!” is correct, the 
fixit needs to insert parentheses.

FWIW, I think the whole thing is confusing because the internal “?” operator 
has a local effect (changing the type of the sub-expression to its left) and a 
global effect (changing the type of the whole expression). The type of ‘a?.b’ 
is ‘B?', isn’t it? That’s a conceptual trap for the unwary, I think.



___

Cocoa-dev mailing list (Cocoa-dev@lists.apple.com)

Please do not post admin requests or moderator comments to the list.
Contact the moderators at cocoa-dev-admins(at)lists.apple.com

Help/Unsubscribe/Update your Subscription:
https://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com

This email sent to arch...@mail-archive.com

Re: Instantiate NSString from NSURL in Swift

2015-02-23 Thread Fritz Anderson
On 23 Feb 2015, at 8:18 AM, Juanjo Conti  wrote:
> 
> I'm translating some code from Objective-C to Swift and in the middle of
> that, i found this problem.
> 
> theUrl is an instance of NSURL
> 
> theUrl.host?.lowercaseString
> 
> compiles ok.
> 
> But
> 
> NSString(string: theUrl.host?.lowercaseString)
> don't. It says "Value of optional type 'String?' no unwrapped; did you mean
> to use '!' or '?'?
> 
> If I click to add the fix, then it complains again and suggest to delete
> the '!' :)

This is written in haste, and few people are experts…

theURL.host  may yield nil (host is declared String!, implicitly unwrapped, 
but optional).

theURL.host?.lowercaseString  will short-circuit and be evaluated as nil if 
.host is nil.

anyString.lowercaseString   may also yield nil; the var is declared String!.

anyString.lowercaseString!   attempts to unwrap a String that the compiler 
has implicitly unwrapped already.

Therefore, because of the short-circuit “?”, the expression 
theUrl.host?.lowercaseString is of type String?, which may be .None (nil), or 
.Some(String) (and therefore have to be unwrapped).

You are passing that optional String as the argument for String(string: {that 
optional expression}). The argument may be nil; or it may need unwrapping. The 
initializer _requires_ a non-nil argument. It’s a righteous error.

The expression

NSString(string: foo!)

is different; by adding the bang you’ve taken responsibility for the 
parameter’s not being nil.

Because .lowercaseString returns an implicitly-unwrapped String (String!),

theURL?.host?.lowercaseString!

tries to unwrap something that is already, syntactically, an unwrapped String.

Quincey — my instinct is that the conditional-unwrap chain necessarily forces 
left-to-right evaluation, tighter than the . operator. The ! would mean, “if 
you got this far without short-circuiting, and b returns an optional, then 
unwrap it.” 

As of today’s Swift 1.2b2, the following in a playground:

let aURL = NSURL(string: "http://wt9t.com/";)!
NSString(string: aURL.host?.lowercaseString)

complains as you suggest: .host? is potentially nil — that would force the 
whole expression to be nil, and thus forbidden as a parameter. lowercaseString 
still gets treated as implicitly unwrapped — so a bang at the end of the whole 
expression is an attempt to unwrap something the compiler was going to unwrap 
anyway.




By the way: The use of +[NSString stringWithString:] or -[NSString 
initWithString:] is a code smell. The result of lowercaseString is declared as 
immutable, and you aren’t trying to initialize an NSMutableString with it. 
Foundation (unless I’m missing something) is free to treat it just as it does 
with -[NSString copy], and simply return the same object with the retain count 
bumped. Once you get into mutability, the smell goes away, and someone will 
surely jump in now with an explanation for why it’s needed more often than I 
think.


— F



___

Cocoa-dev mailing list (Cocoa-dev@lists.apple.com)

Please do not post admin requests or moderator comments to the list.
Contact the moderators at cocoa-dev-admins(at)lists.apple.com

Help/Unsubscribe/Update your Subscription:
https://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com

This email sent to arch...@mail-archive.com

Re: Instantiate NSString from NSURL in Swift

2015-02-23 Thread Kyle Sluder
On Mon, Feb 23, 2015, at 01:48 PM, Marco S Hyman wrote:
> lowerCaseString is a non optional property.  Therefore it makes no sense
> to
> write someString.lowercaseString? or someString.lowercaseString!

It's chained through an optional access though. So the type of
foo?.lowercaseString is String?.

And either way, the fixit diagnostic is broken.

--Kyle
___

Cocoa-dev mailing list (Cocoa-dev@lists.apple.com)

Please do not post admin requests or moderator comments to the list.
Contact the moderators at cocoa-dev-admins(at)lists.apple.com

Help/Unsubscribe/Update your Subscription:
https://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com

This email sent to arch...@mail-archive.com