Closed joeedh closed 4 months ago
There are two scenarios for an "anonymous using
":
using
without introducing a bindingusing
in an expression positionFor "using
without introducing a binding", we have the Discard Binding proposal. This was originally part of this proposal but was cut prior to Stage 3 and is instead being pursued as a separate proposal. Supporting locking scenarios is a major motivation for this proposal since we have been discussing the introduction of Mutex in the Shared Structs proposal:
{
// take exclusive lock over some shared data
using void = new UniqueLock(mutex);
doSomethingWithSharedData(sharedData);
} // lock is released
For "using
in an expression position", explicit syntax for that was rejected for the following reasons:
using
MemberExpression is ambiguous with CallExpression:
const x = using (y);
const x = using (y).z;
using
and await using
are explicitly discoverable at the start of a Statement:
{
using x = ...;
await using y = ...;
}
vs.
{
const x = someArbitrarilyLongAndComplexExpression1(using ...);
const y = someArbitrarilyLongAndComplexExpression2(await using ...);
}
(2) is especially important for await using
since it introduces an implicit await
at the end of the block.
However, you can still achieve "using
in an expression position" through the use of DisposableStack
/AsyncDisposableStack
, which still maintains the invariant in (2):
{
await using stack = new AsyncDisposableStack();
const x = someArbitrarilyLongAndComplexExpression1(stack.use(...));
const y = someArbitrarilyLongAndComplexExpression2(stack.use(...));
}
I was wondering why a syntax like
using lock()
is not in the proposal. I couldn't find much public discussion of it, but while perusing the standard I noticed thisIs this the reason why anonymous
using
is not supported, to avoid ASI hacks? It would be really nice to haveusing object.lock()
but I can see how adding yet more grammar hacks to the language might not be a good idea.