<div dir="ltr"><p style="margin-top:0px;margin-bottom:16px;color:rgb(51,51,51);font-family:'Helvetica Neue',Helvetica,'Segoe UI',Arial,freesans,sans-serif,'Apple Color Emoji','Segoe UI Emoji','Segoe UI Symbol';font-size:16px;line-height:25.6px">I think it would be great if <code style="font-family:Consolas,'Liberation Mono',Menlo,Courier,monospace;font-size:13.6px;padding:0.2em 0px;margin:0px;border-radius:3px;background-color:rgba(0,0,0,0.0392157)">throws -> Foo</code> were a syntactic sugar of <code style="font-family:Consolas,'Liberation Mono',Menlo,Courier,monospace;font-size:13.6px;padding:0.2em 0px;margin:0px;border-radius:3px;background-color:rgba(0,0,0,0.0392157)">-> Result<Foo></code>. Without affecting existing codes, it makes it possible to go back and forth between <em>Manual Propagation</em> and <em>Automatic Propagation</em> seamlessly.</p><div class="" style="margin-bottom:16px;color:rgb(51,51,51);font-family:'Helvetica Neue',Helvetica,'Segoe UI',Arial,freesans,sans-serif,'Apple Color Emoji','Segoe UI Emoji','Segoe UI Symbol';font-size:16px;line-height:25.6px"><pre style="overflow:auto;font-family:Consolas,'Liberation Mono',Menlo,Courier,monospace;font-size:13.6px;margin-top:0px;margin-bottom:0px;font-stretch:normal;line-height:1.45;padding:16px;border-radius:3px;word-wrap:normal;background-color:rgb(247,247,247)"><span class="" style="color:rgb(150,152,150)">// I wish if the first `makeFoo` were</span>
<span class="" style="color:rgb(150,152,150)">// a syntactic sugar of the second one</span>
<span class="" style="color:rgb(167,29,93)">func</span> <span class="" style="color:rgb(121,93,163)">makeFoo</span>(x: <span class="" style="color:rgb(0,134,179)">Int</span>) throws <span class="" style="color:rgb(167,29,93)">-></span> Foo {
<span class="" style="color:rgb(167,29,93)">guard</span> <span class="" style="color:rgb(167,29,93)">...</span> <span class="" style="color:rgb(167,29,93)">else</span> {
<span class="" style="color:rgb(167,29,93)">throw</span> FooError()
}
<span class="" style="color:rgb(167,29,93)">return</span> Foo(x)
}
<span class="" style="color:rgb(150,152,150)">// @warn_unused_result</span>
<span class="" style="color:rgb(150,152,150)">// func makeFoo(x: Int) -> Result<Foo> {</span>
<span class="" style="color:rgb(150,152,150)">// guard ... else {</span>
<span class="" style="color:rgb(150,152,150)">// return Result(error: FooError())</span>
<span class="" style="color:rgb(150,152,150)">// }</span>
<span class="" style="color:rgb(150,152,150)">// return Result(Foo(x))</span>
<span class="" style="color:rgb(150,152,150)">// }</span>
<span class="" style="color:rgb(150,152,150)">// Manual propagation</span>
<span class="" style="color:rgb(167,29,93)">let</span> result: Result<span class="" style="color:rgb(167,29,93)"><</span>Foo<span class="" style="color:rgb(167,29,93)">></span> <span class="" style="color:rgb(167,29,93)">=</span> makeFoo(<span class="" style="color:rgb(0,134,179)">42</span>) <span class="" style="color:rgb(150,152,150)">// without `try`</span>
<span class="" style="color:rgb(167,29,93)">switch</span> result {
<span class="" style="color:rgb(167,29,93)">case</span> <span class="" style="color:rgb(167,29,93)">let</span> <span class="" style="color:rgb(167,29,93)">.</span>Success(foo):
<span class="" style="color:rgb(167,29,93)">...</span>
<span class="" style="color:rgb(167,29,93)">case</span> <span class="" style="color:rgb(167,29,93)">let</span> <span class="" style="color:rgb(167,29,93)">.</span>Failure(error):
<span class="" style="color:rgb(167,29,93)">...</span>
}
<span class="" style="color:rgb(150,152,150)">// Automatic propagation</span>
<span class="" style="color:rgb(167,29,93)">do</span> {
<span class="" style="color:rgb(167,29,93)">let</span> foo: Foo <span class="" style="color:rgb(167,29,93)">=</span> <span class="" style="color:rgb(167,29,93)">try</span> makeFoo(<span class="" style="color:rgb(0,134,179)">42</span>) <span class="" style="color:rgb(150,152,150)">// with `try`: a kind of unwrapping</span>
<span class="" style="color:rgb(167,29,93)">...</span>
} <span class="" style="color:rgb(167,29,93)">catch</span> <span class="" style="color:rgb(167,29,93)">let</span> error {
<span class="" style="color:rgb(167,29,93)">...</span>
}</pre></div><h2 style="margin-top:1em;margin-bottom:16px;line-height:1.225;font-size:1.75em;padding-bottom:0.3em;border-bottom-width:1px;border-bottom-style:solid;border-bottom-color:rgb(238,238,238);color:rgb(51,51,51);font-family:'Helvetica Neue',Helvetica,'Segoe UI',Arial,freesans,sans-serif,'Apple Color Emoji','Segoe UI Emoji','Segoe UI Symbol'"><a id="user-content-for-what" class="" href="https://gist.github.com/koher/e6a8b128bd7ad6898ac9#for-what" style="color:rgb(64,120,192);text-decoration:none;display:inline-block;padding-right:2px;line-height:1;background-color:transparent"></a>For what?</h2><p style="margin-top:0px;margin-bottom:16px;color:rgb(51,51,51);font-family:'Helvetica Neue',Helvetica,'Segoe UI',Arial,freesans,sans-serif,'Apple Color Emoji','Segoe UI Emoji','Segoe UI Symbol';font-size:16px;line-height:25.6px">I want to unify <code style="font-family:Consolas,'Liberation Mono',Menlo,Courier,monospace;font-size:13.6px;padding:0.2em 0px;margin:0px;border-radius:3px;background-color:rgba(0,0,0,0.0392157)">throws</code> and <code style="font-family:Consolas,'Liberation Mono',Menlo,Courier,monospace;font-size:13.6px;padding:0.2em 0px;margin:0px;border-radius:3px;background-color:rgba(0,0,0,0.0392157)">Result</code> into one feature to keep the language simple.</p><p style="margin-top:0px;margin-bottom:16px;color:rgb(51,51,51);font-family:'Helvetica Neue',Helvetica,'Segoe UI',Arial,freesans,sans-serif,'Apple Color Emoji','Segoe UI Emoji','Segoe UI Symbol';font-size:16px;line-height:25.6px">As referred in <a href="https://github.com/apple/swift/blob/master/docs/ErrorHandlingRationale.rst#automatic-propagation" style="color:rgb(64,120,192);text-decoration:none;background-color:transparent">"Error Handling Rationale and Proposal"</a>, I think Swift should provide something like <code style="font-family:Consolas,'Liberation Mono',Menlo,Courier,monospace;font-size:13.6px;padding:0.2em 0px;margin:0px;border-radius:3px;background-color:rgba(0,0,0,0.0392157)">Result</code>. It means we would have similar two features: <code style="font-family:Consolas,'Liberation Mono',Menlo,Courier,monospace;font-size:13.6px;padding:0.2em 0px;margin:0px;border-radius:3px;background-color:rgba(0,0,0,0.0392157)">throws</code> and <code style="font-family:Consolas,'Liberation Mono',Menlo,Courier,monospace;font-size:13.6px;padding:0.2em 0px;margin:0px;border-radius:3px;background-color:rgba(0,0,0,0.0392157)">Result</code>. We need a way to covert them to each other. For examples, it can be done in the following way.</p><div class="" style="margin-bottom:16px;color:rgb(51,51,51);font-family:'Helvetica Neue',Helvetica,'Segoe UI',Arial,freesans,sans-serif,'Apple Color Emoji','Segoe UI Emoji','Segoe UI Symbol';font-size:16px;line-height:25.6px"><pre style="overflow:auto;font-family:Consolas,'Liberation Mono',Menlo,Courier,monospace;font-size:13.6px;margin-top:0px;margin-bottom:0px;font-stretch:normal;line-height:1.45;padding:16px;border-radius:3px;word-wrap:normal;background-color:rgb(247,247,247)"><span class="" style="color:rgb(150,152,150)">// What I DON'T want</span>
<span class="" style="color:rgb(167,29,93)">func</span> <span class="" style="color:rgb(121,93,163)">makeFoo</span>(x: <span class="" style="color:rgb(0,134,179)">Int</span>) throws <span class="" style="color:rgb(167,29,93)">-></span> Foo { <span class="" style="color:rgb(167,29,93)">...</span> } <span class="" style="color:rgb(150,152,150)">// -> Result<Foo></span>
<span class="" style="color:rgb(167,29,93)">let</span> a: Result<span class="" style="color:rgb(167,29,93)"><</span>Foo<span class="" style="color:rgb(167,29,93)">></span> <span class="" style="color:rgb(167,29,93)">=</span> <span class="" style="color:rgb(167,29,93)">try</span><span class="" style="color:rgb(167,29,93)">|</span> makeFoo(<span class="" style="color:rgb(0,134,179)">42</span>)
<span class="" style="color:rgb(150,152,150)">// `try|` for `Result` like `try?` for `Optional`</span>
<span class="" style="color:rgb(167,29,93)">do</span> {
<span class="" style="color:rgb(167,29,93)">let</span> b <span class="" style="color:rgb(167,29,93)">=</span> <span class="" style="color:rgb(167,29,93)">try</span> a<span class="" style="color:rgb(167,29,93)">.</span>throwIfError()
<span class="" style="color:rgb(167,29,93)">...</span>
} <span class="" style="color:rgb(167,29,93)">catch</span> <span class="" style="color:rgb(167,29,93)">let</span> error {
<span class="" style="color:rgb(167,29,93)">...</span>
}</pre></div><p style="margin-top:0px;margin-bottom:16px;color:rgb(51,51,51);font-family:'Helvetica Neue',Helvetica,'Segoe UI',Arial,freesans,sans-serif,'Apple Color Emoji','Segoe UI Emoji','Segoe UI Symbol';font-size:16px;line-height:25.6px">If <code style="font-family:Consolas,'Liberation Mono',Menlo,Courier,monospace;font-size:13.6px;padding:0.2em 0px;margin:0px;border-radius:3px;background-color:rgba(0,0,0,0.0392157)">throws</code> were a syntactic sugar of returning a <code style="font-family:Consolas,'Liberation Mono',Menlo,Courier,monospace;font-size:13.6px;padding:0.2em 0px;margin:0px;border-radius:3px;background-color:rgba(0,0,0,0.0392157)">Result</code>, it would be simpler.</p><div class="" style="margin-bottom:16px;color:rgb(51,51,51);font-family:'Helvetica Neue',Helvetica,'Segoe UI',Arial,freesans,sans-serif,'Apple Color Emoji','Segoe UI Emoji','Segoe UI Symbol';font-size:16px;line-height:25.6px"><pre style="overflow:auto;font-family:Consolas,'Liberation Mono',Menlo,Courier,monospace;font-size:13.6px;margin-top:0px;margin-bottom:0px;font-stretch:normal;line-height:1.45;padding:16px;border-radius:3px;word-wrap:normal;background-color:rgb(247,247,247)"><span class="" style="color:rgb(150,152,150)">// What I want</span>
<span class="" style="color:rgb(167,29,93)">func</span> <span class="" style="color:rgb(121,93,163)">makeFoo</span>(x: <span class="" style="color:rgb(0,134,179)">Int</span>) throws <span class="" style="color:rgb(167,29,93)">-></span> Foo { <span class="" style="color:rgb(167,29,93)">...</span> } <span class="" style="color:rgb(150,152,150)">// -> Result<Foo></span>
<span class="" style="color:rgb(167,29,93)">let</span> a: Result<span class="" style="color:rgb(167,29,93)"><</span>Foo<span class="" style="color:rgb(167,29,93)">></span> <span class="" style="color:rgb(167,29,93)">=</span> makeFoo(<span class="" style="color:rgb(0,134,179)">42</span>)
<span class="" style="color:rgb(167,29,93)">do</span> {
<span class="" style="color:rgb(167,29,93)">let</span> b <span class="" style="color:rgb(167,29,93)">=</span> <span class="" style="color:rgb(167,29,93)">try</span> a
<span class="" style="color:rgb(167,29,93)">...</span>
} <span class="" style="color:rgb(167,29,93)">catch</span> <span class="" style="color:rgb(167,29,93)">let</span> error {
<span class="" style="color:rgb(167,29,93)">...</span>
}</pre></div><p style="margin-top:0px;color:rgb(51,51,51);font-family:'Helvetica Neue',Helvetica,'Segoe UI',Arial,freesans,sans-serif,'Apple Color Emoji','Segoe UI Emoji','Segoe UI Symbol';font-size:16px;line-height:25.6px;margin-bottom:0px!important">In Addition, it prevents that APIs of third-party libraries diverge. If we had similar but different two features, <code style="font-family:Consolas,'Liberation Mono',Menlo,Courier,monospace;font-size:13.6px;padding:0.2em 0px;margin:0px;border-radius:3px;background-color:rgba(0,0,0,0.0392157)">throws</code> and <code style="font-family:Consolas,'Liberation Mono',Menlo,Courier,monospace;font-size:13.6px;padding:0.2em 0px;margin:0px;border-radius:3px;background-color:rgba(0,0,0,0.0392157)">Result</code>, some libraries would use <code style="font-family:Consolas,'Liberation Mono',Menlo,Courier,monospace;font-size:13.6px;padding:0.2em 0px;margin:0px;border-radius:3px;background-color:rgba(0,0,0,0.0392157)">throws</code> and others would use <code style="font-family:Consolas,'Liberation Mono',Menlo,Courier,monospace;font-size:13.6px;padding:0.2em 0px;margin:0px;border-radius:3px;background-color:rgba(0,0,0,0.0392157)">Result</code>. Actually it has already happened. Some popular libraries use <a href="https://github.com/antitypical/Result" style="color:rgb(64,120,192);text-decoration:none;background-color:transparent">antitypical/Result</a> or their own <code style="font-family:Consolas,'Liberation Mono',Menlo,Courier,monospace;font-size:13.6px;padding:0.2em 0px;margin:0px;border-radius:3px;background-color:rgba(0,0,0,0.0392157)">Result</code> types. If <code style="font-family:Consolas,'Liberation Mono',Menlo,Courier,monospace;font-size:13.6px;padding:0.2em 0px;margin:0px;border-radius:3px;background-color:rgba(0,0,0,0.0392157)">throws</code> were a syntactic sugar of returning a <code style="font-family:Consolas,'Liberation Mono',Menlo,Courier,monospace;font-size:13.6px;padding:0.2em 0px;margin:0px;border-radius:3px;background-color:rgba(0,0,0,0.0392157)">Result</code>, using <code style="font-family:Consolas,'Liberation Mono',Menlo,Courier,monospace;font-size:13.6px;padding:0.2em 0px;margin:0px;border-radius:3px;background-color:rgba(0,0,0,0.0392157)">throws</code> or <code style="font-family:Consolas,'Liberation Mono',Menlo,Courier,monospace;font-size:13.6px;padding:0.2em 0px;margin:0px;border-radius:3px;background-color:rgba(0,0,0,0.0392157)">Result</code> would affect only the appearance of codes, and we could use those libraries in the same way.</p><p style="margin-top:0px;color:rgb(51,51,51);font-family:'Helvetica Neue',Helvetica,'Segoe UI',Arial,freesans,sans-serif,'Apple Color Emoji','Segoe UI Emoji','Segoe UI Symbol';font-size:16px;line-height:25.6px;margin-bottom:0px!important"><br></p><p style="margin-top:0px;color:rgb(51,51,51);font-family:'Helvetica Neue',Helvetica,'Segoe UI',Arial,freesans,sans-serif,'Apple Color Emoji','Segoe UI Emoji','Segoe UI Symbol';font-size:16px;line-height:25.6px;margin-bottom:0px!important">-- Yuta</p></div>