<html><head><meta http-equiv="Content-Type" content="text/html; charset=utf-8"></head><body style="word-wrap: break-word; -webkit-nbsp-mode: space; line-break: after-white-space;" 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=""><div class=""><span class="Apple-tab-span" style="white-space:pre">        </span>• What is your evaluation of the proposal?<br class=""></div><div class=""></div></div></div></div></blockquote><div><br class=""></div><div>One thing to keep in mind is that flatMap is basically the equivalent of optional chaining for non-`self` parameters.</div><div><br class=""></div><div><span class="Apple-tab-span" style="white-space:pre">        </span>let result =&nbsp;character?.hexValue // optional chaining</div><div><span class="Apple-tab-span" style="white-space:pre">        </span>let result = character.flatMap { hexValue($0) } // optional "calling"?</div><div><br class=""></div><div>I always found that `flatMap` was a weird name for this. Moreover, if the function you call is not returning an optional, `map` and `flatMap` essentially become synonyms. And thus I find myself using `flatMap` all the time when writing code like this, even when `map` would be enough, simply because it does what I expect all the time (like optional chaining, and unlike `map` that will instead pile up two layers of optionals).</div><div><br class=""></div><div>The name `filterMap` makes a lot of sense for arrays, but it's still a bit awkward for optionals. I think the reason is that the most common thing you'd want to do with an optional is what `flatMap`/`filterMap` does, but the less specialized name (`map`) is already reserved with slightly different semantics. That is a bit dissonant in usage, even though the semantics makes sense in theory.</div><div><br class=""></div><div>I think the most common use case, the one that mirrors optional chaining, should use the simplest name. I'm not sure what that word would be though.</div><div><br class=""></div><div>[[</div><div>Side note: If only there was a nice way to express optional calling (when one of the parameters needs to be unwrapped or the call is skipped) like there is for optional chaining... I dream of this:</div></div><div class=""><br class=""></div><div class=""><span class="Apple-tab-span" style="white-space:pre">        </span>let result = optional hexValue(character?)</div><div class=""><br class=""></div><div class="">where `optional` before an expression enables explicit unwrapping in subexpressions with `?` and any failure to unwrap a subexpression causes the optional expression to return `nil`. But that might be asking for too much sugar.</div><div class="">]]</div><div class=""><br class=""><div class=""><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=""><div class=""><span class="Apple-tab-span" style="white-space:pre">        </span>• Is the problem being addressed significant enough to warrant a change to Swift?<br class=""></div><div class=""></div></div></div></div></blockquote><div><br class=""></div><div><div class=""><div>I actually implemented `Sequence.filterMap` and `Optional.filterMap` in one of my projects and attempted to replace every `flatMap` with it. Looks like most of the `flatMap` calls in my project are used to filter optionals in arrays or doing optional calling. Only a tiny amount had to keep using `flatMap` because they were flattening nested arrays. That leads me to the conclusion that a better name would make most of the code more readable.</div></div></div><div><br class=""></div><div>I think the change is worth it for arrays. Flattening an array is not the same thing as removing parts of it, so the word "filter" adds clarity.</div><div><br class=""></div><div>I'm not sure it adds any clarity for optionals though.</div><div><br class=""></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=""><div class=""><span class="Apple-tab-span" style="white-space:pre">        </span>• Does this proposal fit well with the feel and direction of Swift?<br class=""></div></div></div></div></blockquote><div><br class=""></div><div>I think it fits well for arrays. Not sure about optionals.</div><div><br class=""></div><br class=""><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=""><div class=""><span class="Apple-tab-span" style="white-space:pre">        </span>• If you have used other languages or libraries with a similar feature, how do you feel that this proposal compares to those?<br class=""></div></div></div></div></blockquote><div><br class=""></div><div>N/A</div><div><br class=""></div><br class=""><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=""><div class=""><span class="Apple-tab-span" style="white-space:pre">        </span>• How much effort did you put into your review? A glance, a quick reading, or an in-depth study?</div></div></div></div></blockquote><div><br class=""></div>I implemented filterMap to see what it'd feel like.<br class=""></div></div></div><div><br class=""></div><br class=""><div class="">
<div style="color: rgb(0, 0, 0); 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; word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space;" class=""><div style="color: rgb(0, 0, 0); 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; word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space;" class=""><div style="color: rgb(0, 0, 0); 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; word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space;" class=""><div style="color: rgb(0, 0, 0); font-family: Helvetica; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; line-height: normal; orphans: 2; text-align: -webkit-auto; text-indent: 0px; text-transform: none; white-space: normal; widows: 2; word-spacing: 0px; -webkit-text-stroke-width: 0px; word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space;" class=""><span class="Apple-style-span" style="border-collapse: separate; font-variant-ligatures: normal; font-variant-east-asian: normal; font-variant-position: normal; line-height: normal; border-spacing: 0px;"><div style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space;" class=""><span class="Apple-style-span" style="border-collapse: separate; color: rgb(0, 0, 0); font-family: Helvetica; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; line-height: normal; orphans: 2; text-align: -webkit-auto; text-indent: 0px; text-transform: none; white-space: normal; widows: 2; word-spacing: 0px; border-spacing: 0px; -webkit-text-decorations-in-effect: none; -webkit-text-stroke-width: 0px;"><div style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space;" class=""><span class="Apple-style-span" style="border-collapse: separate; color: rgb(0, 0, 0); font-family: Helvetica; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; line-height: normal; orphans: 2; text-align: -webkit-auto; text-indent: 0px; text-transform: none; white-space: normal; widows: 2; word-spacing: 0px; border-spacing: 0px; -webkit-text-decorations-in-effect: none; -webkit-text-stroke-width: 0px;"><div style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space;" class="">--&nbsp;<br class="">Michel Fortin</div><div style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space;" class=""><span style="text-align: -webkit-auto;" class=""><a href="https://michelf.ca" class="">https://michelf.ca</a></span></div></span></div></span></div></span></div></div></div></div>
</div>
<br class=""></body></html>