<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="">Hi Gwendal,<div class=""><br class=""></div><div class="">Nice writeup. So I see that you recognise how this extra specification will complicate (while also facilitate) things. And I also see that you're a co-author of the proposal. So I'm more than happy if you can squeeze this extra into it.</div><div class=""><br class=""></div><div class="">However reading your example code, I had to squint to see—without the compiler's squiggly red aid—what all the problematic cases are.</div><div class=""><br class=""></div><div class="">1) Is it obvious to everybody why you can't always use `x` in the end of Cases 2 and 4? For example, with `if—else` you MUST initialise the variable or escape its scope in all branches; you can't just write the following to complete the initialisation later:</div><div class=""><br class=""></div><div class=""><font face="Menlo" class=""><span style="font-size: 11px;" class=""> let x: Int</span></font></div><div class=""><font face="Menlo" class=""><span style="font-size: 11px;" class=""> if cond { x = 1 }</span></font></div><div class=""><font face="Menlo" class=""><span style="font-size: 11px;" class=""> // ...</span></font></div><div class=""><font face="Menlo" class=""><span style="font-size: 11px;" class=""> if !cond { x = 2 } // too late!</span></font></div><div class=""><br class=""></div><div class="">2) Should Cases 2 and 4 be made illegal? The requirement could then be that all `catch` blocks either:</div><div class="">2.a) initialise another value for `x`, or</div><div class="">2.b) escape the scope using `throw`, `return`, `fatalError`, whatnot…</div><div class=""><br class=""></div><div class="">3) If you consider including this addition to the proposal, it might also help other reviewers if you explained how the compiler will be able to help the programmer write a valid program. E.g. what would the error messages about partially initialised variables look like? And where and when would they appear? Could the compiler suggest certain fixits? Etc.</div><div class=""><br class=""></div><div class="">So, I'm all +1 and very glad if you can make it! (But also somewhat sceptical whether it could get accepted.)</div><div class=""><br class=""></div><div class="">— Pyry</div><div class=""><br class=""><div><blockquote type="cite" class=""><div class="">On 04 May 2016, at 12:24, Gwendal Roué <<a href="mailto:gwendal.roue@gmail.com" class="">gwendal.roue@gmail.com</a>> wrote:</div><br class="Apple-interchange-newline"><div class=""><div class="">I quite expect being able to throw out of a @noescape(once) block. Maybe the sentence "it must not be executed on any path that throws" should be removed from the proposal, should it have the implications you describe.<br class=""><br class="">Here is below what I expect this proposal to allow. So you see one problematic case?<br class=""><br class=""><span class="Apple-tab-span" style="white-space:pre">        </span>// Function which rethrows closure errors:<br class=""><span class="Apple-tab-span" style="white-space:pre">        </span>func f1(closure: @noescape(once) () throws -> ()) rethrows {<br class=""><span class="Apple-tab-span" style="white-space:pre">        </span><span class="Apple-tab-span" style="white-space:pre">        </span>try closure()<br class=""><span class="Apple-tab-span" style="white-space:pre">        </span>}<br class=""><br class=""><span class="Apple-tab-span" style="white-space:pre">        </span>// Function which may throw before, inside, or after the closure:<br class=""><span class="Apple-tab-span" style="white-space:pre">        </span>func f2(closure: @noescape(once) () throws -> ()) throws {<br class=""><span class="Apple-tab-span" style="white-space:pre">        </span><span class="Apple-tab-span" style="white-space:pre">        </span>try mayFailBefore()<br class=""><span class="Apple-tab-span" style="white-space:pre">        </span><span class="Apple-tab-span" style="white-space:pre">        </span>try closure()<br class=""><span class="Apple-tab-span" style="white-space:pre">        </span><span class="Apple-tab-span" style="white-space:pre">        </span>try mayFailAfter()<br class=""><span class="Apple-tab-span" style="white-space:pre">        </span>}<br class=""><span class="Apple-tab-span" style="white-space:pre">        </span><br class=""><span class="Apple-tab-span" style="white-space:pre">        </span>// Support function<br class=""><span class="Apple-tab-span" style="white-space:pre">        </span>func getX() throws -> Int { return 1 }<br class=""><span class="Apple-tab-span" style="white-space:pre">        </span><br class="">Case 1:<br class=""><br class=""><span class="Apple-tab-span" style="white-space:pre">        </span>let x: Int<br class=""><span class="Apple-tab-span" style="white-space:pre">        </span>f1 {<br class=""><span class="Apple-tab-span" style="white-space:pre">        </span><span class="Apple-tab-span" style="white-space:pre">        </span>x = 1<br class=""><span class="Apple-tab-span" style="white-space:pre">        </span><span class="Apple-tab-span" style="white-space:pre">        </span>// use x<br class=""><span class="Apple-tab-span" style="white-space:pre">        </span>}<br class=""><span class="Apple-tab-span" style="white-space:pre">        </span>// use x<br class=""><span class="Apple-tab-span" style="white-space:pre">        </span><br class="">Case 2:<br class=""><br class=""><span class="Apple-tab-span" style="white-space:pre">        </span>let x: Int<br class=""><span class="Apple-tab-span" style="white-space:pre">        </span>do {<br class=""><span class="Apple-tab-span" style="white-space:pre">        </span><span class="Apple-tab-span" style="white-space:pre">        </span>try f1 {<br class=""><span class="Apple-tab-span" style="white-space:pre">        </span><span class="Apple-tab-span" style="white-space:pre">        </span><span class="Apple-tab-span" style="white-space:pre">        </span>x = try getX()<br class=""><span class="Apple-tab-span" style="white-space:pre">        </span><span class="Apple-tab-span" style="white-space:pre">        </span><span class="Apple-tab-span" style="white-space:pre">        </span>// use x<br class=""><span class="Apple-tab-span" style="white-space:pre">        </span><span class="Apple-tab-span" style="white-space:pre">        </span>}<br class=""><span class="Apple-tab-span" style="white-space:pre">        </span><span class="Apple-tab-span" style="white-space:pre">        </span>// use x<br class=""><span class="Apple-tab-span" style="white-space:pre">        </span>} catch {<br class=""><span class="Apple-tab-span" style="white-space:pre">        </span><span class="Apple-tab-span" style="white-space:pre">        </span>// can't use x<br class=""><span class="Apple-tab-span" style="white-space:pre">        </span>}<br class=""><span class="Apple-tab-span" style="white-space:pre">        </span>// can't use x<br class=""><span class="Apple-tab-span" style="white-space:pre">        </span><br class="">Case 3:<br class=""><br class=""><span class="Apple-tab-span" style="white-space:pre">        </span>let x: Int<br class=""><span class="Apple-tab-span" style="white-space:pre">        </span>do {<br class=""><span class="Apple-tab-span" style="white-space:pre">        </span><span class="Apple-tab-span" style="white-space:pre">        </span>try f1 {<br class=""><span class="Apple-tab-span" style="white-space:pre">        </span><span class="Apple-tab-span" style="white-space:pre">        </span><span class="Apple-tab-span" style="white-space:pre">        </span>x = try getX()<br class=""><span class="Apple-tab-span" style="white-space:pre">        </span><span class="Apple-tab-span" style="white-space:pre">        </span><span class="Apple-tab-span" style="white-space:pre">        </span>// use x<br class=""><span class="Apple-tab-span" style="white-space:pre">        </span><span class="Apple-tab-span" style="white-space:pre">        </span>}<br class=""><span class="Apple-tab-span" style="white-space:pre">        </span><span class="Apple-tab-span" style="white-space:pre">        </span>// use x<br class=""><span class="Apple-tab-span" style="white-space:pre">        </span>} catch {<br class=""><span class="Apple-tab-span" style="white-space:pre">        </span><span class="Apple-tab-span" style="white-space:pre">        </span>x = 1<br class=""><span class="Apple-tab-span" style="white-space:pre">        </span>}<br class=""><span class="Apple-tab-span" style="white-space:pre">        </span>// use x<br class=""><span class="Apple-tab-span" style="white-space:pre">        </span><br class="">Case 4:<br class=""><br class=""><span class="Apple-tab-span" style="white-space:pre">        </span>let x: Int<br class=""><span class="Apple-tab-span" style="white-space:pre">        </span>do {<br class=""><span class="Apple-tab-span" style="white-space:pre">        </span><span class="Apple-tab-span" style="white-space:pre">        </span>try f2 {<br class=""><span class="Apple-tab-span" style="white-space:pre">        </span><span class="Apple-tab-span" style="white-space:pre">        </span><span class="Apple-tab-span" style="white-space:pre">        </span>x = try getX()<br class=""><span class="Apple-tab-span" style="white-space:pre">        </span><span class="Apple-tab-span" style="white-space:pre">        </span><span class="Apple-tab-span" style="white-space:pre">        </span>// use x<br class=""><span class="Apple-tab-span" style="white-space:pre">        </span><span class="Apple-tab-span" style="white-space:pre">        </span>}<br class=""><span class="Apple-tab-span" style="white-space:pre">        </span><span class="Apple-tab-span" style="white-space:pre">        </span>// use x<br class=""><span class="Apple-tab-span" style="white-space:pre">        </span>} catch {<br class=""><span class="Apple-tab-span" style="white-space:pre">        </span><span class="Apple-tab-span" style="white-space:pre">        </span>// can't use x<br class=""><span class="Apple-tab-span" style="white-space:pre">        </span>}<br class=""><span class="Apple-tab-span" style="white-space:pre">        </span>// can't use x<br class=""><br class="">Case 5:<br class=""><br class=""><span class="Apple-tab-span" style="white-space:pre">        </span>let x: Int<br class=""><span class="Apple-tab-span" style="white-space:pre">        </span>do {<br class=""><span class="Apple-tab-span" style="white-space:pre">        </span><span class="Apple-tab-span" style="white-space:pre">        </span>try f2 {<br class=""><span class="Apple-tab-span" style="white-space:pre">        </span><span class="Apple-tab-span" style="white-space:pre">        </span><span class="Apple-tab-span" style="white-space:pre">        </span>x = try getX()<br class=""><span class="Apple-tab-span" style="white-space:pre">        </span><span class="Apple-tab-span" style="white-space:pre">        </span><span class="Apple-tab-span" style="white-space:pre">        </span>// use x<br class=""><span class="Apple-tab-span" style="white-space:pre">        </span><span class="Apple-tab-span" style="white-space:pre">        </span>}<br class=""><span class="Apple-tab-span" style="white-space:pre">        </span><span class="Apple-tab-span" style="white-space:pre">        </span>// use x<br class=""><span class="Apple-tab-span" style="white-space:pre">        </span>} catch {<br class=""><span class="Apple-tab-span" style="white-space:pre">        </span><span class="Apple-tab-span" style="white-space:pre">        </span>x = 1<br class=""><span class="Apple-tab-span" style="white-space:pre">        </span>}<br class=""><span class="Apple-tab-span" style="white-space:pre">        </span>// use x<br class=""><br class="">Gwendal Roué<br class=""><br class=""></div></div></blockquote></div><br class="">
<br class=""></div></body></html>