<html><head><meta http-equiv="Content-Type" content="text/html charset=utf-8"></head><body style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space;" class="">Interesting stuff indeed!<div class=""><br class=""><div><blockquote type="cite" class=""><div class="">Am 10.12.2015 um 19:21 schrieb Al Skipp &lt;<a href="mailto:al_skipp@fastmail.fm" class="">al_skipp@fastmail.fm</a>&gt;:</div><br class="Apple-interchange-newline"><div class=""><meta http-equiv="Content-Type" content="text/html charset=utf-8" class=""><div style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space;" class=""><div class="">Interesting stuff!</div><div class=""><br class=""></div><div class="">It did confuse me too, as I was expecting your initial code sample to work. My understanding is that ‘?’ is syntactic sugar for ‘map’ in this context. Anything following the ‘?’ is inside the Optional context.</div></div></div></blockquote><div><br class=""></div><div>That is a great insight! Of course, ?. is map! That does make sense! And using parentheses to mark the end of the Optional context introduced by ?. makes sense, too.</div><div><br class=""></div><div>Thanks, Greg and Al!</div><div><br class=""></div><div>-Thorsten</div><div>&nbsp;</div><div><br class=""></div><blockquote type="cite" class=""><div class=""><div style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space;" class=""><div class=""><br class=""></div><div class="">Here is a comparison between ‘map’ and optional chaining (with and without parentheses).</div><div class=""><br class=""></div><div class=""><div class="">let type1 = peeps[0].pet.map { $0.age }.dynamicType // Optional&lt;Int&gt;.Type</div><div class="">let type2 = peeps[0].pet.map { $0.age.dynamicType } // Int.Type</div><div class=""><br class=""></div></div><div class=""><div class="">(peeps[0].pet?.age).dynamicType // Optional&lt;Int&gt;.Type</div><div class="">peeps[0].pet?.age.dynamicType // Int.Type</div></div><div class=""><br class=""></div><div class=""><br class=""></div><div class=""><blockquote type="cite" class=""><div class="">On 10 Dec 2015, at 18:01, Greg Titus &lt;<a href="mailto:greg@omnigroup.com" class="">greg@omnigroup.com</a>&gt; wrote:</div><br class="Apple-interchange-newline"><div class=""><blockquote type="cite" class="" style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; line-height: 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=""><br class="Apple-interchange-newline">On Dec 10, 2015, at 9:30 AM, thorsten--- via swift-evolution &lt;<a href="mailto:swift-evolution@swift.org" class="">swift-evolution@swift.org</a>&gt; wrote:</div><br class="Apple-interchange-newline"><div class=""><div class="" style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space;"><blockquote type="cite" class=""><div class="" style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space;"><div class=""><blockquote type="cite" class=""><div class=""><div dir="auto" class=""><div class=""><div class=""><div class=""><font class=""><span class="" style="background-color: rgba(255, 255, 255, 0);">let ps = peeps.filter { $0.pet?.age.map { age in age &lt; 6 } ?? false }</span></font></div></div></div></div></div></blockquote></div></div></blockquote><div class=""><div class="" style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space;"><div class=""><blockquote type="cite" class=""><div class=""><div dir="auto" class=""><div class=""><div class=""><div class=""><br class=""></div></div></div></div></div></blockquote></div></div></div><div class=""><blockquote type="cite" class=""><div class=""><div class="" style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space;"><div class="">It’s curious that your example won’t compile (didn’t when I tried it in a Playground)</div></div></div></blockquote><div class=""><br class=""></div>You are right, the example does not compile (wrote it in the train far away from Xcode). It gives an error of „value of type ‚Int‘ has no member ‚map‘“.</div><div class=""><br class=""></div><div class="">Hmm, I consider that as a bug in the definition of optional chaining, as the documentation clearly states&nbsp;</div><div class="">"Optional chaining&nbsp;is a process for querying and calling properties, methods, and subscripts on an optional that might currently be&nbsp;nil. If the&nbsp;optional contains a value, the property, method, or subscript call succeeds;<span class="Apple-converted-space">&nbsp;</span><b class="">if the optional is&nbsp;nil, the property, method, or subscript call returns&nbsp;nil.</b>“ (note the last sentence).</div><div class=""><br class=""></div><div class="">So if $0.pet?.age should return nil in case of $0.pet being nil, the type of $0.pet?.age has to be Int? and therefore understand map().<br class=""><br class=""><div class="" style="margin: 0px; font-size: 13px; line-height: normal; color: rgb(211, 54, 130);"><font face="Menlo" class="">peeps</font><span class="" style="font-family: Menlo; color: rgb(131, 148, 150);">[</span><span class="" style="font-family: Menlo; color: rgb(41, 161, 152);">0</span><span class="" style="font-family: Menlo; color: rgb(131, 148, 150);">].</span><font face="Menlo" class="">pet</font><span class="" style="font-family: Menlo; color: rgb(131, 148, 150);">?.</span><font face="Menlo" class="">age</font><span class="" style="font-family: Menlo; color: rgb(131, 148, 150);">.</span><span class="" style="font-family: Menlo; color: rgb(133, 153, 1);">dynamicType &nbsp; &nbsp; &nbsp;</span><span class="" style="color: rgb(88, 110, 117);">// =&gt; Int.Type this is wrong!! Should be Optional&lt;Int&gt;.Type</span></div><div class="" style="margin: 0px; font-size: 13px; line-height: normal; color: rgb(211, 54, 130);"><div class="" style="margin: 0px; line-height: normal; color: rgb(131, 148, 150);"><span class="" style="font-family: Menlo; color: rgb(133, 153, 1);">let</span><font face="Menlo" class=""><span class="Apple-converted-space">&nbsp;</span>y:<span class="Apple-converted-space">&nbsp;</span></font><span class="" style="font-family: Menlo; color: rgb(181, 137, 1);">Int</span><font face="Menlo" class=""><span class="Apple-converted-space">&nbsp;</span>=<span class="Apple-converted-space">&nbsp;</span></font><span class="" style="font-family: Menlo; color: rgb(211, 54, 130);">peeps</span><font face="Menlo" class="">[</font><span class="" style="font-family: Menlo; color: rgb(41, 161, 152);">1</span><font face="Menlo" class="">].pet?.age</font><span class="" style="font-family: Menlo; color: rgb(211, 54, 130);">&nbsp; &nbsp; &nbsp;</span><span class="" style="color: rgb(88, 110, 117);">// This gives a type error which is right (but inconsistent with the dynamicType just claimed)</span></div></div><div class="" style="margin: 0px; line-height: normal; min-height: 15px;"><span class="" style="color: rgb(133, 153, 1); font-size: 13px; font-family: Menlo;">let</span><font face="Menlo" class="" style="color: rgb(131, 148, 150); font-size: 13px;"><span class="Apple-converted-space">&nbsp;</span>x =<span class="Apple-converted-space">&nbsp;</span></font><span class="" style="color: rgb(211, 54, 130); font-size: 13px; font-family: Menlo;">peeps</span><font face="Menlo" class="" style="color: rgb(131, 148, 150); font-size: 13px;">[</font><span class="" style="color: rgb(41, 161, 152); font-size: 13px; font-family: Menlo;">1</span><font face="Menlo" class="" style="color: rgb(131, 148, 150); font-size: 13px;">].</font><span class="" style="color: rgb(211, 54, 130); font-size: 13px; font-family: Menlo;">pet</span><font face="Menlo" class="" style="color: rgb(131, 148, 150); font-size: 13px;">?.</font><span class="" style="color: rgb(211, 54, 130); font-size: 13px; font-family: Menlo;">age &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;</span><font color="#586e75" size="2" class="">// Now let’s see what the type is after assigning the expression</font></div><div class="" style="margin: 0px; font-size: 13px; line-height: normal; color: rgb(133, 153, 1);"><span class="" style="font-family: Menlo; color: rgb(211, 54, 130);">x</span><span class="" style="font-family: Menlo; color: rgb(131, 148, 150);">.</span><font face="Menlo" class="">dynamicType &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;</font><span class="" style="color: rgb(88, 110, 117);">// =&gt;</span><span class="" style="color: rgb(88, 110, 117);">&nbsp;Optional&lt;Int&gt;.Type as expected</span></div><div class=""><div class="" style="margin: 0px; font-size: 13px; line-height: normal; color: rgb(131, 148, 150);"><span class="" style="font-family: Menlo; color: rgb(211, 54, 130);">x</span><font face="Menlo" class="">.</font><span class="" style="font-family: Menlo; color: rgb(108, 113, 196);">map</span><font face="Menlo" class=""><span class="Apple-converted-space">&nbsp;</span>{ age<span class="Apple-converted-space">&nbsp;</span></font><span class="" style="font-family: Menlo; color: rgb(133, 153, 1);">in</span><font face="Menlo" class=""><span class="Apple-converted-space">&nbsp;</span>age &lt;<span class="Apple-converted-space">&nbsp;</span></font><span class="" style="font-family: Menlo; color: rgb(41, 161, 152);">6</span><font face="Menlo" class=""><span class="Apple-converted-space">&nbsp;</span>} ??<span class="Apple-converted-space">&nbsp;</span></font><span class="" style="font-family: Menlo; color: rgb(133, 153, 1);">false &nbsp;</span><span class="" style="color: rgb(88, 110, 117);">// =&gt;</span><span class="" style="color: rgb(88, 110, 117);">&nbsp;false as expected</span></div></div><div class="" style="margin: 0px; font-size: 13px; line-height: normal; font-family: Menlo; color: rgb(131, 148, 150);"><span class="" style="color: rgb(88, 110, 117);"><br class=""></span></div><div class="">So, obviously a bug in the compiler.</div><div class=""><br class=""></div></div></div></div></blockquote><br class="" style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; line-height: 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;"><span style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; line-height: 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="">This works:&nbsp;</span><br class="" style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; line-height: 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;"><br class="" style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; line-height: 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;"><span style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; line-height: 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="">let ps = peeps.filter { ($0.pet?.age).map { age in age &lt; 6 } ?? false }</span><br class="" style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; line-height: 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;"><br class="" style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; line-height: 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;"><span style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; line-height: 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="">Essentially the “?.” operator unwraps the optional, and any further “.” in the chain get applied with the non-optional types as long as the results are non-nil. In order to get an optional result again, you need to break the “.” chain, as with the parens in this case.</span><br class="" style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; line-height: 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;"><br class="" style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; line-height: 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;"><span style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; line-height: 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="">I’m not sure: is this actually a compiler bug, and the type constraint system ought to consider binding to members of “T?" as well as “T" at each further “.”, or is this an expected (but obscure) part of the language, in which case the bug is maybe just that if no members match for “T" the error could suggest this paren fix if there is a member match for “T?”?</span><br class="" style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; line-height: 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;"><br class="" style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; line-height: 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;"><span class="Apple-tab-span" style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; line-height: normal; orphans: auto; text-align: start; text-indent: 0px; text-transform: none; white-space: pre; widows: auto; word-spacing: 0px; -webkit-text-stroke-width: 0px;">        </span><span style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; line-height: 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="">- Greg</span></div></blockquote></div><br class=""></div></div></blockquote></div><br class=""></div></body></html>