<html><head><style>body{font-family:Helvetica,Arial;font-size:13px}</style></head><body style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space;"><div id="bloop_customfont" style="font-family:Helvetica,Arial;font-size:13px; color: rgba(0,0,0,1.0); margin: 0px; line-height: auto;">Was it a part of your idea to allow the `PossibleValueType` to be used in Optional-only syntax constructs like conditional binding? If so, do you see any advantages of such solution over `CustomOptionalConvertible`?</div><div id="bloop_customfont" style="font-family:Helvetica,Arial;font-size:13px; color: rgba(0,0,0,1.0); margin: 0px; line-height: auto;"><br></div><div id="bloop_customfont" style="font-family:Helvetica,Arial;font-size:13px; color: rgba(0,0,0,1.0); margin: 0px; line-height: auto;">Cheers,</div><div id="bloop_customfont" style="font-family:Helvetica,Arial;font-size:13px; color: rgba(0,0,0,1.0); margin: 0px; line-height: auto;">Krzysztof</div> <div id="bloop_sign_1449583751037275136" class="bloop_sign"></div> <br><p class="airmail_on">On 8 December 2015 at 04:46:55, Matthew Johnson (<a href="mailto:matthew@anandabits.com">matthew@anandabits.com</a>) wrote:</p> <blockquote type="cite" class="clean_bq"><span><div dir="auto"><div></div><div>
<title></title>
<div>For what it's worth, I filed a radar for a protocol along
these lines epic the early days OS Swift, but took a slightly
different approach. It looked something like this:</div>
<div id="AppleMailSignature"><br></div>
<div id="AppleMailSignature">protocol PossibleValueType {</div>
<div id="AppleMailSignature"> typealias
Value</div>
<div id="AppleMailSignature"> var hasValue: Bool { get
}</div>
<div id="AppleMailSignature"> var value: Value //
implementations call fatalError or similar if hasValue is
false</div>
<div id="AppleMailSignature">}<br>
<br>
Rather than returning an Optional that wraps the value we allow
presence or absence of value to be detected and if a value is
present we allow it to be extracted.</div>
<div id="AppleMailSignature"><br></div>
<div id="AppleMailSignature">Matthew</div>
<div id="AppleMailSignature"><br></div>
<div id="AppleMailSignature">Sent from my iPad</div>
<div><br>
On Dec 7, 2015, at 3:38 PM, Paul Cantrell via swift-evolution
<<a href="mailto:swift-evolution@swift.org">swift-evolution@swift.org</a>>
wrote:<br>
<br></div>
<blockquote type="cite">
<div>
<div class="">
<div class="bloop_sign" id="bloop_sign_1449521438123563008">
<div class="bloop_sign" id="bloop_sign_1449521438123563008">
<div class="bloop_sign" id="bloop_sign_1449521438123563008">
<div class="bloop_sign" id="bloop_sign_1449521438123563008" style="font-family: Helvetica, Arial;">I like the sentiment of this
proposal, but I’m not sure it provides clear value. We already have
a generalized version of “if let” in the form of “if case”:</div>
<div class="bloop_sign" id="bloop_sign_1449521438123563008" style="font-family: Helvetica, Arial;"><br class=""></div>
<div class="bloop_sign" id="bloop_sign_1449521438123563008">
<div class="bloop_sign" id="bloop_sign_1449521438123563008">
<div style="margin: 0px; font-size: 10.5px; line-height: normal; font-family: Menlo;" class=""> <span style="color: rgb(50, 62, 125);" class="">func</span> foo(either: <span style="color: rgb(88, 126, 168);" class="">Either</span><<span style="color: rgb(88, 126, 168);" class="">String</span>>)
-> <span style="color: rgb(88, 126, 168);" class="">String</span> {</div>
<div style="margin: 0px; font-size: 10.5px; line-height: normal; font-family: Menlo;" class=""> <span style="color: rgb(50, 62, 125);" class="">if</span> <span style="color: rgb(50, 62, 125);" class="">case</span> .Right(<span style="color: rgb(50, 62, 125);" class="">let</span> string) = either {</div>
<div style="margin: 0px; font-size: 10.5px; line-height: normal; font-family: Menlo;" class="">
<span style="color: rgb(50, 62, 125);" class="">return</span> string</div>
<div style="margin: 0px; font-size: 10.5px; line-height: normal; font-family: Menlo;" class=""> } <span style="color: rgb(50, 62, 125);" class="">else</span> {</div>
<div style="margin: 0px; font-size: 10.5px; line-height: normal; font-family: Menlo;" class="">
<span style="color: rgb(50, 62, 125);" class="">return</span> <span style="color: rgb(132, 62, 100);" class="">"No value"</span></div>
<div style="margin: 0px; font-size: 10.5px; line-height: normal; font-family: Menlo;" class=""> }</div>
<div style="margin: 0px; font-size: 10.5px; line-height: normal; font-family: Menlo;" class=""> }</div>
<div class=""><br class=""></div>
<div class="">This works with cascades just fine:</div>
<div class=""><br class=""></div>
</div>
</div>
</div>
</div>
</div>
</div>
<div style="margin: 0px; font-size: 10.5px; line-height: normal; font-family: Menlo;" class=""> <span style="color: rgb(50, 62, 125);" class="">if</span> <span style="color: rgb(50, 62, 125);" class="">case</span> .Right(<span style="color: rgb(50, 62, 125);" class="">let</span> string0) =
either0,</div>
<div style="margin: 0px; font-size: 10.5px; line-height: normal; font-family: Menlo;" class="">
.Right(<span style="color: rgb(50, 62, 125);" class="">let</span> string1) = either1,</div>
<div style="margin: 0px; font-size: 10.5px; line-height: normal; font-family: Menlo;" class="">
.Right(<span style="color: rgb(50, 62, 125);" class="">let</span> string2) = either2 {</div>
<div class=""><br class=""></div>
<div class="">Leaving aside that Swift’s “if case” syntax is a bit
clumsy and hard to remember at first, does a <font face="Helvetica, Arial" class="">CustomOptionalConvertible really grant
additional benefit in terms of either safety or
readability?</font></div>
<div class=""><font face="Helvetica, Arial" class=""><br class=""></font></div>
<div class=""><font face="Helvetica, Arial" class="">Cheers,</font></div>
<div class=""><font face="Helvetica, Arial" class=""><br class=""></font></div>
<div class=""><font face="Helvetica, Arial" class="">Paul</font></div>
<div class=""><font face="Helvetica, Arial" class=""><br class=""></font></div>
<div class=""><font face="Helvetica, Arial" class=""><br class=""></font></div>
<div>
<blockquote type="cite" class="">
<div class="">On Dec 7, 2015, at 2:58 PM, <a href="mailto:krzysztof@siejkowski.net" class="">krzysztof@siejkowski.net</a> via swift-evolution <<a href="mailto:swift-evolution@swift.org" class="">swift-evolution@swift.org</a>> wrote:</div>
<br class="Apple-interchange-newline">
<div class="">
<div id="bloop_customfont" style="font-family: Helvetica, Arial; font-size: 13px; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; orphans: auto; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: auto; word-spacing: 0px; -webkit-text-stroke-width: 0px; margin: 0px;" class="">Hi,</div>
<div style="font-family: Helvetica, Arial; font-size: 13px; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; orphans: auto; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: auto; word-spacing: 0px; -webkit-text-stroke-width: 0px;" class=""><br class=""></div>
<div style="font-family: Helvetica, Arial; font-size: 13px; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; orphans: auto; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: auto; word-spacing: 0px; -webkit-text-stroke-width: 0px;" class=""><br class=""></div>
<div style="font-family: Helvetica, Arial; font-size: 13px; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; orphans: auto; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: auto; word-spacing: 0px; -webkit-text-stroke-width: 0px;" class=""># Introduction</div>
<br style="font-family: Helvetica, Arial; font-size: 13px; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; orphans: auto; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: auto; word-spacing: 0px; -webkit-text-stroke-width: 0px;" class="">
<div class="bloop_sign" id="bloop_sign_1449521438123563008" style="font-family: Helvetica, Arial; font-size: 13px; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; orphans: auto; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: auto; word-spacing: 0px; -webkit-text-stroke-width: 0px;">
<div class="bloop_sign" id="bloop_sign_1449521438123563008">I'd
like to propose a non-invasive way of extending the funtionality of
`if let` conditional binding (and potencially other
Optional-related language constructs) by introducing
`CustomOptionalConvertible` protocol. The idea is basically the
same as with `CustomStringConvertible` protocol used to provide
string interpolation or with `~=` operator used in `switch`
statement pattern matching. I believe it's going to simplity
and unify the use of the Optional-related family of Swift syntax
constructs for custom types.</div>
<div class="bloop_sign" id="bloop_sign_1449521438123563008">
<br class=""></div>
<div class="bloop_sign" id="bloop_sign_1449521438123563008">The
proposal is in a draft stage right now, I'll clear it up if it
proves worth to be pull-requested.</div>
<div class="bloop_sign" id="bloop_sign_1449521438123563008">
<br class=""></div>
<div class="bloop_sign" id="bloop_sign_1449521438123563008">
<br class=""></div>
<div class="bloop_sign" id="bloop_sign_1449521438123563008">#
Motivation</div>
<div class="bloop_sign" id="bloop_sign_1449521438123563008">
<br class=""></div>
<div class="bloop_sign" id="bloop_sign_1449521438123563008">One of
the Swift features that are core to it's safety and readability are
Optionals. They're important enough to be given special place in
the language syntax. Special operators like `?`, `!` or `??`,
special casting keywords like `as?`, special conditional binding
`if let`. The Optionals, however, might be also seen as a member of
larger family of constructs: call them monads, boxes, value
containers, computational context bearers. One example of those
would be a very similar type going by the name of Either, Try
or Result. It can be seen as an Optional that carries some
additional information about the reason why the value is absent.
That information is not always of our interest and in those cases
conditional binding for Either type makes a lot of sense.
However, the `if let` syntax is currently exclusively working only
for optionals.</div>
<div class="bloop_sign" id="bloop_sign_1449521438123563008">
<br class=""></div>
<div class="bloop_sign" id="bloop_sign_1449521438123563008">
<br class=""></div>
<div class="bloop_sign" id="bloop_sign_1449521438123563008">#
Proposed solution</div>
<div class="bloop_sign" id="bloop_sign_1449521438123563008">
<br class=""></div>
<div class="bloop_sign" id="bloop_sign_1449521438123563008">While
I'd love to see Swift introducing a powerful construct similar to
Haskell's `do-notation` or Scala's `for-comprehension`, I believe
it'd require a significant invasive change in the language
implementation (and, possibly, vision). Therefore the proposed
solutions is much more humble. Let's introduce the
`CustomOptionalConvertible` protocol with signature:</div>
<div class="bloop_sign" id="bloop_sign_1449521438123563008">
<br class=""></div>
<div class="bloop_sign" id="bloop_sign_1449521438123563008">
```</div>
<div class="bloop_sign" id="bloop_sign_1449521438123563008">
protocol CustomOptionalConvertible {</div>
<div class="bloop_sign" id="bloop_sign_1449521438123563008">
typealias Wrapped</div>
<div class="bloop_sign" id="bloop_sign_1449521438123563008">public
var optional: Optional<Wrapped> { get }</div>
<div class="bloop_sign" id="bloop_sign_1449521438123563008">}</div>
<div class="bloop_sign" id="bloop_sign_1449521438123563008">
```</div>
<div class="bloop_sign" id="bloop_sign_1449521438123563008">
<br class=""></div>
<div class="bloop_sign" id="bloop_sign_1449521438123563008">Such a
protocol will provide a way for an arbitrary type to convert to the
Optional. All the types implementing this protocol could then be
used in conditional binding syntax without explicit declaration of
conversion. I do not propose the introduction of general implicit
conversion construct, just a special case. The same as
`CustomStringConvertible` is a special case of allowing the value
to express itself in the string
interpolation.`CustomOptionalConvertible` will allow the author of
an arbitratry type to integrate with Swift syntax:</div>
<div class="bloop_sign" id="bloop_sign_1449521438123563008">
<br class=""></div>
<div class="bloop_sign" id="bloop_sign_1449521438123563008">
```</div>
<div class="bloop_sign" id="bloop_sign_1449521438123563008">enum
Either<Value> {</div>
<div class="bloop_sign" id="bloop_sign_1449521438123563008">case
Left(ErrorType)</div>
<div class="bloop_sign" id="bloop_sign_1449521438123563008">case
Right(Value)</div>
<div class="bloop_sign" id="bloop_sign_1449521438123563008">}</div>
<div class="bloop_sign" id="bloop_sign_1449521438123563008">
<br class=""></div>
<div class="bloop_sign" id="bloop_sign_1449521438123563008">
extension Either : CustomOptionalConvertible {</div>
<div class="bloop_sign" id="bloop_sign_1449521438123563008">
typealias Wrapped = Value</div>
<div class="bloop_sign" id="bloop_sign_1449521438123563008">public
var optional: Optional<Value> {</div>
<div class="bloop_sign" id="bloop_sign_1449521438123563008">get
{</div>
<div class="bloop_sign" id="bloop_sign_1449521438123563008">switch
(self) {</div>
<div class="bloop_sign" id="bloop_sign_1449521438123563008">case
.Left(_): return .None</div>
<div class="bloop_sign" id="bloop_sign_1449521438123563008">case
.Right(let value): return .Some(value)</div>
<div class="bloop_sign" id="bloop_sign_1449521438123563008">}</div>
<div class="bloop_sign" id="bloop_sign_1449521438123563008">}</div>
<div class="bloop_sign" id="bloop_sign_1449521438123563008">
} </div>
<div class="bloop_sign" id="bloop_sign_1449521438123563008">}</div>
<div class="bloop_sign" id="bloop_sign_1449521438123563008">
<br class=""></div>
<div class="bloop_sign" id="bloop_sign_1449521438123563008">func
foo(either: Either<String>) -> String {</div>
<div class="bloop_sign" id="bloop_sign_1449521438123563008">if let
string = either {</div>
<div class="bloop_sign" id="bloop_sign_1449521438123563008">return
string</div>
<div class="bloop_sign" id="bloop_sign_1449521438123563008">} else
{</div>
<div class="bloop_sign" id="bloop_sign_1449521438123563008">return
"No value"</div>
<div class="bloop_sign" id="bloop_sign_1449521438123563008">}</div>
<div class="bloop_sign" id="bloop_sign_1449521438123563008">}</div>
<div class="bloop_sign" id="bloop_sign_1449521438123563008">
```</div>
<div class="bloop_sign" id="bloop_sign_1449521438123563008">
<br class=""></div>
<div class="bloop_sign" id="bloop_sign_1449521438123563008">There
is already a similar mechanism available in the context of pattern
matching: `~=` operator.</div>
<div class="bloop_sign" id="bloop_sign_1449521438123563008">
<br class=""></div>
<div class="bloop_sign" id="bloop_sign_1449521438123563008">
<br class=""></div>
<div class="bloop_sign" id="bloop_sign_1449521438123563008">#
Impact on the language</div>
<div class="bloop_sign" id="bloop_sign_1449521438123563008">
<br class=""></div>
<div class="bloop_sign" id="bloop_sign_1449521438123563008">While I
cannot say much about the impact on the compiler, I believe the
introduction will bring no breaking change to the Swift language
itself. All the places that are currently requiring Optionals will
still require Optionals. </div>
<div class="bloop_sign" id="bloop_sign_1449521438123563008">
<br class=""></div>
<div class="bloop_sign" id="bloop_sign_1449521438123563008">For the
language users it'll make it easier to integrate the constructs
used in the program with the native syntax, making them easier to
use and read. Current solution, namely:</div>
<div class="bloop_sign" id="bloop_sign_1449521438123563008">
```</div>
<div class="bloop_sign" id="bloop_sign_1449521438123563008">func
foo(either: Either<String>) -> String {</div>
<div class="bloop_sign" id="bloop_sign_1449521438123563008">if let
string = either.optional {</div>
<div class="bloop_sign" id="bloop_sign_1449521438123563008">return
string</div>
<div class="bloop_sign" id="bloop_sign_1449521438123563008">} else
{</div>
<div class="bloop_sign" id="bloop_sign_1449521438123563008">return
"No value"</div>
<div class="bloop_sign" id="bloop_sign_1449521438123563008">}</div>
<div class="bloop_sign" id="bloop_sign_1449521438123563008">}</div>
<div class="bloop_sign" id="bloop_sign_1449521438123563008">
```</div>
<div class="bloop_sign" id="bloop_sign_1449521438123563008">is
introducing unnecessary noise in the otherwise neat syntax. The
problem escalates when `if let` cascade is used:</div>
<div class="bloop_sign" id="bloop_sign_1449521438123563008">
```</div>
<div class="bloop_sign" id="bloop_sign_1449521438123563008">if let
string = eitherString.optional</div>
<div class="bloop_sign" id="bloop_sign_1449521438123563008">
int = eitherInt.optional</div>
<div class="bloop_sign" id="bloop_sign_1449521438123563008">
array =
eitherArray.optional </div>
<div class="bloop_sign" id="bloop_sign_1449521438123563008">//
...</div>
<div class="bloop_sign" id="bloop_sign_1449521438123563008">
```</div>
<div class="bloop_sign" id="bloop_sign_1449521438123563008">
<br class=""></div>
<div class="bloop_sign" id="bloop_sign_1449521438123563008">
<br class=""></div>
<div class="bloop_sign" id="bloop_sign_1449521438123563008">#
Alternatives considered</div>
<div class="bloop_sign" id="bloop_sign_1449521438123563008">
<br class=""></div>
<div class="bloop_sign" id="bloop_sign_1449521438123563008">The
equivalent of Haskell’s `do-notation`. It’s a powerful construct
(some say even too powerful, see<span class="Apple-converted-space"> </span><a href="https://wiki.haskell.org/Do_notation_considered_harmful" class="">https://wiki.haskell.org/Do_notation_considered_harmful</a>).
However, I can’t imagine it without significant changes to the
language syntax (`if let` should return value) and vision (I
believe that Optional are syntactic unicorns by design).</div>
<div class="bloop_sign" id="bloop_sign_1449521438123563008">
<br class=""></div>
<div class="bloop_sign" id="bloop_sign_1449521438123563008">
<br class=""></div>
<div class="bloop_sign" id="bloop_sign_1449521438123563008">All the
best,</div>
<div class="bloop_sign" id="bloop_sign_1449521438123563008">
Krzysztof</div>
</div>
<img src="https://u2002410.ct.sendgrid.net/wf/open?upn=zCg-2FSGF9Wk188a6c55kLyEbrj7YhaXxFEHM-2F-2B0YAlzU-2BBDVSWsUj77HUiysJMlegociHziwkchzr3djG7Cvd34cz39J-2FoOuyeJgJifP-2FROeFPzq5Ju599lDgCR-2BUHLO-2B4j2A7XXl4K6utMHQqOZQe-2Bw5bJWIuwLSXmsjwgLHCAuJM435R2-2FaOg9Y-2BGKuXDQvR114mwwogi9AH8pZEoEEKvMx6-2BTeOPI4ufY-2F777fBGY-3D" alt="" width="1" height="1" border="0" style="font-family: Helvetica, Arial; font-size: 13px; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; orphans: auto; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: auto; word-spacing: 0px; -webkit-text-stroke-width: 0px; height: 1px !important; width: 1px !important; border-width: 0px !important; margin: 0px !important; padding: 0px !important;" class=""><span style="font-family: Helvetica, Arial; font-size: 13px; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; orphans: auto; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: auto; word-spacing: 0px; -webkit-text-stroke-width: 0px; float: none; display: inline !important;" class=""><span class="Apple-converted-space"> </span>_______________________________________________</span><br style="font-family: Helvetica, Arial; font-size: 13px; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; orphans: auto; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: auto; word-spacing: 0px; -webkit-text-stroke-width: 0px;" class="">
<span style="font-family: Helvetica, Arial; font-size: 13px; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; orphans: auto; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: auto; word-spacing: 0px; -webkit-text-stroke-width: 0px; float: none; display: inline !important;" class="">swift-evolution mailing list</span><br style="font-family: Helvetica, Arial; font-size: 13px; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; orphans: auto; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: auto; word-spacing: 0px; -webkit-text-stroke-width: 0px;" class="">
<a href="mailto:swift-evolution@swift.org" style="font-family: Helvetica, Arial; font-size: 13px; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; orphans: auto; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: auto; word-spacing: 0px; -webkit-text-stroke-width: 0px;" class="">swift-evolution@swift.org</a><br style="font-family: Helvetica, Arial; font-size: 13px; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; orphans: auto; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: auto; word-spacing: 0px; -webkit-text-stroke-width: 0px;" class="">
<a href="https://lists.swift.org/mailman/listinfo/swift-evolution" style="font-family: Helvetica, Arial; font-size: 13px; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; orphans: auto; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: auto; word-spacing: 0px; -webkit-text-stroke-width: 0px;" class="">https://lists.swift.org/mailman/listinfo/swift-evolution</a></div>
</blockquote>
</div>
<br class="">
<img src="https://u2002410.ct.sendgrid.net/wf/open?upn=eLFMrKDT8iBxZ-2Fbnk-2BZqvSchNN-2FvYXdceA0T7VxwkAcTTkWTKZFebFi9IikZz4aX0X-2F53Gh-2FFcvtxr-2FFNGvLVaLJeFU7xxsBIKft0Eg3Oq7jHAo-2F3bRCklW0bp26bAPzW8FecUA7MQ4RAgx931URSFf-2BrxuaJL1YGyVessBP5raBaCKfh2BdXedQBXN-2FdN6lFplRQ5EqT6UQMcBRjoelrxfRxYrLcs54vkmy6KFLETQ-3D" alt="" width="1" height="1" border="0" style="height:1px !important;width:1px !important;border-width:0 !important;margin-top:0 !important;margin-bottom:0 !important;margin-right:0 !important;margin-left:0 !important;padding-top:0 !important;padding-bottom:0 !important;padding-right:0 !important;padding-left:0 !important;">
</div>
</blockquote>
<blockquote type="cite">
<div>
<span>_______________________________________________</span><br>
<span>swift-evolution mailing list</span><br>
<span><a href="mailto:swift-evolution@swift.org">swift-evolution@swift.org</a></span><br>
<span><a href="https://lists.swift.org/mailman/listinfo/swift-evolution">https://lists.swift.org/mailman/listinfo/swift-evolution</a></span><br>
</div>
</blockquote>
</div></div></span></blockquote></body></html>