Re: [swift-evolution] [Proposal] A more liberal placement of defer

2016-06-06 Thread Kenny Leung via swift-evolution
This proposal runs counter to the spirit of what defer seems to be meant for in 
the first place. It’s to save you forgetting to do something (like closing a 
stream) before you exit a block of code. If you push it down in the code to 
after the return, then you might as well have just put the code in *before* the 
return without the defer.

public func doMyThing() {
let theStream = openStream()
defer {
closeStream()
}

…
…
…

return
}

In this case, putting closeStream() after the return would defeat the purpose.

-Kenny


> On Jun 6, 2016, at 12:50 PM, donny wals via swift-evolution 
>  wrote:
> 
> Hi,
> 
> When we’re using defer we write some code that we want to execute the moment 
> a scope exits.
> This leads to code that could read like:
> 
> let fibonacci = sequence(state: (0, 1)) { (pair: inout (Int, Int)) -> Int in
>defer { pair = (pair.1, pair.0 + pair.1) }
>return pair.0
> }
> 
> What I find strange about this is that we have to write the code that we want 
> to execute after the return before the return.
> 
> I’d like to propose a change to defer that would allow the above code to be 
> written as:
> 
> let fibonacci = sequence(state: (0, 1)) { (pair: inout (Int, Int)) -> Int in
>return pair.0
>defer { pair = (pair.1, pair.0 + pair.1) }
> }
> 
> This would make the intent of the code more clear (return first, then mutate 
> state). Not all cases can benefit from this change, but anytime you exit a 
> scope using a return I think it might be more clear to define the defer after 
> the return. The code would more closely mirror the intent of the code.
> 
> A rule of thumb I’ve come up with for this is that whenever you’re using 
> return to exit a scope, any defer in that same scope should be executed 
> regardless of it’s position in that same scope. This proposal would 
> supplement the way defer currently works.
> 
> What do you all think?
> ___
> swift-evolution mailing list
> swift-evolution@swift.org
> https://lists.swift.org/mailman/listinfo/swift-evolution

___
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


Re: [swift-evolution] [Proposal] A more liberal placement of defer

2016-06-06 Thread Haravikk via swift-evolution
While I can kind of see where you’re coming from I’m not sure about the change; 
the key thing about defer is that it doesn’t just execute in the cases you 
explicitly define, but can also occur if exceptions are thrown and other exit 
cases that could be all over the scope.

To compare with other languages, I’ve used several that achieve this with a 
finally block instead, usually as part of a try/catch like so:

try { doSomethingThatCanThrow(); return 1; }
catch (Exception e) { print(e); return 0; }
finally { doSomeCleanup(); }

Here you have two possible exit points, and in both cases the code in the 
finally block is executed. But it’s pretty rigid.

This is fine in cases like you suggest where it makes a bit more sense 
visually, but the cool thing about Swift is that you can declare defer blocks 
all over the place, build upon them and so-on. It means you can group your 
cleanup code with the statements that actually require the cleanup, even if 
there is a ton of extra code that comes afterwards. For example, opening a TCP 
connection may use a defer block right away to ensure the connection is closed 
cleanly and any buffers are cleared regardless of how the method ends 
(normally, IO error etc.), but before that happens there may be a whole load of 
parsing and other operations before you hit the final return statement.

It’s also pretty clear from the keyword defer; putting it after the return 
statement actually makes less sense, as there is nothing for it to be deferred 
in relation to (as there’s nothing else left to do).


I’d say that if you want cleanup to appear visually afterwards you’d be better 
off promising a finally block, this could be nice to have, especially if it 
could be applied to most blocks like so:

do {
somethingThatCouldThrow()
if someCondition { return }
} finally { someCleanup() } // Executed whether the block throws, 
returns or completes normally

for eachValue in theValues {
if doSomethingTo(eachValue) { break }
if someCondition { return }
else { throw SomeError() }
} finally { doSomeCleanup() } // Executes regardless of whether the 
loop ends normally, breaks, returns or throws

And so-on. I’d say that defer is more flexible overall, but there could be some 
cause for this visually so you can move simpler deferred code away from the 
main method body.

> On 6 Jun 2016, at 20:50, donny wals via swift-evolution 
>  wrote:
> 
> Hi,
> 
> When we’re using defer we write some code that we want to execute the moment 
> a scope exits.
> This leads to code that could read like:
> 
> let fibonacci = sequence(state: (0, 1)) { (pair: inout (Int, Int)) -> Int in
>defer { pair = (pair.1, pair.0 + pair.1) }
>return pair.0
> }
> 
> What I find strange about this is that we have to write the code that we want 
> to execute after the return before the return.
> 
> I’d like to propose a change to defer that would allow the above code to be 
> written as:
> 
> let fibonacci = sequence(state: (0, 1)) { (pair: inout (Int, Int)) -> Int in
>return pair.0
>defer { pair = (pair.1, pair.0 + pair.1) }
> }
> 
> This would make the intent of the code more clear (return first, then mutate 
> state). Not all cases can benefit from this change, but anytime you exit a 
> scope using a return I think it might be more clear to define the defer after 
> the return. The code would more closely mirror the intent of the code.
> 
> A rule of thumb I’ve come up with for this is that whenever you’re using 
> return to exit a scope, any defer in that same scope should be executed 
> regardless of it’s position in that same scope. This proposal would 
> supplement the way defer currently works.
> 
> What do you all think?
> ___
> swift-evolution mailing list
> swift-evolution@swift.org
> https://lists.swift.org/mailman/listinfo/swift-evolution

___
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


Re: [swift-evolution] [Proposal] A more liberal placement of defer

2016-06-06 Thread Erica Sadun via swift-evolution
Not sure I see how they're in different scopes. Can you explain that to me?

-- E

> On Jun 6, 2016, at 2:18 PM, donny wals  wrote:
> 
> Erica,
> 
> Maybe my phrasing was a bit off, but in my proposal it’s really important 
> that the return and the defer are in the same scope. In your example the 
> allocate memory line is in a different scope that the guard/else statements. 
> Therefor, the defer { release memory } shouldn’t be executed if the guards 
> don’t hold.
> 
> D
> 
>> On 06 Jun 2016, at 22:09, Erica Sadun  wrote:
>> 
>> This is problematic. You may want to defer code at different points with 
>> different reasons. For example, you might not want to trigger defer until 
>> after some preconditions have been met.:
>> 
>> guard something 
>> guard something
>> allocate memory; defer {release memory}
>> 
>> -- E

___
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


Re: [swift-evolution] [Proposal] A more liberal placement of defer

2016-06-06 Thread Tim Vermeulen via swift-evolution
>And simple functions like fibonacci I would just write without using `defer` 
>at all - it's just confusing to use `defer` and `inout` in this case IMO.
> 
> /// Calculates the n'th fibonacci number. (n>= 1)
> func fibonacci(n: Int) ->Int {
> var a = 0
> var b = 1
> for _ in 1...n {
> (a,b)=(b, a+b)
> }
> return a
> }

This is simply a function to calculate the n-th Fibonacci number, though. The 
original code constructed a sequence.

> Hi,
> 
> you may think of `defer` as a function that pushes a block onto an implicit 
> cleanup stack that is part of every lexical closure. On each scope exit, all 
> blocks from its cleanup stack are popped and executed.
> 
> E.g.:
> 
> func f(x: Int) {
> defer { print("A"); }
> defer { print("B"); }
> if x == 3 {
> return
> }
> defer { print("C"); }
> }
> 
> So, f(2) will print "CBA", but f(3) will print "BA" instead. Furthermore, 
> this will change semantics and break the following code:
> 
> func g(x: Int) {
> defer { print("A"); }
> let b: Int
> if x == 3 {
> return
> } else {
> b = x
> }
> defer { print("b is \(b)") }
> }
> 
> In the code above, b is only defined if x is not 3. If x is 3, the last 
> `defer` block cannot be called, and that code would no longer compile.
> 
> So I think the current language behavior is more powerful. `defer` is usually 
> used to do cleanup work, and it is called near the place where some resource 
> is initialized. Putting a `defer` block to the end of a function kinda 
> defeats its purpose. And simple functions like fibonacci I would just write 
> without using `defer` at all - it's just confusing to use `defer` and `inout` 
> in this case IMO.
> 
> /// Calculates the n'th fibonacci number. (n>= 1)
> func fibonacci(n: Int) ->Int {
> var a = 0
> var b = 1
> for _ in 1...n {
> (a,b)=(b, a+b)
> }
> return a
> }
> 
> Regards,
> Michael
> 
> 
> > Am 06.06.2016 um 21:50 schrieb donny wals via 
> > swift-evolution:
> > 
> > Hi,
> > 
> > When we’re using defer we write some code that we want to execute the 
> > moment a scope exits.
> > This leads to code that could read like:
> > 
> > let fibonacci = sequence(state: (0, 1)) { (pair: inout (Int, Int)) ->Int in
> > defer { pair = (pair.1, pair.0 + pair.1) }
> > return pair.0
> > }
> > 
> > What I find strange about this is that we have to write the code that we 
> > want to execute after the return before the return.
> > 
> > I’d like to propose a change to defer that would allow the above code to be 
> > written as:
> > 
> > let fibonacci = sequence(state: (0, 1)) { (pair: inout (Int, Int)) ->Int in
> > return pair.0
> > defer { pair = (pair.1, pair.0 + pair.1) }
> > }
> > 
> > This would make the intent of the code more clear (return first, then 
> > mutate state). Not all cases can benefit from this change, but anytime you 
> > exit a scope using a return I think it might be more clear to define the 
> > defer after the return. The code would more closely mirror the intent of 
> > the code.
> > 
> > A rule of thumb I’ve come up with for this is that whenever you’re using 
> > return to exit a scope, any defer in that same scope should be executed 
> > regardless of it’s position in that same scope. This proposal would 
> > supplement the way defer currently works.
> > 
> > What do you all think?
> > ___
> > swift-evolution mailing list
> > swift-evolution@swift.org
> > https://lists.swift.org/mailman/listinfo/swift-evolution
> 
> 
> 
___
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


Re: [swift-evolution] [Proposal] A more liberal placement of defer

2016-06-06 Thread donny wals via swift-evolution
Hi,

That’s fair enough. IMO structuring code so it reads in the same order it 
executes is an opportunity to simplify code rather than complicate it. However, 
I do agree that the fibonacci example I mentioned earlier might not be the best 
use case and it’s probably the best use case for this proposal. Since in terms 
of using defer as cleanup code the order doesn’t matter as much. But still.. it 
feels a bit weird to be forced to write the “after return” code before the 
actual return. On the other hand, defer has a pretty clear meaning already and 
if you and others think that this proposal would break semantics, it’s probably 
not the best idea

D


> On 06 Jun 2016, at 22:25, michael.petern...@gmx.at wrote:
> 
> Hi,
> 
> I think that's an awful idea. I can already tell you that this will never be 
> accepted. It just complicates the design and the semantics of the `defer` 
> statement, and I don't see any advantage. Sorry.
> 
> -Michael
> 
>> Am 06.06.2016 um 22:14 schrieb donny wals via swift-evolution 
>> :
>> 
>> Michael,
>> 
>> How would this proposal break your snippet?
>> 
>>> func g(x: Int) {
>>>  defer { print("A"); }
>>>  let b: Int
>>>  if x == 3 {
>>>  return
>>>  } else {
>>>  b = x
>>>  }
>>>  defer { print("b is \(b)") }
>>> }
>> 
>> In this case if x==3 the function should return without executing the final 
>> defer. The reason I think it should work like that is that the if statement 
>> creates a scope of it’s own. You’re using a return inside of that scope, so 
>> only if you’re adding a defer inside of that scope it should be executed 
>> even if it’s after the return. The important part here is that the return 
>> and the defer should be in the same scope for this proposal to apply.
>> 
>>> On 06 Jun 2016, at 22:07, Michael Peternell  
>>> wrote:
>>> 
>>> Hi,
>>> 
>>> you may think of `defer` as a function that pushes a block onto an implicit 
>>> cleanup stack that is part of every lexical closure. On each scope exit, 
>>> all blocks from its cleanup stack are popped and executed.
>>> 
>>> E.g.:
>>> 
>>> func f(x: Int) {
>>>  defer { print("A"); }
>>>  defer { print("B"); }
>>>  if x == 3 {
>>>  return
>>>  }
>>>  defer { print("C"); }
>>> }
>>> 
>>> So, f(2) will print "CBA", but f(3) will print "BA" instead. Furthermore, 
>>> this will change semantics and break the following code:
>>> 
>>> func g(x: Int) {
>>>  defer { print("A"); }
>>>  let b: Int
>>>  if x == 3 {
>>>  return
>>>  } else {
>>>  b = x
>>>  }
>>>  defer { print("b is \(b)") }
>>> }
>>> 
>>> In the code above, b is only defined if x is not 3. If x is 3, the last 
>>> `defer` block cannot be called, and that code would no longer compile.
>>> 
>>> So I think the current language behavior is more powerful. `defer` is 
>>> usually used to do cleanup work, and it is called near the place where some 
>>> resource is initialized. Putting a `defer` block to the end of a function 
>>> kinda defeats its purpose. And simple functions like fibonacci I would just 
>>> write without using `defer` at all - it's just confusing to use `defer` and 
>>> `inout` in this case IMO.
>>> 
>>> /// Calculates the n'th fibonacci number. (n >= 1)
>>> func fibonacci(n: Int) -> Int {
>>>  var a = 0
>>>  var b = 1
>>>  for _ in 1...n {
>>>  (a,b)=(b, a+b)
>>>  }
>>>  return a
>>> }
>>> 
>>> Regards,
>>> Michael
>>> 
>>> 
 Am 06.06.2016 um 21:50 schrieb donny wals via swift-evolution 
 :
 
 Hi,
 
 When we’re using defer we write some code that we want to execute the 
 moment a scope exits.
 This leads to code that could read like:
 
 let fibonacci = sequence(state: (0, 1)) { (pair: inout (Int, Int)) -> Int 
 in
 defer { pair = (pair.1, pair.0 + pair.1) }
 return pair.0
 }
 
 What I find strange about this is that we have to write the code that we 
 want to execute after the return before the return.
 
 I’d like to propose a change to defer that would allow the above code to 
 be written as:
 
 let fibonacci = sequence(state: (0, 1)) { (pair: inout (Int, Int)) -> Int 
 in
 return pair.0
 defer { pair = (pair.1, pair.0 + pair.1) }
 }
 
 This would make the intent of the code more clear (return first, then 
 mutate state). Not all cases can benefit from this change, but anytime you 
 exit a scope using a return I think it might be more clear to define the 
 defer after the return. The code would more closely mirror the intent of 
 the code.
 
 A rule of thumb I’ve come up with for this is that whenever you’re using 
 return to exit a scope, any defer in that same scope should be executed 
 regardless of it’s position in that same scope. This proposal would 
 supplement the way defer currently works.
 
 What do you all think?
 ___
 

Re: [swift-evolution] [Proposal] A more liberal placement of defer

2016-06-06 Thread Michael Peternell via swift-evolution
Hi,

I think that's an awful idea. I can already tell you that this will never be 
accepted. It just complicates the design and the semantics of the `defer` 
statement, and I don't see any advantage. Sorry.

-Michael

> Am 06.06.2016 um 22:14 schrieb donny wals via swift-evolution 
> :
> 
> Michael,
> 
> How would this proposal break your snippet?
> 
>> func g(x: Int) {
>>   defer { print("A"); }
>>   let b: Int
>>   if x == 3 {
>>   return
>>   } else {
>>   b = x
>>   }
>>   defer { print("b is \(b)") }
>> }
> 
> In this case if x==3 the function should return without executing the final 
> defer. The reason I think it should work like that is that the if statement 
> creates a scope of it’s own. You’re using a return inside of that scope, so 
> only if you’re adding a defer inside of that scope it should be executed even 
> if it’s after the return. The important part here is that the return and the 
> defer should be in the same scope for this proposal to apply.
> 
>> On 06 Jun 2016, at 22:07, Michael Peternell  wrote:
>> 
>> Hi,
>> 
>> you may think of `defer` as a function that pushes a block onto an implicit 
>> cleanup stack that is part of every lexical closure. On each scope exit, all 
>> blocks from its cleanup stack are popped and executed.
>> 
>> E.g.:
>> 
>> func f(x: Int) {
>>   defer { print("A"); }
>>   defer { print("B"); }
>>   if x == 3 {
>>   return
>>   }
>>   defer { print("C"); }
>> }
>> 
>> So, f(2) will print "CBA", but f(3) will print "BA" instead. Furthermore, 
>> this will change semantics and break the following code:
>> 
>> func g(x: Int) {
>>   defer { print("A"); }
>>   let b: Int
>>   if x == 3 {
>>   return
>>   } else {
>>   b = x
>>   }
>>   defer { print("b is \(b)") }
>> }
>> 
>> In the code above, b is only defined if x is not 3. If x is 3, the last 
>> `defer` block cannot be called, and that code would no longer compile.
>> 
>> So I think the current language behavior is more powerful. `defer` is 
>> usually used to do cleanup work, and it is called near the place where some 
>> resource is initialized. Putting a `defer` block to the end of a function 
>> kinda defeats its purpose. And simple functions like fibonacci I would just 
>> write without using `defer` at all - it's just confusing to use `defer` and 
>> `inout` in this case IMO.
>> 
>> /// Calculates the n'th fibonacci number. (n >= 1)
>> func fibonacci(n: Int) -> Int {
>>   var a = 0
>>   var b = 1
>>   for _ in 1...n {
>>   (a,b)=(b, a+b)
>>   }
>>   return a
>> }
>> 
>> Regards,
>> Michael
>> 
>> 
>>> Am 06.06.2016 um 21:50 schrieb donny wals via swift-evolution 
>>> :
>>> 
>>> Hi,
>>> 
>>> When we’re using defer we write some code that we want to execute the 
>>> moment a scope exits.
>>> This leads to code that could read like:
>>> 
>>> let fibonacci = sequence(state: (0, 1)) { (pair: inout (Int, Int)) -> Int in
>>>  defer { pair = (pair.1, pair.0 + pair.1) }
>>>  return pair.0
>>> }
>>> 
>>> What I find strange about this is that we have to write the code that we 
>>> want to execute after the return before the return.
>>> 
>>> I’d like to propose a change to defer that would allow the above code to be 
>>> written as:
>>> 
>>> let fibonacci = sequence(state: (0, 1)) { (pair: inout (Int, Int)) -> Int in
>>>  return pair.0
>>>  defer { pair = (pair.1, pair.0 + pair.1) }
>>> }
>>> 
>>> This would make the intent of the code more clear (return first, then 
>>> mutate state). Not all cases can benefit from this change, but anytime you 
>>> exit a scope using a return I think it might be more clear to define the 
>>> defer after the return. The code would more closely mirror the intent of 
>>> the code.
>>> 
>>> A rule of thumb I’ve come up with for this is that whenever you’re using 
>>> return to exit a scope, any defer in that same scope should be executed 
>>> regardless of it’s position in that same scope. This proposal would 
>>> supplement the way defer currently works.
>>> 
>>> What do you all think?
>>> ___
>>> swift-evolution mailing list
>>> swift-evolution@swift.org
>>> https://lists.swift.org/mailman/listinfo/swift-evolution
>> 
> 
> ___
> swift-evolution mailing list
> swift-evolution@swift.org
> https://lists.swift.org/mailman/listinfo/swift-evolution

___
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


Re: [swift-evolution] [Proposal] A more liberal placement of defer

2016-06-06 Thread donny wals via swift-evolution
Erica,

Maybe my phrasing was a bit off, but in my proposal it’s really important that 
the return and the defer are in the same scope. In your example the allocate 
memory line is in a different scope that the guard/else statements. Therefor, 
the defer { release memory } shouldn’t be executed if the guards don’t hold.

D

> On 06 Jun 2016, at 22:09, Erica Sadun  wrote:
> 
> This is problematic. You may want to defer code at different points with 
> different reasons. For example, you might not want to trigger defer until 
> after some preconditions have been met.:
> 
> guard something 
> guard something
> allocate memory; defer {release memory}
> 
> -- E
> 
> 
> 
>> On Jun 6, 2016, at 1:50 PM, donny wals via swift-evolution 
>>  wrote:
>> 
>> Hi,
>> 
>> When we’re using defer we write some code that we want to execute the moment 
>> a scope exits.
>> This leads to code that could read like:
>> 
>> let fibonacci = sequence(state: (0, 1)) { (pair: inout (Int, Int)) -> Int in
>>   defer { pair = (pair.1, pair.0 + pair.1) }
>>   return pair.0
>> }
>> 
>> What I find strange about this is that we have to write the code that we 
>> want to execute after the return before the return.
>> 
>> I’d like to propose a change to defer that would allow the above code to be 
>> written as:
>> 
>> let fibonacci = sequence(state: (0, 1)) { (pair: inout (Int, Int)) -> Int in
>>   return pair.0
>>   defer { pair = (pair.1, pair.0 + pair.1) }
>> }
>> 
>> This would make the intent of the code more clear (return first, then mutate 
>> state). Not all cases can benefit from this change, but anytime you exit a 
>> scope using a return I think it might be more clear to define the defer 
>> after the return. The code would more closely mirror the intent of the code.
>> 
>> A rule of thumb I’ve come up with for this is that whenever you’re using 
>> return to exit a scope, any defer in that same scope should be executed 
>> regardless of it’s position in that same scope. This proposal would 
>> supplement the way defer currently works.
>> 
>> What do you all think?
>> ___
>> swift-evolution mailing list
>> swift-evolution@swift.org
>> https://lists.swift.org/mailman/listinfo/swift-evolution
> 

___
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


Re: [swift-evolution] [Proposal] A more liberal placement of defer

2016-06-06 Thread donny wals via swift-evolution
Michael,

How would this proposal break your snippet?

> func g(x: Int) {
>defer { print("A"); }
>let b: Int
>if x == 3 {
>return
>} else {
>b = x
>}
>defer { print("b is \(b)") }
> }

In this case if x==3 the function should return without executing the final 
defer. The reason I think it should work like that is that the if statement 
creates a scope of it’s own. You’re using a return inside of that scope, so 
only if you’re adding a defer inside of that scope it should be executed even 
if it’s after the return. The important part here is that the return and the 
defer should be in the same scope for this proposal to apply.

> On 06 Jun 2016, at 22:07, Michael Peternell  wrote:
> 
> Hi,
> 
> you may think of `defer` as a function that pushes a block onto an implicit 
> cleanup stack that is part of every lexical closure. On each scope exit, all 
> blocks from its cleanup stack are popped and executed.
> 
> E.g.:
> 
> func f(x: Int) {
>defer { print("A"); }
>defer { print("B"); }
>if x == 3 {
>return
>}
>defer { print("C"); }
> }
> 
> So, f(2) will print "CBA", but f(3) will print "BA" instead. Furthermore, 
> this will change semantics and break the following code:
> 
> func g(x: Int) {
>defer { print("A"); }
>let b: Int
>if x == 3 {
>return
>} else {
>b = x
>}
>defer { print("b is \(b)") }
> }
> 
> In the code above, b is only defined if x is not 3. If x is 3, the last 
> `defer` block cannot be called, and that code would no longer compile.
> 
> So I think the current language behavior is more powerful. `defer` is usually 
> used to do cleanup work, and it is called near the place where some resource 
> is initialized. Putting a `defer` block to the end of a function kinda 
> defeats its purpose. And simple functions like fibonacci I would just write 
> without using `defer` at all - it's just confusing to use `defer` and `inout` 
> in this case IMO.
> 
> /// Calculates the n'th fibonacci number. (n >= 1)
> func fibonacci(n: Int) -> Int {
>var a = 0
>var b = 1
>for _ in 1...n {
>(a,b)=(b, a+b)
>}
>return a
> }
> 
> Regards,
> Michael
> 
> 
>> Am 06.06.2016 um 21:50 schrieb donny wals via swift-evolution 
>> :
>> 
>> Hi,
>> 
>> When we’re using defer we write some code that we want to execute the moment 
>> a scope exits.
>> This leads to code that could read like:
>> 
>> let fibonacci = sequence(state: (0, 1)) { (pair: inout (Int, Int)) -> Int in
>>   defer { pair = (pair.1, pair.0 + pair.1) }
>>   return pair.0
>> }
>> 
>> What I find strange about this is that we have to write the code that we 
>> want to execute after the return before the return.
>> 
>> I’d like to propose a change to defer that would allow the above code to be 
>> written as:
>> 
>> let fibonacci = sequence(state: (0, 1)) { (pair: inout (Int, Int)) -> Int in
>>   return pair.0
>>   defer { pair = (pair.1, pair.0 + pair.1) }
>> }
>> 
>> This would make the intent of the code more clear (return first, then mutate 
>> state). Not all cases can benefit from this change, but anytime you exit a 
>> scope using a return I think it might be more clear to define the defer 
>> after the return. The code would more closely mirror the intent of the code.
>> 
>> A rule of thumb I’ve come up with for this is that whenever you’re using 
>> return to exit a scope, any defer in that same scope should be executed 
>> regardless of it’s position in that same scope. This proposal would 
>> supplement the way defer currently works.
>> 
>> What do you all think?
>> ___
>> swift-evolution mailing list
>> swift-evolution@swift.org
>> https://lists.swift.org/mailman/listinfo/swift-evolution
> 

___
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


Re: [swift-evolution] [Proposal] A more liberal placement of defer

2016-06-06 Thread Erica Sadun via swift-evolution
This is problematic. You may want to defer code at different points with 
different reasons. For example, you might not want to trigger defer until after 
some preconditions have been met.:

guard something 
guard something
allocate memory; defer {release memory}

-- E



> On Jun 6, 2016, at 1:50 PM, donny wals via swift-evolution 
>  wrote:
> 
> Hi,
> 
> When we’re using defer we write some code that we want to execute the moment 
> a scope exits.
> This leads to code that could read like:
> 
> let fibonacci = sequence(state: (0, 1)) { (pair: inout (Int, Int)) -> Int in
>defer { pair = (pair.1, pair.0 + pair.1) }
>return pair.0
> }
> 
> What I find strange about this is that we have to write the code that we want 
> to execute after the return before the return.
> 
> I’d like to propose a change to defer that would allow the above code to be 
> written as:
> 
> let fibonacci = sequence(state: (0, 1)) { (pair: inout (Int, Int)) -> Int in
>return pair.0
>defer { pair = (pair.1, pair.0 + pair.1) }
> }
> 
> This would make the intent of the code more clear (return first, then mutate 
> state). Not all cases can benefit from this change, but anytime you exit a 
> scope using a return I think it might be more clear to define the defer after 
> the return. The code would more closely mirror the intent of the code.
> 
> A rule of thumb I’ve come up with for this is that whenever you’re using 
> return to exit a scope, any defer in that same scope should be executed 
> regardless of it’s position in that same scope. This proposal would 
> supplement the way defer currently works.
> 
> What do you all think?
> ___
> swift-evolution mailing list
> swift-evolution@swift.org
> https://lists.swift.org/mailman/listinfo/swift-evolution

___
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


Re: [swift-evolution] [Proposal] A more liberal placement of defer

2016-06-06 Thread Michael Peternell via swift-evolution
Hi,

you may think of `defer` as a function that pushes a block onto an implicit 
cleanup stack that is part of every lexical closure. On each scope exit, all 
blocks from its cleanup stack are popped and executed.

E.g.:

func f(x: Int) {
defer { print("A"); }
defer { print("B"); }
if x == 3 {
return
}
defer { print("C"); }
}

So, f(2) will print "CBA", but f(3) will print "BA" instead. Furthermore, this 
will change semantics and break the following code:

func g(x: Int) {
defer { print("A"); }
let b: Int
if x == 3 {
return
} else {
b = x
}
defer { print("b is \(b)") }
}

In the code above, b is only defined if x is not 3. If x is 3, the last `defer` 
block cannot be called, and that code would no longer compile.

So I think the current language behavior is more powerful. `defer` is usually 
used to do cleanup work, and it is called near the place where some resource is 
initialized. Putting a `defer` block to the end of a function kinda defeats its 
purpose. And simple functions like fibonacci I would just write without using 
`defer` at all - it's just confusing to use `defer` and `inout` in this case 
IMO.

/// Calculates the n'th fibonacci number. (n >= 1)
func fibonacci(n: Int) -> Int {
var a = 0
var b = 1
for _ in 1...n {
(a,b)=(b, a+b)
}
return a
}

Regards,
Michael


> Am 06.06.2016 um 21:50 schrieb donny wals via swift-evolution 
> :
> 
> Hi,
> 
> When we’re using defer we write some code that we want to execute the moment 
> a scope exits.
> This leads to code that could read like:
> 
> let fibonacci = sequence(state: (0, 1)) { (pair: inout (Int, Int)) -> Int in
>defer { pair = (pair.1, pair.0 + pair.1) }
>return pair.0
> }
> 
> What I find strange about this is that we have to write the code that we want 
> to execute after the return before the return.
> 
> I’d like to propose a change to defer that would allow the above code to be 
> written as:
> 
> let fibonacci = sequence(state: (0, 1)) { (pair: inout (Int, Int)) -> Int in
>return pair.0
>defer { pair = (pair.1, pair.0 + pair.1) }
> }
> 
> This would make the intent of the code more clear (return first, then mutate 
> state). Not all cases can benefit from this change, but anytime you exit a 
> scope using a return I think it might be more clear to define the defer after 
> the return. The code would more closely mirror the intent of the code.
> 
> A rule of thumb I’ve come up with for this is that whenever you’re using 
> return to exit a scope, any defer in that same scope should be executed 
> regardless of it’s position in that same scope. This proposal would 
> supplement the way defer currently works.
> 
> What do you all think?
> ___
> swift-evolution mailing list
> swift-evolution@swift.org
> https://lists.swift.org/mailman/listinfo/swift-evolution

___
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


[swift-evolution] [Proposal] A more liberal placement of defer

2016-06-06 Thread donny wals via swift-evolution
Hi,

When we’re using defer we write some code that we want to execute the moment a 
scope exits.
This leads to code that could read like:

let fibonacci = sequence(state: (0, 1)) { (pair: inout (Int, Int)) -> Int in
defer { pair = (pair.1, pair.0 + pair.1) }
return pair.0
}

What I find strange about this is that we have to write the code that we want 
to execute after the return before the return.

I’d like to propose a change to defer that would allow the above code to be 
written as:

let fibonacci = sequence(state: (0, 1)) { (pair: inout (Int, Int)) -> Int in
return pair.0
defer { pair = (pair.1, pair.0 + pair.1) }
}

This would make the intent of the code more clear (return first, then mutate 
state). Not all cases can benefit from this change, but anytime you exit a 
scope using a return I think it might be more clear to define the defer after 
the return. The code would more closely mirror the intent of the code.

A rule of thumb I’ve come up with for this is that whenever you’re using return 
to exit a scope, any defer in that same scope should be executed regardless of 
it’s position in that same scope. This proposal would supplement the way defer 
currently works.

What do you all think?
___
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution