# try? works on non-method-call?

**URL:** <https://forums.swift.org/t/try-works-on-non-method-call/3497>\
**Category:** Using Swift\
**Created:** [July 21, 2016, 6:13am UTC](https://forums.swift.org/t/try-works-on-non-method-call/3497 "2016-07-21T06:13:01Z")\
**Posts on this page:** 6\
**Page:** 1

<div class="post-metadata">

**Author:** ![Sikhapol\_Saijit](https://avatars.discourse-cdn.com/v4/letter/s/48db29/32.png) [@Sikhapol\_Saijit](https://forums.swift.org/u/Sikhapol_Saijit)\
**Post date:** [July 21, 2016, 6:13am UTC](https://forums.swift.org/t/try-works-on-non-method-call/3497/1 "2016-07-21T06:13:01Z")

</div>

Hi Swift Community,

Yesterday I tried this code:

```swift
func couldFailButWillNot() throws -> Any {
  return 42
}

if let a = try? couldFailButWillNot() as? Int {
  print(a)
}

```

And was surprised that the output was "Optional(42)” on both Swift 2.2 and Swift 3.  
I always have the impression that when a variable is resolved with `if let` it will never be optional.

So, with a little investigation, I found out that it happens because `as?` has higher precedence than `try?` and is evaluated first.  
And the whole expression `try? couldFailButWillNot() as? Int` evaluated as “Optional(Optional(42))”.

Also, I’m surprised that `try?` can be used with non-method-call.  
This code: `print(try? 42)` will print “Optional(42)”.

So, the questions are:

1. Is it intentional that `try?` can be used with non-method-call and return an optional of the type that follows?

2. Should we design `try?` to have higher precedence than `as?`.  
My intuition tells me that  
`let a = try? couldFailButWillNot() as? Int`  
and  
`let a = (try? couldFailButWillNot()) as? Int`  
should be equivalent.

3. Do you think that doubly-nested optional (or multi-level-nested optional) is confusing and should be removed from Swift? (Yes, I’ve seen this blog post [Optionals Case Study: valuesForKeys]([Optionals Case Study: valuesForKeys - Swift Blog - Apple Developer](https://developer.apple.com/swift/blog/?id=12) \<[Optionals Case Study: valuesForKeys - Swift Blog - Apple Developer](https://developer.apple.com/swift/blog/?id=12&gt;%5C)))  
For me “Optional(nil)” (aka “Optional.Some(Optional.None))”) doesn’t make any sense at all.  
Maybe, one of the solution is to always have optional of optional merged into a single level optional? Like Optional(Optional(Optional(42))) should be the merged to Optional(42).

Thank you  
Sikhapol Saijit (Sam)  
iOS Developer, Taskworld, Bangkok

---

<div class="post-metadata">

**Author:** ![hartbit](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/hartbit/32/738_2.png) [@hartbit](https://forums.swift.org/u/hartbit)\
**Post date:** [July 21, 2016, 6:27am UTC](https://forums.swift.org/t/try-works-on-non-method-call/3497/2 "2016-07-21T06:27:30Z")

</div>

I think that on error or warning like this is the right solution.

> **···**
>
> > On 21 Jul 2016, at 08:13, Sikhapol Saijit via swift-users \<swift-users@swift.org\> wrote:
> > 
> > 1. Is it intentional that `try?` can be used with non-method-call and return an optional of the type that follows?

---

<div class="post-metadata">

**Author:** ![Nicholas\_Outram](https://avatars.discourse-cdn.com/v4/letter/n/df705f/32.png) [@Nicholas\_Outram](https://forums.swift.org/u/Nicholas_Outram)\
**Post date:** [July 21, 2016, 7:59am UTC](https://forums.swift.org/t/try-works-on-non-method-call/3497/3 "2016-07-21T07:59:18Z")

</div>

The issue is related to the as?

Try this:

if let a = try? couldFailButWillNot() {  
&nbsp;&nbsp;&nbsp;print(a)  
}

Nick

> **···**
>
> > On 21 Jul 2016, at 07:13, Sikhapol Saijit via swift-users \<swift-users@swift.org\> wrote:
> > 
> > Hi Swift Community,
> > 
> > Yesterday I tried this code:
> > 
> > ```swift
> > func couldFailButWillNot() throws -> Any {
> > return 42
> > }
> > 
> > if let a = try? couldFailButWillNot() as? Int {
> > print(a)
> > }
> > 
> > ```
> > 
> > And was surprised that the output was "Optional(42)” on both Swift 2.2 and Swift 3.  
> > I always have the impression that when a variable is resolved with `if let` it will never be optional.
> > 
> > So, with a little investigation, I found out that it happens because `as?` has higher precedence than `try?` and is evaluated first.  
> > And the whole expression `try? couldFailButWillNot() as? Int` evaluated as “Optional(Optional(42))”.
> > 
> > Also, I’m surprised that `try?` can be used with non-method-call.  
> > This code: `print(try? 42)` will print “Optional(42)”.
> > 
> > So, the questions are:
> > 
> > 1. Is it intentional that `try?` can be used with non-method-call and return an optional of the type that follows?
> > 
> > 2. Should we design `try?` to have higher precedence than `as?`.  
> > My intuition tells me that  
> > `let a = try? couldFailButWillNot() as? Int`  
> > and  
> > `let a = (try? couldFailButWillNot()) as? Int`  
> > should be equivalent.
> > 
> > 3. Do you think that doubly-nested optional (or multi-level-nested optional) is confusing and should be removed from Swift? (Yes, I’ve seen this blog post [Optionals Case Study: valuesForKeys]([Optionals Case Study: valuesForKeys - Swift Blog - Apple Developer](https://developer.apple.com/swift/blog/?id=12) \<[Optionals Case Study: valuesForKeys - Swift Blog - Apple Developer](https://developer.apple.com/swift/blog/?id=12&gt;%5C)))  
> > For me “Optional(nil)” (aka “Optional.Some(Optional.None))”) doesn’t make any sense at all.  
> > Maybe, one of the solution is to always have optional of optional merged into a single level optional? Like Optional(Optional(Optional(42))) should be the merged to Optional(42).
> > 
> > Thank you  
> > Sikhapol Saijit (Sam)  
> > iOS Developer, Taskworld, Bangkok  
> > \_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_  
> > swift-users mailing list  
> > swift-users@swift.org  
> > [https://lists.swift.org/mailman/listinfo/swift-users](https://lists.swift.org/mailman/listinfo/swift-users)

---

<div class="post-metadata">

**Author:** ![Nicholas\_Outram](https://avatars.discourse-cdn.com/v4/letter/n/df705f/32.png) [@Nicholas\_Outram](https://forums.swift.org/u/Nicholas_Outram)\
**Post date:** [July 21, 2016, 8:03am UTC](https://forums.swift.org/t/try-works-on-non-method-call/3497/4 "2016-07-21T08:03:40Z")

</div>

Are we saying this function

func couldFailButWillNot() throws -\> Any {  
&nbsp;&nbsp;return 42  
}

has an implicit Int return type?

If so, there is actually no need for as? (which will result in an Optional - which I thought that was the behaviour in Swift 2 as well?)

> **···**
>
> > On 21 Jul 2016, at 08:59, Nicholas Outram via swift-users \<swift-users@swift.org\> wrote:
> > 
> > The issue is related to the as?
> > 
> > Try this:
> > 
> > if let a = try? couldFailButWillNot() {  
> > &nbsp;&nbsp;&nbsp;print(a)  
> > }
> > 
> > Nick
> > 
> > > On 21 Jul 2016, at 07:13, Sikhapol Saijit via swift-users \<swift-users@swift.org \<mailto:swift-users@swift.org\>\> wrote:
> > > 
> > > Hi Swift Community,
> > > 
> > > Yesterday I tried this code:
> > > 
> > > ```swift
> > > func couldFailButWillNot() throws -> Any {
> > > return 42
> > > }
> > > 
> > > if let a = try? couldFailButWillNot() as? Int {
> > > print(a)
> > > }
> > > 
> > > ```
> > > 
> > > And was surprised that the output was "Optional(42)” on both Swift 2.2 and Swift 3.  
> > > I always have the impression that when a variable is resolved with `if let` it will never be optional.
> > > 
> > > So, with a little investigation, I found out that it happens because `as?` has higher precedence than `try?` and is evaluated first.  
> > > And the whole expression `try? couldFailButWillNot() as? Int` evaluated as “Optional(Optional(42))”.
> > > 
> > > Also, I’m surprised that `try?` can be used with non-method-call.  
> > > This code: `print(try? 42)` will print “Optional(42)”.
> > > 
> > > So, the questions are:
> > > 
> > > 1. Is it intentional that `try?` can be used with non-method-call and return an optional of the type that follows?
> > > 
> > > 2. Should we design `try?` to have higher precedence than `as?`.  
> > > My intuition tells me that  
> > > `let a = try? couldFailButWillNot() as? Int`  
> > > and  
> > > `let a = (try? couldFailButWillNot()) as? Int`  
> > > should be equivalent.
> > > 
> > > 3. Do you think that doubly-nested optional (or multi-level-nested optional) is confusing and should be removed from Swift? (Yes, I’ve seen this blog post [Optionals Case Study: valuesForKeys]([Optionals Case Study: valuesForKeys - Swift Blog - Apple Developer](https://developer.apple.com/swift/blog/?id=12) \<[Optionals Case Study: valuesForKeys - Swift Blog - Apple Developer](https://developer.apple.com/swift/blog/?id=12&gt;%5C)))  
> > > For me “Optional(nil)” (aka “Optional.Some(Optional.None))”) doesn’t make any sense at all.  
> > > Maybe, one of the solution is to always have optional of optional merged into a single level optional? Like Optional(Optional(Optional(42))) should be the merged to Optional(42).
> > > 
> > > Thank you  
> > > Sikhapol Saijit (Sam)  
> > > iOS Developer, Taskworld, Bangkok  
> > > \_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_  
> > > swift-users mailing list  
> > > swift-users@swift.org \<mailto:swift-users@swift.org\>  
> > > [https://lists.swift.org/mailman/listinfo/swift-users](https://lists.swift.org/mailman/listinfo/swift-users)
> > 
> > \_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_  
> > swift-users mailing list  
> > swift-users@swift.org  
> > [https://lists.swift.org/mailman/listinfo/swift-users](https://lists.swift.org/mailman/listinfo/swift-users)

---

<div class="post-metadata">

**Author:** ![Sikhapol\_Saijit](https://avatars.discourse-cdn.com/v4/letter/s/48db29/32.png) [@Sikhapol\_Saijit](https://forums.swift.org/u/Sikhapol_Saijit)\
**Post date:** [July 21, 2016, 8:25am UTC](https://forums.swift.org/t/try-works-on-non-method-call/3497/5 "2016-07-21T08:25:12Z")

</div>

Hi Nick,

The code was simplified for demonstration.  
You’re right that in a simple case like that I wouldn’t need to use `as?`.

In my actual case it was something like this:

func parse(JSON: Data) throws -\> Any {  
&nbsp;&nbsp;&nbsp;&nbsp;// …  
}

if let dict = try? parse(JSON: json) as? [String: Any] {  
&nbsp;&nbsp;&nbsp;&nbsp;// assume dict is a valid [String: Any] dictionary  
&nbsp;&nbsp;&nbsp;&nbsp;// …  
}

Sure, this could be written as:

if let jsonObject = try? parse(JSON: json),  
let dict = jsonObject as? [String: Any] {  
&nbsp;&nbsp;&nbsp;&nbsp;// …  
}

But I just wonder why the first case behave as it does and whether it should.

Sam

> **···**
>
> > On Jul 21, 2016, at 3:03 PM, Nicholas Outram \<nicholas.outram@icloud.com\> wrote:
> > 
> > Are we saying this function
> > 
> > func couldFailButWillNot() throws -\> Any {  
> > &nbsp;&nbsp;return 42  
> > }
> > 
> > has an implicit Int return type?
> > 
> > If so, there is actually no need for as? (which will result in an Optional - which I thought that was the behaviour in Swift 2 as well?)
> > 
> > > On 21 Jul 2016, at 08:59, Nicholas Outram via swift-users \<swift-users@swift.org \<mailto:swift-users@swift.org\>\> wrote:
> > > 
> > > The issue is related to the as?
> > > 
> > > Try this:
> > > 
> > > if let a = try? couldFailButWillNot() {  
> > > &nbsp;&nbsp;&nbsp;print(a)  
> > > }
> > > 
> > > Nick
> > > 
> > > > On 21 Jul 2016, at 07:13, Sikhapol Saijit via swift-users \<swift-users@swift.org \<mailto:swift-users@swift.org\>\> wrote:
> > > > 
> > > > Hi Swift Community,
> > > > 
> > > > Yesterday I tried this code:
> > > > 
> > > > ```swift
> > > > func couldFailButWillNot() throws -> Any {
> > > > return 42
> > > > }
> > > > 
> > > > if let a = try? couldFailButWillNot() as? Int {
> > > > print(a)
> > > > }
> > > > 
> > > > ```
> > > > 
> > > > And was surprised that the output was "Optional(42)” on both Swift 2.2 and Swift 3.  
> > > > I always have the impression that when a variable is resolved with `if let` it will never be optional.
> > > > 
> > > > So, with a little investigation, I found out that it happens because `as?` has higher precedence than `try?` and is evaluated first.  
> > > > And the whole expression `try? couldFailButWillNot() as? Int` evaluated as “Optional(Optional(42))”.
> > > > 
> > > > Also, I’m surprised that `try?` can be used with non-method-call.  
> > > > This code: `print(try? 42)` will print “Optional(42)”.
> > > > 
> > > > So, the questions are:
> > > > 
> > > > 1. Is it intentional that `try?` can be used with non-method-call and return an optional of the type that follows?
> > > > 
> > > > 2. Should we design `try?` to have higher precedence than `as?`.  
> > > > My intuition tells me that  
> > > > `let a = try? couldFailButWillNot() as? Int`  
> > > > and  
> > > > `let a = (try? couldFailButWillNot()) as? Int`  
> > > > should be equivalent.
> > > > 
> > > > 3. Do you think that doubly-nested optional (or multi-level-nested optional) is confusing and should be removed from Swift? (Yes, I’ve seen this blog post [Optionals Case Study: valuesForKeys]([Optionals Case Study: valuesForKeys - Swift Blog - Apple Developer](https://developer.apple.com/swift/blog/?id=12) \<[Optionals Case Study: valuesForKeys - Swift Blog - Apple Developer](https://developer.apple.com/swift/blog/?id=12&gt;%5C)))  
> > > > For me “Optional(nil)” (aka “Optional.Some(Optional.None))”) doesn’t make any sense at all.  
> > > > Maybe, one of the solution is to always have optional of optional merged into a single level optional? Like Optional(Optional(Optional(42))) should be the merged to Optional(42).
> > > > 
> > > > Thank you  
> > > > Sikhapol Saijit (Sam)  
> > > > iOS Developer, Taskworld, Bangkok  
> > > > \_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_  
> > > > swift-users mailing list  
> > > > swift-users@swift.org \<mailto:swift-users@swift.org\>  
> > > > [https://lists.swift.org/mailman/listinfo/swift-users](https://lists.swift.org/mailman/listinfo/swift-users)
> > > 
> > > \_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_  
> > > swift-users mailing list  
> > > swift-users@swift.org \<mailto:swift-users@swift.org\>  
> > > [https://lists.swift.org/mailman/listinfo/swift-users](https://lists.swift.org/mailman/listinfo/swift-users)

---

<div class="post-metadata">

**Author:** ![Zhao\_Xin](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/zhao_xin/32/8394_2.png) [@Zhao\_Xin](https://forums.swift.org/u/Zhao_Xin)\
**Post date:** [July 21, 2016, 8:57am UTC](https://forums.swift.org/t/try-works-on-non-method-call/3497/6 "2016-07-21T08:57:17Z")

</div>

I think the best way is

do {

&nbsp;&nbsp;&nbsp;&nbsp;let a = try couldFailButWillNot()

&nbsp;&nbsp;&nbsp;&nbsp;if let b = a as? Int {

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;print(b)

&nbsp;&nbsp;&nbsp;&nbsp;}

} catch let error {

&nbsp;&nbsp;&nbsp;&nbsp;print(error)

}

It is longer, but much clearer.

Below code will work, but not as clear. You don't know whether it is a or b  
causes the failure. It is not a good practice to use try? if that is not on  
purpose.

if let a = try? couldFailButWillNot(), let b = a as? Int {

&nbsp;&nbsp;&nbsp;&nbsp;print(b)

}  
or

if let a = (try? couldFailButWillNot()) as? Int {

&nbsp;&nbsp;&nbsp;&nbsp;print(a)

}

Zhaoxin

> **···**
>
> On Thu, Jul 21, 2016 at 4:25 PM, Sikhapol Saijit via swift-users \< swift-users@swift.org\> wrote:
> 
> > Hi Nick,
> > 
> > The code was simplified for demonstration.  
> > You’re right that in a simple case like that I wouldn’t need to use `as?`.
> > 
> > In my actual case it was something like this:
> > 
> > func parse(JSON: Data) throws -\> Any {  
> > &nbsp;&nbsp;&nbsp;&nbsp;// …  
> > }
> > 
> > if let dict = try? parse(JSON: json) as? [String: Any] {  
> > &nbsp;&nbsp;&nbsp;&nbsp;// assume dict is a valid [String: Any] dictionary  
> > &nbsp;&nbsp;&nbsp;&nbsp;// …  
> > }
> > 
> > Sure, this could be written as:
> > 
> > if let jsonObject = try? parse(JSON: json),  
> > let dict = jsonObject as? [String: Any] {  
> > &nbsp;&nbsp;&nbsp;&nbsp;// …  
> > }
> > 
> > But I just wonder why the first case behave as it does and whether it  
> > should.
> > 
> > Sam
> > 
> > On Jul 21, 2016, at 3:03 PM, Nicholas Outram \<nicholas.outram@icloud.com\> \> wrote:
> > 
> > Are we saying this function
> > 
> > func couldFailButWillNot() throws -\> Any {  
> > &nbsp;&nbsp;return 42  
> > }
> > 
> > has an implicit Int return type?
> > 
> > If so, there is actually no need for as? (which will result in an Optional  
> > - which I thought that was the behaviour in Swift 2 as well?)
> > 
> > On 21 Jul 2016, at 08:59, Nicholas Outram via swift-users \< \> swift-users@swift.org\> wrote:
> > 
> > The issue is related to the as?
> > 
> > Try this:
> > 
> > if let a = try? couldFailButWillNot() {  
> > &nbsp;&nbsp;&nbsp;print(a)  
> > }
> > 
> > Nick
> > 
> > On 21 Jul 2016, at 07:13, Sikhapol Saijit via swift-users \< \> swift-users@swift.org\> wrote:
> > 
> > Hi Swift Community,
> > 
> > Yesterday I tried this code:
> > 
> > ```swift
> > func couldFailButWillNot() throws -> Any {
> > return 42
> > }
> > 
> > if let a = try? couldFailButWillNot() as? Int {
> > print(a)
> > }
> > 
> > ```
> > 
> > And was surprised that the output was \*"Optional(42)”\* on both Swift 2.2  
> > and Swift 3.  
> > I always have the impression that when a variable is resolved with `if  
> > let` it will never be optional.
> > 
> > So, with a little investigation, I found out that it happens because `as?`  
> > has higher precedence than `try?` and is evaluated first.  
> > And the whole expression `try? couldFailButWillNot() as? Int` evaluated  
> > as \*“Optional(Optional(42))”\*.
> > 
> > Also, I’m surprised that `try?` can be used with non-method-call.  
> > This code: `print(try? 42)` will print \*“Optional(42)”\*.
> > 
> > So, the questions are:
> > 
> > 1. Is it intentional that `try?` can be used with non-method-call and  
> > return an optional of the type that follows?
> > 
> > 2. Should we design `try?` to have higher precedence than `as?`.  
> > My intuition tells me that  
> > `let a = try? couldFailButWillNot() as? Int`  
> > and  
> > `let a = (try? couldFailButWillNot()) as? Int`  
> > should be equivalent.
> > 
> > 3. Do you think that doubly-nested optional (or multi-level-nested  
> > optional) is confusing and should be removed from Swift? (Yes, I’ve seen  
> > this blog post [Optionals Case Study: valuesForKeys](  
> > [Swift Blog - Apple Developer](https://developer.apple.com/swift/blog/?id=12%5C)))  
> > For me “Optional(nil)” (aka “Optional.Some(Optional.None))”) doesn’t make  
> > any sense at all.  
> > Maybe, one of the solution is to always have optional of optional merged  
> > into a single level optional? Like Optional(Optional(Optional(42))) should  
> > be the merged to Optional(42).
> > 
> > Thank you  
> > Sikhapol Saijit (Sam)  
> > iOS Developer, Taskworld, Bangkok  
> > \_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_  
> > swift-users mailing list  
> > swift-users@swift.org  
> > [https://lists.swift.org/mailman/listinfo/swift-users](https://lists.swift.org/mailman/listinfo/swift-users)
> > 
> > \_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_  
> > swift-users mailing list  
> > swift-users@swift.org  
> > [https://lists.swift.org/mailman/listinfo/swift-users](https://lists.swift.org/mailman/listinfo/swift-users)
> > 
> > \_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_  
> > swift-users mailing list  
> > swift-users@swift.org  
> > [https://lists.swift.org/mailman/listinfo/swift-users](https://lists.swift.org/mailman/listinfo/swift-users)
