Hacker News new | ask | show | jobs
by unilynx 586 days ago
> navigator.locks.request("my_resource", async (lock) => {

This would be so much more readable with `using`

  {
    using lock = navigator.lock('my_resource');
    await do_something();
    await do_something_else();
  }
(https://github.com/tc39/proposal-explicit-resource-managemen...)
6 comments

It doesn't actually feel more readable to me. I find the idea that the lock declaration sits at the same level as the lock content confusing.
It's readable if you're familiar with the RAII pattern which is used in languages like C++ and Go.
It's also similar to C#'s "using ...;" without a block. Syntax sugar there rather than RAII, but looks the same.
C#'s using can be used without a block. It disposes the resource at the end of a current scope.
I always felt that pattern was a bit too clever than it was a good design.
Makes me wonder what part of the pattern you think is "too clever"? I think it is fairly easy to reason about when the lock is restricted to the encompassing block and automatically dropped when you leave the block.
It’s kind of a weird design that some of your variables (which you can define anywhere in the scope FWIW) just randomly define a critical section. I strongly prefer languages that do a

  with lock {
      // do stuff 
  }
design. This could be C++ too to be honest because lambdas exist but RAII is just too common for people to design their locks like this.
Well, Go doesn't quite support RAII.

This syntax looks more like Python or Rust.

It's not RAII, but closer to dynamic-wind.
Yes, it sits at the same level to signify the lifetime of the lock.
Why can't we just `await` the lock call?

Edit: Nevermind, release of the lock is automatic when the callback resolves its promise. I get it now.

If you really wanted it to be at the top level you could probably turn it into an explicit `release` call using a wrapper and two `Promise` constructors, though that would probably be a bad idea since it could introduce bugs
Subjectiveness aside on what’s more readable… your proposing a new language feature would be more readable than an API design. To me, the MDN proposal is declarative whereas your proposal is imperative. And with my subjectiveness, JavaScript shines in declarative programming.

   navigator whileLocked:'my_resource' do:{ :protected |
      protected doSomething.
      protected doOtherThing.
   }
You can probably wrap it to have that API
Sadly it needs a language feature that doesn't exist yet
What do you mean? You can definitely already wrap that into a Symbol.dispose-keyed object and use it via `using`
`using` is not a thing in JS
Uh, you are wrong. It absolutely is a thing and it has been in your browser and Node for longer than a year.

https://github.com/nodejs/node/pull/48518 https://github.com/tc39/proposal-explicit-resource-managemen...

s/yet/thankfully/. We don’t need it cause it solves no real problem and the solution is loaded with implicit complexity.
'using' fixes having to do cleanup in a finally {} handler, which you can a) forget, and b) often messes up scoping of variables as you need to move them outside the 'try' block.
It also creates additional finalization semantics for a using-ed value. Which has all sorts of implications. lock.do(async (lock) => {work}) is a similar construct - a scope-limited aquisition that requires nothing special.

Catch/finally not sharing a scope with try is a repeated mistake, that I surely agree with!

If it only weren’t for that crippled "using" syntax. On the other hand, though:

    const denialOfService = res => void navigator.lock(res);
I mean, one might write this just as well with the callback interface, but this is much easier to do accidentally.