Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Cover using statement #86

Closed
wants to merge 5 commits into from
Closed

Cover using statement #86

wants to merge 5 commits into from

Conversation

rbuckton
Copy link
Collaborator

@rbuckton rbuckton commented May 24, 2022

This adds a tentative cover grammar to reintroduce UsingStatement and removes using await const, per this comment. Specifically, the following syntax is used:

// Synchronous dispose:

// UsingStatement[~Await]:
using (x = expr) { ... } // NOTE: was `using (const x = expr) { ... }`
using (void = expr) { ... } // NOTE: was `using (expr) { ... }`

// UsingDeclaration:
using x = ...; // NOTE: was `using const x = ...`
using void = ...; // NOTE: was `using const void = ...`

// `using` in ForDeclaration
for (using x of ...) { } // NOTE: was `for (using const x of ...)`

// Asynchronous dispose:

// UsingStatement[+Await]:
using await (x = expr) { ... } // NOTE: was `using await (const x = expr) { ... }`
using await (void = expr) { ... } // NOTE: was `using await (expr) { ... }`

// NOTE: `using await const x = ...` has been removed
// NOTE: `using await const void = ...` has been removed
// NOTE: `for (using await const x of ...)` has been removed

const has been removed from all declarations/statements in favor of treating using as a contextual keyword. This helps to reinforce that using has different behavior from a normal const in that it has side effects at the end of the block, does not allow destructuring, and supports the void = form which allows capturing a resource for disposal without introducing a binding. We have also dropped the using (expr) { ... } form in favor of the using (void = expr) { ... } form which is more consistent between the statement and declaration forms.

These changes help to create a clear parallel between the using Declaration and using Statement:

{
  using x = expr1, y = expr2;
  ...;
}
// is analogous to
using (x = expr1, y = expr2) {
  ...;
}

As well as a clear parallel between the using Statement and using await Statement:

using (x = expr1, y = expr2) { ... }

// is analogous to

using await (x = expr1, y = expr2) { }

This allows us to continue to have first-class syntax support for Symbol.asyncDispose (via the using await statement), as well as RAII-style resource declaration for Symbol.dispose (via the using declaration). We can then potentially introduce a using await declaration form in the future if we find an acceptable compromise regarding the implicit await at the end of the block.

@github-actions
Copy link

A preview of this PR can be found at https://tc39.es/proposal-explicit-resource-management/pr/86.

@rbuckton rbuckton mentioned this pull request May 24, 2022
@bergus
Copy link

bergus commented May 24, 2022

You might want to mention that the using block allows destructuring:

using (const {pattern,} = ) {  }

Also this allows asynchronous iteration of async disposables:

for await (using x of …) { … }

@rbuckton
Copy link
Collaborator Author

You might want to mention that the using block allows destructuring:

using (const {pattern,} = ) {  }

This is explicitly forbidden. The UsingStatement production has the following definition:

UsingStatement[Yield, Await] :
  `using` `(` `const` BindingList[+In, ?Yield, ?Await, +Using] `)` [no LineTerminator here] Block[?Yield, ?Await]
  [+Await] `using` `await` `(` `const` BindingList[+In, ?Yield, +Await, +Using] `)` [no LineTerminator here] Block[?Yield, +Await]

In both cases, +Using is passed to BindingList, which disallows binding patterns.

Also this allows asynchronous iteration of async disposables:

for await (using x of …) { … }

No it does not. This allows asynchronous iteration of synchronous disposables only. You must use using await (...) for any async disposable with these changes.

@rbuckton rbuckton marked this pull request as draft May 25, 2022 23:13
@rbuckton rbuckton marked this pull request as ready for review August 5, 2022 23:16
@rbuckton
Copy link
Collaborator Author

rbuckton commented Sep 2, 2022

Closing for now in favor of #89.

@rbuckton rbuckton closed this Sep 2, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants