<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 class="">Even this small example I think this is still a little fiddly. If we add another required parameter to the Markdown initializer:</div><div class=""><span class="Apple-tab-span" style="white-space:pre">        </span>let readme = String(contentsOfFile: “README.md”).flatMap { Markdown(string: $0, flavor: .github) }</div><div class="">this starts to feel a little inside-out and crufty to me. <br class=""><div><br class=""><blockquote type="cite" class=""><div class="">On 12 Dec 2017, at 05:54, Félix Cloutier <<a href="mailto:felixcloutier@icloud.com" class="">felixcloutier@icloud.com</a>> wrote:</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; line-break: after-white-space;" class="">You talk about flatMap without giving an example. The readme isn't that bad with it, IMO:<br class=""><div class=""><br class=""></div><div class=""><div class="">if let readme = String(contentsOfFile: "README.md").flatMap(Markdown) {</div><div class=""><span class="Apple-tab-span" style="white-space:pre">        </span>// use contents here</div><div class="">}</div><div class=""><br class=""></div><div class="">That doesn't work when you need multiple optional parameters. In my own experience, that hasn't been a huge problem, though.</div><div class=""><br class=""></div><div class="">Félix</div><div class=""><br class=""><blockquote type="cite" class=""><div class="">Le 11 déc. 2017 à 08:30, Jared Khan via swift-evolution <<a href="mailto:swift-evolution@swift.org" class="">swift-evolution@swift.org</a>> a écrit :</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; line-break: after-white-space;" class=""><p class="">Hi all,</p><p class="">I'd like to propose a syntax addition that acts to ease some things that I believe should fall under the umbrella of 'optional chaining'. Optional chaining allows us to access the properties of an optional value and return nil if any link in that chain breaks. I propose we introduce syntax to allow similar chaining when passing optional valued parameters to functions that expect that parameter to be non-optional.</p><p class="">The example below is taken from a project I'm working on at the moment:</p><pre class=""><br class=""></pre><blockquote class="" style="margin: 0px 0px 0px 40px; border: none; padding: 0px;"><pre class=""><code class="">// Current
let readme: Markdown?
if let rawMarkdown = String(contentsOfFile: "README.md") {
        readme = Markdown(string: rawMarkdown)
} else {
        readme = nil
}</code></pre></blockquote><p class="">In this example we want to perform an operation, the initialisation of a 'Markdown' type, with our raw text if it exists and get nil otherwise. This is rather verbose</p><p class="">I propose the following syntax for an alternative:</p><div class=""><br class=""></div><blockquote class="" style="margin: 0px 0px 0px 40px; border: none; padding: 0px;"><pre class=""><code class="">// Proposed alternative
let readme = Markdown(string: String(contentsOfFile: "README.md")?)</code></pre><pre class=""><code class=""><br class=""></code></pre></blockquote><p class="">The <code class="">?</code> is familiar in its use for optional chaining.</p><p class="">This would act like syntactic sugar for the <code class="">flatMap</code> method on <code class="">Optional</code>. For example:</p><div class="">(where `john` is of a `Person` type with a property `address: Address?`)</div><blockquote class="" style="margin: 0px 0px 0px 40px; border: none; padding: 0px;"><pre class=""><code class="">// func getZipCode(fromAddress address: Address) -> ZipCode</code></pre><pre class=""><code class="">getZipCode(fromAddress: john.address?)
// Would be equivalent to…
john.address.flatMap {
        getZipCode($0)
}</code></pre></blockquote><p class="">An example with multiple parameters:</p><blockquote class="" style="margin: 0px 0px 0px 40px; border: none; padding: 0px;"><pre class=""><code class="">// func getPostageEstimate(source: Address, destination: Address, weight: Double) -> Int</code></pre><pre class=""><code class="">getPostageEstimate(source: john.address?, destination: alice.address?, weight: 2.0)
// Equivalent to
john.address.flatMap { freshVar1 in
        alice.address.flatMap { freshVar2 in
                getPostageEstimate(source: freshVar1, destination: freshVar2, weight: 2.0)
        }
}
// Or equally:
{
        guard let freshVar1 = john.address,
                let freshVar2 = alice.address else {
                        return nil
        }
        return getPostageEstimate(source: freshVar1, destination: freshVar2, weight: 2.0)
}()</code></pre></blockquote><p class="">This would only be allowed when the parameter doesn’t already accept Optionals and when the chained value is in fact an optional. We’d want to consider emitting at least the following errors/warnings in the given scenarios:</p><blockquote class="" style="margin: 0px 0px 0px 40px; border: none; padding: 0px;"><pre class=""><code class="">
let result = myFunc(3?)
// error: cannot use optional chaining on non-optional value of type 'Int'
// func myFunc2(x: String?) -> String
let result = myFunc2(x: john.address?)
// error: cannot use optional argument chaining on argument of optional type</code></pre><pre class=""><code class="">let result = myFunc(nil?)
// warning: optional argument chaining with nil literal always results in nil</code></pre><pre class=""><code class=""><br class=""></code></pre></blockquote><p class="">Seeking your thoughts on this idea, the specific syntax, and more use case examples.</p><p class="">Best,</p><p class="">Jared</p></div>_______________________________________________<br class="">swift-evolution mailing list<br class=""><a href="mailto:swift-evolution@swift.org" class="">swift-evolution@swift.org</a><br class=""><a href="https://lists.swift.org/mailman/listinfo/swift-evolution" class="">https://lists.swift.org/mailman/listinfo/swift-evolution</a><br class=""></div></blockquote></div><br class=""></div></div></div></blockquote></div><br class=""></div></body></html>