With optional chaining, if I have a Swift variable
var s: String?
s might contain nil, or a String wrapped in an Optional. So, I tried this
to get its length:
let count = s?.characters?.count ?? 0
However, the compiler wants this:
let count = s?.characters.count ?? 0
or this:
let count = (s?.characters)?.count ?? 0
My understanding of optional chaining is that, once you start using '?.' in
a dotted expression, the rest of the properties evaluate as optional and
are typically accessed by '?.', not '.'.
So, I dug a little further and tried this in the playground:
var s: String? = "Foo"
print(s?.characters)
The result indicates that s?.characters is indeed an Optional instance,
indicating that s?.characters.count should be illegal.
This isn’t quite how optional chaining in Swift works; see the Swift Programming Guide <The Swift Programming Language: Redirect, specifically “Linking Multiple Levels of Chaining". Basically, `s?.characters.count` works because `s.characters` isn’t Optional. You only use ? on properties that are Optional.
···
On Aug 1, 2016, at 10:26, Stephen Schaub via swift-users <swift-users@swift.org> wrote:
With optional chaining, if I have a Swift variable
var s: String?
s might contain nil, or a String wrapped in an Optional. So, I tried this to get its length:
let count = s?.characters?.count ?? 0
However, the compiler wants this:
let count = s?.characters.count ?? 0
or this:
let count = (s?.characters)?.count ?? 0
My understanding of optional chaining is that, once you start using '?.' in a dotted expression, the rest of the properties evaluate as optional and are typically accessed by '?.', not '.'.
So, I dug a little further and tried this in the playground:
var s: String? = "Foo"
print(s?.characters)
The result indicates that s?.characters is indeed an Optional instance, indicating that s?.characters.count should be illegal.
I understand that the String.characters property is not optional. However,
I am puzzled as to why
s?.characters.count
is legal, but
(s?.characters).count
is not. This seems counterintuitive. Can someone explain the logic or rules
being used here?
Stephen
···
On Mon, Aug 1, 2016 at 2:09 PM, Saagar Jha <saagar@saagarjha.com> wrote:
Saagar Jha
This isn’t quite how optional chaining in Swift works; see the Swift
Programming Guide
<The Swift Programming Language: Redirect,
specifically “Linking Multiple Levels of Chaining". Basically,
`s?.characters.count` works because `s.characters` isn’t Optional. You only
use ? on properties that are Optional.
On Aug 1, 2016, at 10:26, Stephen Schaub via swift-users < > swift-users@swift.org> wrote:
With optional chaining, if I have a Swift variable
var s: String?
s might contain nil, or a String wrapped in an Optional. So, I tried this
to get its length:
let count = s?.characters?.count ?? 0
However, the compiler wants this:
let count = s?.characters.count ?? 0
or this:
let count = (s?.characters)?.count ?? 0
My understanding of optional chaining is that, once you start using '?.'
in a dotted expression, the rest of the properties evaluate as optional and
are typically accessed by '?.', not '.'.
So, I dug a little further and tried this in the playground:
var s: String? = "Foo"
print(s?.characters)
The result indicates that s?.characters is indeed an Optional instance,
indicating that s?.characters.count should be illegal.
let count = s.flatMap { $0.characters.count } ?? 0 // like
s?.characters.count ?? 0
let count = s.flatMap { $0.characters }.flatMap { $0.count } ?? 0 //
like (s?.characters)?.count ?? 0
Jacob
···
On Mon, Aug 1, 2016 at 10:26 AM, Stephen Schaub via swift-users < swift-users@swift.org> wrote:
With optional chaining, if I have a Swift variable
var s: String?
s might contain nil, or a String wrapped in an Optional. So, I tried this
to get its length:
let count = s?.characters?.count ?? 0
However, the compiler wants this:
let count = s?.characters.count ?? 0
or this:
let count = (s?.characters)?.count ?? 0
My understanding of optional chaining is that, once you start using '?.'
in a dotted expression, the rest of the properties evaluate as optional and
are typically accessed by '?.', not '.'.
So, I dug a little further and tried this in the playground:
var s: String? = "Foo"
print(s?.characters)
The result indicates that s?.characters is indeed an Optional instance,
indicating that s?.characters.count should be illegal.
When you write `(s?.characters).count`, the parentheses are evaluated first; `(s?.characters)` gives an `String.CharacterView?`. Accessing the `String.CharacterView?`’s `count` property requires a `?`: `(s?.characters)?.count`. `s?.characters.count`, on the other hand, is applying chaining, which only gives an Optional at the end, intermediate properties don’t require a `?` unless they’re Optional themselves.
Saagar Jha
···
On Aug 1, 2016, at 11:17, Stephen Schaub <sschaub@gmail.com> wrote:
I understand that the String.characters property is not optional. However, I am puzzled as to why
s?.characters.count
is legal, but
(s?.characters).count
is not. This seems counterintuitive. Can someone explain the logic or rules being used here?
Stephen
On Mon, Aug 1, 2016 at 2:09 PM, Saagar Jha <saagar@saagarjha.com <mailto:saagar@saagarjha.com>> wrote:
Saagar Jha
This isn’t quite how optional chaining in Swift works; see the Swift Programming Guide <The Swift Programming Language: Redirect, specifically “Linking Multiple Levels of Chaining". Basically, `s?.characters.count` works because `s.characters` isn’t Optional. You only use ? on properties that are Optional.
On Aug 1, 2016, at 10:26, Stephen Schaub via swift-users <swift-users@swift.org <mailto:swift-users@swift.org>> wrote:
With optional chaining, if I have a Swift variable
var s: String?
s might contain nil, or a String wrapped in an Optional. So, I tried this to get its length:
let count = s?.characters?.count ?? 0
However, the compiler wants this:
let count = s?.characters.count ?? 0
or this:
let count = (s?.characters)?.count ?? 0
My understanding of optional chaining is that, once you start using '?.' in a dotted expression, the rest of the properties evaluate as optional and are typically accessed by '?.', not '.'.
So, I dug a little further and tried this in the playground:
var s: String? = "Foo"
print(s?.characters)
The result indicates that s?.characters is indeed an Optional instance, indicating that s?.characters.count should be illegal.
Got it, I think! I didn't understand that the chaining of intermediate
properties worked that way.
Thanks very much for the explanation.
Stephen
···
On Mon, Aug 1, 2016 at 2:25 PM, Saagar Jha <saagar@saagarjha.com> wrote:
When you write `(s?.characters).count`, the parentheses are evaluated
first; `(s?.characters)` gives an `String.CharacterView?`. Accessing
the `String.CharacterView?`’s `count` property requires a
`?`: `(s?.characters)?.count`. `s?.characters.count`, on the other hand, is
applying chaining, which only gives an Optional at the end, intermediate
properties don’t require a `?` unless they’re Optional themselves.
Saagar Jha
On Aug 1, 2016, at 11:17, Stephen Schaub <sschaub@gmail.com> wrote:
I understand that the String.characters property is not optional. However,
I am puzzled as to why
s?.characters.count
is legal, but
(s?.characters).count
is not. This seems counterintuitive. Can someone explain the logic or
rules being used here?
Stephen
On Mon, Aug 1, 2016 at 2:09 PM, Saagar Jha <saagar@saagarjha.com> wrote:
Saagar Jha
This isn’t quite how optional chaining in Swift works; see the Swift
Programming Guide
<The Swift Programming Language: Redirect,
specifically “Linking Multiple Levels of Chaining". Basically,
`s?.characters.count` works because `s.characters` isn’t Optional. You only
use ? on properties that are Optional.
On Aug 1, 2016, at 10:26, Stephen Schaub via swift-users < >> swift-users@swift.org> wrote:
With optional chaining, if I have a Swift variable
var s: String?
s might contain nil, or a String wrapped in an Optional. So, I tried this
to get its length:
let count = s?.characters?.count ?? 0
However, the compiler wants this:
let count = s?.characters.count ?? 0
or this:
let count = (s?.characters)?.count ?? 0
My understanding of optional chaining is that, once you start using '?.'
in a dotted expression, the rest of the properties evaluate as optional and
are typically accessed by '?.', not '.'.
So, I dug a little further and tried this in the playground:
var s: String? = "Foo"
print(s?.characters)
The result indicates that s?.characters is indeed an Optional instance,
indicating that s?.characters.count should be illegal.
er, I guess it's probably plain ol' map, rather than flatMap.
···
On Mon, Aug 1, 2016 at 8:28 PM, Jacob Bandes-Storch <jtbandes@gmail.com> wrote:
You can think of this like flatMap:
let count = s.flatMap { $0.characters.count } ?? 0 // like
s?.characters.count ?? 0
let count = s.flatMap { $0.characters }.flatMap { $0.count } ?? 0 //
like (s?.characters)?.count ?? 0
Jacob
On Mon, Aug 1, 2016 at 10:26 AM, Stephen Schaub via swift-users < > swift-users@swift.org> wrote:
With optional chaining, if I have a Swift variable
var s: String?
s might contain nil, or a String wrapped in an Optional. So, I tried this
to get its length:
let count = s?.characters?.count ?? 0
However, the compiler wants this:
let count = s?.characters.count ?? 0
or this:
let count = (s?.characters)?.count ?? 0
My understanding of optional chaining is that, once you start using '?.'
in a dotted expression, the rest of the properties evaluate as optional and
are typically accessed by '?.', not '.'.
So, I dug a little further and tried this in the playground:
var s: String? = "Foo"
print(s?.characters)
The result indicates that s?.characters is indeed an Optional instance,
indicating that s?.characters.count should be illegal.
If you are looking for the actual rules, they are defined in the
language reference, in the section on optional chaining expressions
[1]. It states that if you have an optional chaining expression of the
form `expression?` then
"If the value of the optional-chaining expression is nil, all of the
other operations in the postfix expression are ignored and the entire
postfix expression evaluates to nil. If the value of the
optional-chaining expression is not nil, the value of the
optional-chaining expression is unwrapped and used to evaluate the
rest of the postfix expression. [...]. If a postfix expression that
contains an optional-chaining expression is nested inside other
postfix expressions, only the outermost expression returns an optional
type."
However, it seems to me that this is not quite a correct description
of what swiftc does. Note the last sentence in particular. According
to the grammar, given a postfix expression <e> and two identifiers x
and y, the following are both postfix expressions:
<e>?.x.y
(<e>?.x).y
Without further specification, I would consider "the outermost
expression" to be `(<e>?.x).y` for the last case, when swiftc clearly
stops at parentheses. The spec should distinguish between
parenthesized-expressions and other postfix expressions or am I
missing that part?
On Mon, Aug 1, 2016 at 8:17 PM, Stephen Schaub via swift-users <swift-users@swift.org> wrote:
I understand that the String.characters property is not optional. However, I
am puzzled as to why
s?.characters.count
is legal, but
(s?.characters).count
is not. This seems counterintuitive. Can someone explain the logic or rules
being used here?
Stephen
On Mon, Aug 1, 2016 at 2:09 PM, Saagar Jha <saagar@saagarjha.com> wrote:
Saagar Jha
This isn’t quite how optional chaining in Swift works; see the Swift
Programming Guide, specifically “Linking Multiple Levels of Chaining".
Basically, `s?.characters.count` works because `s.characters` isn’t
Optional. You only use ? on properties that are Optional.
On Aug 1, 2016, at 10:26, Stephen Schaub via swift-users >> <swift-users@swift.org> wrote:
With optional chaining, if I have a Swift variable
var s: String?
s might contain nil, or a String wrapped in an Optional. So, I tried this
to get its length:
let count = s?.characters?.count ?? 0
However, the compiler wants this:
let count = s?.characters.count ?? 0
or this:
let count = (s?.characters)?.count ?? 0
My understanding of optional chaining is that, once you start using '?.'
in a dotted expression, the rest of the properties evaluate as optional and
are typically accessed by '?.', not '.'.
So, I dug a little further and tried this in the playground:
var s: String? = "Foo"
print(s?.characters)
The result indicates that s?.characters is indeed an Optional instance,
indicating that s?.characters.count should be illegal.
Thanks for pointing me to the specification. The example given in that
section is helpful.
You make a good point about what constitutes "the outermost expression."
Parenthesized expressions, according to the spec, are primary expressions,
not postfix expressions, but the spec also states that "Syntactically,
every primary expression is also a postfix expression." So, either I'm not
understanding the spec correctly, or the compiler is handling this case
differently for some reason.
Stephen
···
On Mon, Aug 1, 2016 at 3:05 PM, Ingo Maier <ingoem@gmail.com> wrote:
If you are looking for the actual rules, they are defined in the
language reference, in the section on optional chaining expressions
[1]. It states that if you have an optional chaining expression of the
form `expression?` then
"If the value of the optional-chaining expression is nil, all of the
other operations in the postfix expression are ignored and the entire
postfix expression evaluates to nil. If the value of the
optional-chaining expression is not nil, the value of the
optional-chaining expression is unwrapped and used to evaluate the
rest of the postfix expression. [...]. If a postfix expression that
contains an optional-chaining expression is nested inside other
postfix expressions, only the outermost expression returns an optional
type."
However, it seems to me that this is not quite a correct description
of what swiftc does. Note the last sentence in particular. According
to the grammar, given a postfix expression <e> and two identifiers x
and y, the following are both postfix expressions:
<e>?.x.y
(<e>?.x).y
Without further specification, I would consider "the outermost
expression" to be `(<e>?.x).y` for the last case, when swiftc clearly
stops at parentheses. The spec should distinguish between
parenthesized-expressions and other postfix expressions or am I
missing that part?
On Mon, Aug 1, 2016 at 8:17 PM, Stephen Schaub via swift-users > <swift-users@swift.org> wrote:
> I understand that the String.characters property is not optional.
However, I
> am puzzled as to why
>
> s?.characters.count
>
> is legal, but
>
> (s?.characters).count
>
> is not. This seems counterintuitive. Can someone explain the logic or
rules
> being used here?
>
> Stephen
>
>
>
>
> On Mon, Aug 1, 2016 at 2:09 PM, Saagar Jha <saagar@saagarjha.com> wrote:
>>
>>
>> Saagar Jha
>>
>> This isn’t quite how optional chaining in Swift works; see the Swift
>> Programming Guide, specifically “Linking Multiple Levels of Chaining".
>> Basically, `s?.characters.count` works because `s.characters` isn’t
>> Optional. You only use ? on properties that are Optional.
>>
>> On Aug 1, 2016, at 10:26, Stephen Schaub via swift-users > >> <swift-users@swift.org> wrote:
>>
>> With optional chaining, if I have a Swift variable
>>
>> var s: String?
>>
>> s might contain nil, or a String wrapped in an Optional. So, I tried
this
>> to get its length:
>>
>> let count = s?.characters?.count ?? 0
>>
>> However, the compiler wants this:
>>
>> let count = s?.characters.count ?? 0
>>
>> or this:
>>
>> let count = (s?.characters)?.count ?? 0
>>
>> My understanding of optional chaining is that, once you start using '?.'
>> in a dotted expression, the rest of the properties evaluate as optional
and
>> are typically accessed by '?.', not '.'.
>>
>> So, I dug a little further and tried this in the playground:
>>
>> var s: String? = "Foo"
>> print(s?.characters)
>>
>> The result indicates that s?.characters is indeed an Optional instance,
>> indicating that s?.characters.count should be illegal.
>>
>> Why is s?.characters.count a legal expression?
>>
>>
>> --
>> Stephen Schaub
>> _______________________________________________
>> swift-users mailing list
>> swift-users@swift.org
>> https://lists.swift.org/mailman/listinfo/swift-users
>>
>>
>
>
>
> --
> Stephen Schaub
>
> _______________________________________________
> swift-users mailing list
> swift-users@swift.org
> https://lists.swift.org/mailman/listinfo/swift-users
>
Yes, parenthesized expressions are primary expressions, which in turn
are all postfix expressions as specified by the first grammar rule for
postfix expressions and also the note you mentioned. I do think that
swiftc's behavior is the most intuitive. I just think the spec needs
to be clarified in that regard, that's all.
Cheers,
Ingo
···
On Mon, Aug 1, 2016 at 9:24 PM, Stephen Schaub <sschaub@gmail.com> wrote:
Ingo,
Thanks for pointing me to the specification. The example given in that
section is helpful.
You make a good point about what constitutes "the outermost expression."
Parenthesized expressions, according to the spec, are primary expressions,
not postfix expressions, but the spec also states that "Syntactically, every
primary expression is also a postfix expression." So, either I'm not
understanding the spec correctly, or the compiler is handling this case
differently for some reason.
Stephen
On Mon, Aug 1, 2016 at 3:05 PM, Ingo Maier <ingoem@gmail.com> wrote:
If you are looking for the actual rules, they are defined in the
language reference, in the section on optional chaining expressions
[1]. It states that if you have an optional chaining expression of the
form `expression?` then
"If the value of the optional-chaining expression is nil, all of the
other operations in the postfix expression are ignored and the entire
postfix expression evaluates to nil. If the value of the
optional-chaining expression is not nil, the value of the
optional-chaining expression is unwrapped and used to evaluate the
rest of the postfix expression. [...]. If a postfix expression that
contains an optional-chaining expression is nested inside other
postfix expressions, only the outermost expression returns an optional
type."
However, it seems to me that this is not quite a correct description
of what swiftc does. Note the last sentence in particular. According
to the grammar, given a postfix expression <e> and two identifiers x
and y, the following are both postfix expressions:
<e>?.x.y
(<e>?.x).y
Without further specification, I would consider "the outermost
expression" to be `(<e>?.x).y` for the last case, when swiftc clearly
stops at parentheses. The spec should distinguish between
parenthesized-expressions and other postfix expressions or am I
missing that part?
On Mon, Aug 1, 2016 at 8:17 PM, Stephen Schaub via swift-users >> <swift-users@swift.org> wrote:
> I understand that the String.characters property is not optional.
> However, I
> am puzzled as to why
>
> s?.characters.count
>
> is legal, but
>
> (s?.characters).count
>
> is not. This seems counterintuitive. Can someone explain the logic or
> rules
> being used here?
>
> Stephen
>
>
>
>
> On Mon, Aug 1, 2016 at 2:09 PM, Saagar Jha <saagar@saagarjha.com> wrote:
>>
>>
>> Saagar Jha
>>
>> This isn’t quite how optional chaining in Swift works; see the Swift
>> Programming Guide, specifically “Linking Multiple Levels of Chaining".
>> Basically, `s?.characters.count` works because `s.characters` isn’t
>> Optional. You only use ? on properties that are Optional.
>>
>> On Aug 1, 2016, at 10:26, Stephen Schaub via swift-users >> >> <swift-users@swift.org> wrote:
>>
>> With optional chaining, if I have a Swift variable
>>
>> var s: String?
>>
>> s might contain nil, or a String wrapped in an Optional. So, I tried
>> this
>> to get its length:
>>
>> let count = s?.characters?.count ?? 0
>>
>> However, the compiler wants this:
>>
>> let count = s?.characters.count ?? 0
>>
>> or this:
>>
>> let count = (s?.characters)?.count ?? 0
>>
>> My understanding of optional chaining is that, once you start using
>> '?.'
>> in a dotted expression, the rest of the properties evaluate as optional
>> and
>> are typically accessed by '?.', not '.'.
>>
>> So, I dug a little further and tried this in the playground:
>>
>> var s: String? = "Foo"
>> print(s?.characters)
>>
>> The result indicates that s?.characters is indeed an Optional instance,
>> indicating that s?.characters.count should be illegal.
>>
>> Why is s?.characters.count a legal expression?
>>
>>
>> --
>> Stephen Schaub
>> _______________________________________________
>> swift-users mailing list
>> swift-users@swift.org
>> https://lists.swift.org/mailman/listinfo/swift-users
>>
>>
>
>
>
> --
> Stephen Schaub
>
> _______________________________________________
> swift-users mailing list
> swift-users@swift.org
> https://lists.swift.org/mailman/listinfo/swift-users
>