> > On 15 Aug 2016, at 08:02, Justin Jia via 
> > swift-evolution<swift-evolution@swift.org(mailto:swift-evolution@swift.org)>wrote:
> > Hi!
> > 
> > I don’t know if this has came up before. I tried to search though the 
> > mailing list but didn’t find any related threads.
> > 
> > This is purely a syntactic thing (which I know it’s the lowest priority for 
> > Swift 4), but I think it’s an important one.
> > 
> > Let’s say we have a struct with a function:
> > 
> > ```
> > struct Foo {
> > func bar(x: Int)
> > }
> > ```
> > 
> > We can use optionals:
> > 
> > ```
> > let foo: Foo? = nil
> > let x = 1
> > foo!.bar(x: x) // Able to compile, but will cause runtime error
> > foo?.bar(x: x) // Able to compile, and won't cause runtime error
> > ```
> > 
> > However:
> > 
> > ```
> > let foo = Foo()
> > let x: Int? = nil
> > foo.bar(x: x!) // Able to compile, but will cause runtime error
> > foo.bar(x: x?) // Won't compile
> > ```
> > 
> > I propose that we should allow `foo.bar(x: x?)`, which should be equivalent 
> > to:
> > 
> > ```
> > if let x = x {
> > foo.bar(x: x)
> > }
> > ```
> > 
> > What do you think?
> I like the intent behind this, but personally I think it's not clear enough. 
> For me, putting the statement in a conditional as you've shown is the better 
> solution, as it's a lot clearer exactly what's going on. Putting a question 
> mark on a variable makes it look like something specific to that variable, 
> rather than preventing the entire statement from executing.

I get where you’re coming from, but how would people react if optional chaining 
wasn’t in the language yet and someone proposed it now? I know it’s not 
strictly the same thing, but it’s still a single question mark that prevents 
the whole statement from being executed. I think it would be met with a lot of 
resistance from people saying that being more explicit with `if let` is the way 
to go.

> There may be some alternatives though, for example, what about a shorthand 
> for the conditional like so:
> 
> if let x? { foo.bar(x: x) }
> if x? { foo.bar(x: x) } // even shorter?

The alternatives you’ve come up with would only work if foo.bar doesn’t return 
anything. If it does return something, and you want to assign it to a variable, 
you have to declare the variable beforehand and it just becomes ugly. It’s then 
probably a better idea to use map/flatmap:

x.flatMap { foo.bar(x: $0) }

But IMO that's not as clean as `foo.bar(x: x?)`. flatMap is so hidden to most 
people that they resort to things like

myDictionary[myOptionalString ?? “”]

assuming that no key is the empty string. People might also make function 
overloads that accept and return optionals, just to avoid nesting. I’m sure 
you’ve seen something like this before:

if limit == nil || number < limit! { /* … */ }

There’s no great way to “fix” this. We can do

if limit.map({ number < $0 }) { /* … */ }

or we can overload the < operator for optionals to return Bool?, which we can 
use with

if (number < limit) ?? true { /* … */ }

With the new sugar, we’d be able to do

if (number < limit?) ?? true { /* … */ }

out of the box.

> But in general, I think it's best to be explicit about the entire statement 
> being optional, which the conditional does but a postfix on a variable 
> doesn't to the same degree._______________________________________________
> swift-evolution mailing list
> swift-evolution@swift.org
> https://lists.swift.org/mailman/listinfo/swift-evolution
> 
> 
> 
_______________________________________________
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution

Reply via email to