4 ms·
I think Swift’s defer (https://docs.swift.org/swift-book/documentation/the-swift-programming-language/statements/#Defer-Statement https://docs.swift.org/swift-b
by Someone 10mo ago
I think Swift’s defer (https://docs.swift.org/swift-book/documentation/the-swift-programming-language/statements/#Defer-Statement https://docs.swift.org/swift-book/documentation/the-swift-pr...) was inspired by/copied from go (https://go.dev/tour/flowcontrol/12 https://go.dev/tour/flowcontrol/12), but they may have taken it from an even earlier language that I’m not aware of.
Defer has two advantages over try…finally: firstly, it doesn’t introduce a nesting level.
Secondly, if you write
foo
defer revert_foo
, when scanning the code, it’s easier to verify that you didn’t forget the revert_foo part than when there are many lines between foo and the finally block that calls revert_foo.
A disadvantage is that defer breaks the “statements are logically executed in source code order” convention. I think that’s more than worth it, though.
- mojuba 10mo agoYeah, it's especially handy in UI code where you can have asynchronous operations but want to have a clear start/end indication in the UI: busy = true Task { defer { busy = false } // do async stuff, possibly throwing exceptions and whatnot }
- kibwen 10mo agoI'll disagree here. I'd much rather have a Python-style context manager, even if it introduces a level of indentation, rather than have the sort of munged-up control flow that `defer` introduces.
- Someone 10mo agoI can see your point, but that (https://book.pythontips.com/en/latest/context_managers.html https://book.pythontips.com/en/latest/context_managers.html) requires the object you’re using to implement __enter__ and __exit__ (or, in C#, implement IDisposable (https://learn.microsoft.com/en-us/dotnet/csharp/language-reference/statements/using https://learn.microsoft.com/en-us/dotnet/csharp/language-ref...), in Java, implement AutoCloseable (https://docs.oracle.com/javase/tutorial/essential/exceptions/tryResourceClose.html https://docs.oracle.com/javase/tutorial/essential/exceptions...); there likely are other languages providing something similar). Defer is more flexible/requires less boilerplate to add callsite specific handling. For an example, see https://news.ycombinator.com/item?id=46410610 https://news.ycombinator.com/item?id=46410610
- Snarwin 10mo agoThe oldest defer-like feature I can find reference to is the ON_BLOCK_EXIT macro from this article in the December 2000 issue of the C/C++ Users Journal: https://jacobfilipp.com/DrDobbs/articles/CUJ/2000/cexp1812/alexandr/alexandr.htm https://jacobfilipp.com/DrDobbs/articles/CUJ/2000/cexp1812/a... A similar macro later (2006) made its way into Boost as BOOST_SCOPE_EXIT: https://www.boost.org/doc/libs/latest/libs/scope_exit/doc/html/index.html https://www.boost.org/doc/libs/latest/libs/scope_exit/doc/ht... I can't say for sure whether Go's creators took inspiration from these, but it wouldn't be surprising if they did.