Scope Guard Statements
The D programming language have a feature I'm fond off called Scope Guard Statements
Go also have a variant of that feature called defer.
The feature works like this:
r = acquire_resource()
scope(exit) {r.release()}
// Do stuff with r without worrying about releasing it
The scope guard block will be executed when the current scope is exited. Under the hood, it's just syntactic sugar for try / finally.
It's also possible to do scope(success) and scope(failure) which does the same thing but one runs if the scope exits without exception and the other when it exits with exception.
Any proposed syntaxes, suggested compilations and/or use cases?
I'm in favor of this.
In Python, this feature is called a context block and it uses the with statement:
with open('readme.md', 'rU') as f:
for line in f:
print line.strip().lower()
which is sugar for:
f = open('readme.md', 'rU')
f.__enter__()
try:
for line in f:
print line.strip().lower()
finally:
f.__exit__()
All the details as well as a ton of use-cases can be found in the with-statement PEP.
Unfortunately, JavaScript has uselessly commandeered the with keyword, and Coco has carried on that tradition by recycling it as IIFE sugar. As an alternative keyword, I'd suggest using or closing, both in the form using VAR = EXPR.
Again, this proposal needs syntaxes/compilations/use-cases in JS.
I think that this is most useful for I/O, and that's async in node. Therefore, I think this also needs to be able to span async stuff. As long as we don't have a bunch of special syntax for that, we IMO have to either mark the end somehow (which defeats the whole point of this), or we patch the callback so that it closes stuff. Contrived example:
getServerID = (server, cb) ->
cbCalled = false
cb calling (return if cbCalled; cbCalled = true)
socket = net.connect 1234, server
socket.setEncoding \utf8
cb calling socket.destroy!
<- socket.on \connect
data = ''
socket.on \data, (chunk) ->
data += chunk
cb data if (data.indexOf \\n) > -1
socket.on \close, -> cb
Transformation:
<name> calling <function body>
is the same as
<tempvar> = <name>
<name> = ->
<function body>
<tempvar>...
Example:
cb calling (return if cbCalled; cbCalled = true)
is the same as
cb_ = cb
cb = ->
return if cbCalled
cbCalled = true
cb_ ...
Or in JS:
var cb_ = cb;
cb = function() {
if (cbCalled) return;
cbCalled = true;
cb_.apply(this, arguments);
};
Of course, there's probably some better name than calling.