<div dir="ltr">@Slava,<div><br></div><div>I'm imagining that the compiler does much the same as Anton suggested, e.g. Anton's:<br><br> struct FStore<E: Error> { </div><div> let f: () throws<E> -> Void </div><div> init(_ f: @escaping () throws<E> -> Void) { self.f = f } </div><div> func call() throws<E> { try f() } </div><div> }<br><br>Is much the same as my:<br><br><div> struct FStore { </div><div> let f: () throws -> Void </div><div> init(_ f: @escaping () throws -> Void) { self.f = f } </div><div> func call() throws { try f() } </div><div> }<br><br></div></div><div>From a compiler point of view.</div><div><br></div><div>The idea is that the compiler reuses some of its existing generic's infrastructure. The main differences between my proposal and Anton's is that because mine doesn't use a typed throw, E can only be 'AnyError' (any type that implements Error) or Never, and E is not explicit. The throws/rethrows distinction just becomes a compiler optimization in both cases.</div></div><div class="gmail_extra"><br clear="all"><div><div class="gmail_signature" data-smartmail="gmail_signature"> -- Howard.<br></div></div>
<br><div class="gmail_quote">On 13 January 2017 at 10:42, Slava Pestov <span dir="ltr"><<a href="mailto:spestov@apple.com" target="_blank">spestov@apple.com</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div style="word-wrap:break-word"><br><div><blockquote type="cite"><div>On Jan 11, 2017, at 2:02 PM, Howard Lovatt via swift-evolution <<a href="mailto:swift-evolution@swift.org" target="_blank">swift-evolution@swift.org</a>> wrote:</div><br class="m_-2292996592850934567Apple-interchange-newline"><div><div style="font-family:Helvetica;font-size:12px;font-style:normal;font-variant-caps:normal;font-weight:normal;letter-spacing:normal;text-align:start;text-indent:0px;text-transform:none;white-space:normal;word-spacing:0px"><div>Another possibility, other than generics, would be to drop rethrows all together and have the compiler infer if a throw is possible or not, including:</div></div><div style="font-family:Helvetica;font-size:12px;font-style:normal;font-variant-caps:normal;font-weight:normal;letter-spacing:normal;text-align:start;text-indent:0px;text-transform:none;white-space:normal;word-spacing:0px"><br></div><div style="font-family:Helvetica;font-size:12px;font-style:normal;font-variant-caps:normal;font-weight:normal;letter-spacing:normal;text-align:start;text-indent:0px;text-transform:none;white-space:normal;word-spacing:0px"><div class="m_-2292996592850934567gmail_msg"> struct FStore {</div><div class="m_-2292996592850934567gmail_msg"> let f: () throws -> Void</div><div class="m_-2292996592850934567gmail_msg"> func call() throws { try f() }</div><div class="m_-2292996592850934567gmail_msg"> }</div></div><div class="m_-2292996592850934567gmail_msg" style="font-family:Helvetica;font-size:12px;font-style:normal;font-variant-caps:normal;font-weight:normal;letter-spacing:normal;text-align:start;text-indent:0px;text-transform:none;white-space:normal;word-spacing:0px"><br></div><div class="m_-2292996592850934567gmail_msg" style="font-family:Helvetica;font-size:12px;font-style:normal;font-variant-caps:normal;font-weight:normal;letter-spacing:normal;text-align:start;text-indent:0px;text-transform:none;white-space:normal;word-spacing:0px">The compiler can make two versions, one if f can throw and one if it definitely doesn't. </div></div></blockquote><div><br></div>It seems that this approach is impractical, because you either have to compile two versions of every function, or make all function bodies available for inlining, which is a non-starter for a stable ABI.</div><div><br></div><div>Slava</div><div><br><blockquote type="cite"><div><div class="m_-2292996592850934567gmail_msg" style="font-family:Helvetica;font-size:12px;font-style:normal;font-variant-caps:normal;font-weight:normal;letter-spacing:normal;text-align:start;text-indent:0px;text-transform:none;white-space:normal;word-spacing:0px"><br></div><div class="m_-2292996592850934567gmail_msg" style="font-family:Helvetica;font-size:12px;font-style:normal;font-variant-caps:normal;font-weight:normal;letter-spacing:normal;text-align:start;text-indent:0px;text-transform:none;white-space:normal;word-spacing:0px">Just a thought. </div><div style="font-family:Helvetica;font-size:12px;font-style:normal;font-variant-caps:normal;font-weight:normal;letter-spacing:normal;text-align:start;text-indent:0px;text-transform:none;white-space:normal;word-spacing:0px"><br><div class="gmail_quote"><div>On Tue, 10 Jan 2017 at 4:29 pm, Jacob Bandes-Storch <<a href="mailto:jtbandes@gmail.com" target="_blank">jtbandes@gmail.com</a>> wrote:<br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);border-left-style:solid;padding-left:1ex"><div class="m_-2292996592850934567gmail_msg">Moving to swift-users list.<div class="gmail_extra m_-2292996592850934567gmail_msg"><br clear="all" class="m_-2292996592850934567gmail_msg"><div class="m_-2292996592850934567gmail_msg"><div class="m_-2292996592850934567gmail_msg m_-2292996592850934567m_3804435008049710637m_9079363423569745951gmail_signature" data-smartmail="gmail_signature"><div class="m_-2292996592850934567gmail_msg"><div class="m_-2292996592850934567gmail_msg">No, there's no way to do this today. The point of rethrows is that within one call site, "f(block)" can be treated as throwing if the block throws, or not throwing if the block doesn't throw. In your example, once the FStore object is constructed, the information about the original passed-in function is lost, so the caller has no way to know whether call() can throw or not.</div><div class="m_-2292996592850934567gmail_msg"><br class="m_-2292996592850934567gmail_msg"></div><div class="m_-2292996592850934567gmail_msg">If this *were* possible, the information would somehow need to be encoded in the type system when creating FStore(f: block). That would require something like dependent typing, or generic-param-based-rethrows, e.g.</div><div class="m_-2292996592850934567gmail_msg"><br class="m_-2292996592850934567gmail_msg"></div><div class="m_-2292996592850934567gmail_msg">struct FStore<T: () throws -> Void> { // made-up syntax</div><div class="m_-2292996592850934567gmail_msg"> <span class="m_-2292996592850934567Apple-converted-space"> </span>let f: T</div><div class="m_-2292996592850934567gmail_msg"> <span class="m_-2292996592850934567Apple-converted-space"> </span>func call() rethrows(T) { try f() } // throws-ness of this function depends on throws-ness of T</div><div class="m_-2292996592850934567gmail_msg">}</div></div></div></div><br><br><br class="m_-2292996592850934567gmail_msg"><div class="gmail_quote m_-2292996592850934567gmail_msg"></div></div></div><div class="m_-2292996592850934567gmail_msg"><div class="gmail_extra m_-2292996592850934567gmail_msg"><div class="gmail_quote m_-2292996592850934567gmail_msg">On Mon, Jan 9, 2017 at 9:21 PM, Howard Lovatt via swift-evolution<span class="m_-2292996592850934567Apple-converted-space"> </span><span class="m_-2292996592850934567gmail_msg"><<a href="mailto:swift-evolution@swift.org" class="m_-2292996592850934567gmail_msg" target="_blank">swift-<wbr>evolution@swift.org</a>></span><span class="m_-2292996592850934567Apple-converted-space"> </span>wrote:<br class="m_-2292996592850934567gmail_msg"></div></div></div><div class="m_-2292996592850934567gmail_msg"><div class="gmail_extra m_-2292996592850934567gmail_msg"><div class="gmail_quote m_-2292996592850934567gmail_msg"><blockquote class="gmail_quote m_-2292996592850934567gmail_msg" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);border-left-style:solid;padding-left:1ex"><div class="m_-2292996592850934567gmail_msg">Hi,<div class="m_-2292996592850934567gmail_msg"><br class="m_-2292996592850934567gmail_msg"></div><div class="m_-2292996592850934567gmail_msg">If I have an escaping function that I store and then call, I need to declare the calling function as throwing, not rethrowing. EG:</div><div class="m_-2292996592850934567gmail_msg"><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><p class="m_-2292996592850934567gmail_msg m_-2292996592850934567m_3804435008049710637m_9079363423569745951m_-6115875790740195702gmail-p1"><span class="m_-2292996592850934567gmail_msg m_-2292996592850934567m_3804435008049710637m_9079363423569745951m_-6115875790740195702gmail-s1"> </span>struct FStore {<br class="m_-2292996592850934567gmail_msg"> <span class="m_-2292996592850934567Apple-converted-space"> </span>let f: () throws -> Void<br class="m_-2292996592850934567gmail_msg"> <span class="m_-2292996592850934567Apple-converted-space"> </span>init(f: @escaping () throws -> Void) { self.f = f }<br class="m_-2292996592850934567gmail_msg"> <span class="m_-2292996592850934567Apple-converted-space"> </span>func call() throws { try f() } // Can't put rethrows here - have to use throws<br class="m_-2292996592850934567gmail_msg"> <span class="m_-2292996592850934567Apple-converted-space"> </span>}</p></div><div class="m_-2292996592850934567gmail_msg">Is there a better solution?</div><div class="m_-2292996592850934567gmail_msg"><br class="m_-2292996592850934567gmail_msg"></div><div class="m_-2292996592850934567gmail_msg">Thanks for any suggestions,</div><div class="m_-2292996592850934567gmail_msg"><br clear="all" class="m_-2292996592850934567gmail_msg"><div class="m_-2292996592850934567gmail_msg"><div class="m_-2292996592850934567gmail_msg m_-2292996592850934567m_3804435008049710637m_9079363423569745951m_-6115875790740195702gmail_signature"> <span class="m_-2292996592850934567Apple-converted-space"> </span>-- Howard.<br class="m_-2292996592850934567gmail_msg"></div></div><br><br></div></div><br><br><br class="m_-2292996592850934567gmail_msg"></blockquote></div></div></div><div class="m_-2292996592850934567gmail_msg"><div class="gmail_extra m_-2292996592850934567gmail_msg"><div class="gmail_quote m_-2292996592850934567gmail_msg"><blockquote class="gmail_quote m_-2292996592850934567gmail_msg" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);border-left-style:solid;padding-left:1ex">______________________________<wbr>_________________<br class="m_-2292996592850934567gmail_msg"><br><br>swift-evolution mailing list<br class="m_-2292996592850934567gmail_msg"><br><br><a href="mailto:swift-evolution@swift.org" class="m_-2292996592850934567gmail_msg" target="_blank">swift-evolution@swift.org</a><br class="m_-2292996592850934567gmail_msg"><br><br><a href="https://lists.swift.org/mailman/listinfo/swift-evolution" rel="noreferrer" class="m_-2292996592850934567gmail_msg" target="_blank">https://lists.swift.org/<wbr>mailman/listinfo/swift-<wbr>evolution</a><br class="m_-2292996592850934567gmail_msg"><br><br><br class="m_-2292996592850934567gmail_msg"></blockquote></div><br class="m_-2292996592850934567gmail_msg"></div></div><br><span class="HOEnZb"><font color="#888888"><br></font></span></blockquote></div></div><span class="HOEnZb"><font color="#888888"><div dir="ltr" style="font-family:Helvetica;font-size:12px;font-style:normal;font-variant-caps:normal;font-weight:normal;letter-spacing:normal;text-align:start;text-indent:0px;text-transform:none;white-space:normal;word-spacing:0px">--<span class="m_-2292996592850934567Apple-converted-space"> </span><br></div><div data-smartmail="gmail_signature" style="font-family:Helvetica;font-size:12px;font-style:normal;font-variant-caps:normal;font-weight:normal;letter-spacing:normal;text-align:start;text-indent:0px;text-transform:none;white-space:normal;word-spacing:0px">-- Howard.</div><span style="font-family:Helvetica;font-size:12px;font-style:normal;font-variant-caps:normal;font-weight:normal;letter-spacing:normal;text-align:start;text-indent:0px;text-transform:none;white-space:normal;word-spacing:0px;float:none;display:inline!important">______________________________<wbr>_________________</span><br style="font-family:Helvetica;font-size:12px;font-style:normal;font-variant-caps:normal;font-weight:normal;letter-spacing:normal;text-align:start;text-indent:0px;text-transform:none;white-space:normal;word-spacing:0px"><span style="font-family:Helvetica;font-size:12px;font-style:normal;font-variant-caps:normal;font-weight:normal;letter-spacing:normal;text-align:start;text-indent:0px;text-transform:none;white-space:normal;word-spacing:0px;float:none;display:inline!important">swift-evolution mailing list</span><br style="font-family:Helvetica;font-size:12px;font-style:normal;font-variant-caps:normal;font-weight:normal;letter-spacing:normal;text-align:start;text-indent:0px;text-transform:none;white-space:normal;word-spacing:0px"><a href="mailto:swift-evolution@swift.org" style="font-family:Helvetica;font-size:12px;font-style:normal;font-variant-caps:normal;font-weight:normal;letter-spacing:normal;text-align:start;text-indent:0px;text-transform:none;white-space:normal;word-spacing:0px" target="_blank">swift-evolution@swift.org</a><br style="font-family:Helvetica;font-size:12px;font-style:normal;font-variant-caps:normal;font-weight:normal;letter-spacing:normal;text-align:start;text-indent:0px;text-transform:none;white-space:normal;word-spacing:0px"><a href="https://lists.swift.org/mailman/listinfo/swift-evolution" style="font-family:Helvetica;font-size:12px;font-style:normal;font-variant-caps:normal;font-weight:normal;letter-spacing:normal;text-align:start;text-indent:0px;text-transform:none;white-space:normal;word-spacing:0px" target="_blank">https://lists.swift.org/<wbr>mailman/listinfo/swift-<wbr>evolution</a></font></span></div></blockquote></div><br></div></blockquote></div><br></div>