+1. I've had a hard time cleaning up certain pieces of code that involve
multiple optional chains and condition checks.
One solution I came up with, but have never used in practice (because it's
too obscure), is this:
extension Equatable {
func *except*(excludedValue: Self) -> Self? {
return self == excludedValue ? nil : self
}
}
Then you can make a non-optional Equatable value into an Optional by
checking against a known excluded value:
if let input = inputs.first, ...,
let matchLoc = regex.rangeOfFirstMatchInString(...).location.
*except*(NSNotFound)
{
// Do something with matchLoc
} else ...
Another, more flexible, option is to make a new protocol with an extension
that provides similar functionality, but with a closure argument. Then you
unfortunately have to add a trivial conformance for any type you need to
use.
protocol Satisfying {}
extension Satisfying {
func *satisfying*(@noescape predicate: Self -> Bool) -> Self? {
return predicate(self) ? self : nil
}
}
extension NSRange: Satisfying {}
if let input = inputs.first, ...,
let matchRange = regex.rangeOfFirstMatchInString(...).*satisfying*({
$0.location != NSNotFound })
{
// Do something with matchRange
} else ...
To be clear, here's what the user *wants* to do; the clearest code:
if let input = inputs.first, ...,
let matchRange = regex.rangeOfFirstMatchInString(...)
*where* matchRange.location != NSNotFound
{
// Do something with matchRange
} else ...
But that's not allowed, because rangeOfFirstMatchInString returns a
non-optional NSRange.
(Arguably this is a bug to be fixed in the regex API, which should be
replacing NSRange with Range<Int>?, but it's a good example of something
that crops up in plenty of other places.)
Jacob
···
On Wed, Jan 6, 2016 at 11:06 PM, Krzysztof Siejkowski via swift-evolution < swift-evolution@swift.org> wrote:
FWIW, not sure if it fits your desired outcome, but some time ago I’ve
proposed the idea of `CustomOptionalConvertible` protocol:
[swift-evolution] Proposal: extend Optional-specific syntax to arbitrary types with CustomOptionalConvertible
This could be used to extend the let binding syntax to any arbitrary type,
as long as the user provides the valid translation to Optional<Type>.
The proposal, unfortunately, did not get a lot of attention at the time.
The main drawback to such a solution for your case is that
CustomOptionalConvertible is an opt-in mechanism, so you’d need to write
the implementation of CustomOptionalConvertible to each type you wish to
let bind:
extension Type : CustomOptionalConvertible {
typealias Wrapped = Type
public var optional: Optional<Type> { get {
return .Some(self)
}}
}
Would the necessity for the above boilerplate be a show-stopper to you?
If so, would you rather see the extension of let bind syntax as default on
for all the types?
Cheers,
Krzysztof
On 7 January 2016 at 07:41:06, Russ Bishop via swift-evolution ( > swift-evolution@swift.org) wrote:
I often want to bind variables to a specific scope, or perhaps I have
three optionals I want to bind and one non-optional. (Often I need that
non-optional value as part of a where condition check but not being able to
bind it means I leak the variable to the outer scope).
Not being able to bind non-optionals breaks the flow of the code and
forces me to make a minor context switch when it really doesn’t matter, nor
does it aid code clarity.
Does anyone have strong thoughts about this? I tried searching the
evolution repo and the mailing list and didn’t see anything.
—russ
_______________________________________________
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