Feature Suggestion: defer and early

defer is built into the language to ease handling a finaliziation where multiple code flow paths are available.

But defer is usually complementrarty to an action that is planned to happen at the begining of the method, examples come to mind


  • Transcations handling (The defer example used on 106 - What's New in Swift 45:19)
  • Timeing execution time (take system time at the begining, take system time at end) of methods
  • Pull semaphore lock queue -> ..use.. -> Return semaphore to queue
  • and co.


There I think it's wise to add an early keyword that will happen when method starts, which is followed by a defer that will happen when function ends. Then followed by the body of the method itself.


As an example, taken from the mentioned 106 WWDC'15 talk:


func processSale(json: AnyObject) throws {
  early { delegate?.didBeginReadingSale() }
  defer { delegate?.didEndReadingSale() }

  guard let buyerJson = json["buyer"] as? NSDictionaey {
    throw DataError.MissingBuyer
  }

  let buyer = try processPerson(buyerJson)
  guard let price = json["price"] as? Int {
    throw DataError.MissingPrice
  }

  return Sale(buyer, price)
}


In this example you can clearly distinguishe between code responsible for "wrapping" the logic and the logic inself. I think it's awesome, and would apprecite feedback.


-m

But semantically there seems to be absolutely no difference in writing

early { delegate?.didBeginReadingSale() }
defer { delegate?.didEndReadingSale() }

vs

delegate?.didBeginReadingSale()
defer { delegate?.didEndReadingSale() }

So it would just be a noop in your example.

As you said: defer is there because there an be muliple code paths for exiting the function. But there is only one code path for entering the function.

I my opinion there is no point for "early". I would make the code just less readable:

early { A() }
defer { B() }

doStuff()

// more stuff...

early { C() }
defer { D() }

doMoreStuff()

Order of Execution:

A, C, doStuff, doMoreStuff, D, B

Not intuitive at all.

When I read code from top to bottom, I would like rely upon that the order I read it is the order it is executed. The defer statement is acceptable because I can just skip at during reading. But the early statement would mix it all up because I could not read just the upper part of the function without checking if anywhere further down an early statement is used. Imagine a function with 50+ lines of code.

Agreed, this would be terribly confusing.

Feature Suggestion: defer and early
 
 
Q