frontpage.
newsnewestaskshowjobs

Made with ♥ by @iamnishanth

Open Source @Github

JavaScript's New Superpower: Explicit Resource Management

https://v8.dev/features/explicit-resource-management
85•olalonde•5h ago•52 comments

Getting AI to write good SQL

https://cloud.google.com/blog/products/databases/techniques-for-improving-text-to-sql
358•richards•13h ago•182 comments

Wow@Home – Network of Amateur Radio Telescopes

https://phl.upr.edu/wow/outreach
123•visviva•8h ago•7 comments

XTool – Cross-platform Xcode replacement

https://github.com/xtool-org/xtool
113•TheWiggles•8h ago•31 comments

A Linux kernel developer plays with Home Assistant: general impressions

https://lwn.net/SubscriberLink/1017720/7155ecb9602e9ef2/
98•pabs3•7h ago•36 comments

Catalog of Novel Operating Systems

https://github.com/prathyvsh/os-catalog
23•prathyvsh•3h ago•3 comments

Thoughts on thinking

https://dcurt.is/thinking
462•bradgessler•15h ago•300 comments

Popcorn: Run Elixir in WASM

https://popcorn.swmansion.com/
22•clessg•1d ago•2 comments

A Research Preview of Codex

https://openai.com/index/introducing-codex/
434•meetpateltech•19h ago•368 comments

Implementing a RISC-V Hypervisor

https://seiya.me/blog/riscv-hypervisor
8•ingve•3h ago•0 comments

New high-quality hash measures 71GB/s on M4

https://github.com/Nicoshev/rapidhash
68•nicoshev11•3d ago•27 comments

Show HN: Fahmatrix – A Lightweight, Pandas-Like DataFrame Library for Java

https://github.com/moustafa-nasr/fahmatrix
28•mousomashakel•6h ago•5 comments

MIT asks arXiv to withdraw preprint of paper on AI and scientific discovery

https://economics.mit.edu/news/assuring-accurate-research-record
313•carabiner•19h ago•162 comments

Rustls Server-Side Performance

https://www.memorysafety.org/blog/rustls-server-perf/
116•jaas•3d ago•31 comments

MCP: An in-depth introduction

https://www.speakeasy.com/mcp/mcp-tutorial
86•ritzaco•3d ago•27 comments

Why Moderna Merged Its Tech and HR Departments

https://www.wsj.com/articles/why-moderna-merged-its-tech-and-hr-departments-95318c2a
8•andy99•3d ago•2 comments

I'm Peter Roberts, immigration attorney, who does work for YC and startups. AMA

220•proberts•19h ago•377 comments

Coding agent in 94 lines of Ruby

https://radanskoric.com/articles/coding-agent-in-ruby
110•radanskoric•2d ago•53 comments

Show HN: Merliot – plugging physical devices into LLMs

https://github.com/merliot/hub
45•sfeldma•9h ago•11 comments

ClojureScript 1.12.42

https://clojurescript.org/news/2025-05-16-release
160•Borkdude•14h ago•29 comments

A Critical Look at "A Critical Look at MCP."

https://docs.mcp.run/blog/2025/05/16/mcp-implenda-est/
30•palmfacehn•2h ago•6 comments

Show HN: Visual flow-based programming for Erlang, inspired by Node-RED

https://github.com/gorenje/erlang-red
226•Towaway69•19h ago•94 comments

Hunting extreme microbes that redefine the limits of life

https://www.nature.com/articles/d41586-025-01464-7
18•gnabgib•2d ago•1 comments

X X^t can be faster

https://arxiv.org/abs/2505.09814
178•robinhouston•19h ago•52 comments

Show HN: KVSplit – Run 2-3x longer contexts on Apple Silicon

https://github.com/dipampaul17/KVSplit
247•dipampaul17•14h ago•36 comments

Fixrleak: Fixing Java Resource Leaks with GenAI

https://www.uber.com/blog/fixrleak-fixing-java-resource-leaks-with-genai/
7•carimura•3d ago•5 comments

A Linux kernel developer plays with Home Assistant: case studies

https://lwn.net/SubscriberLink/1017945/93d12d28178b372e/
59•pabs3•9h ago•35 comments

The first year of free-threaded Python

https://labs.quansight.org/blog/free-threaded-one-year-recap
273•rbanffy•1d ago•267 comments

Java at 30: Interview with James Gosling

https://thenewstack.io/java-at-30-the-genius-behind-the-code-that-changed-tech/
215•chhum•21h ago•306 comments

The Joys of Discovering the Roman Underground

https://www.smithsonianmag.com/travel/the-joys-of-discovering-the-roman-underground-from-the-colosseum-to-whats-beneath-the-trevi-foundation-180986626/
20•ulrischa•1d ago•11 comments
Open in hackernews

JavaScript's New Superpower: Explicit Resource Management

https://v8.dev/features/explicit-resource-management
85•olalonde•5h ago

Comments

qprofyeh•2h ago
Can someone explain why they didn’t go with (anonymous) class destructors? Or something other than a Symbol as special object key. Especially when there are two Symbols (different one for asynchronous) which makes it a leaky abstraction, no?
Garlef•2h ago
Because this approach also works for stuff that is not a class instance.
matharmin•2h ago
Destructors I other languages are typically used for when the object is garbage collected. That has a whole bunch of associated issues, which is why the pattern is often avoided these days.

The dispose methods on the other hand are called when the variable goes out of scope, which is much more predictable. You can rely on for example a file being closed ot a lock released before your method returns.

JavaScript is already explicit about what is synchronous versus asynchronous everywhere else, and this is no exception. Your method needs to wait for disposing to complete, so if disposing is asynchronous, your method must be asynchronous as well. It does get a bit annoying though that you end up with a double await, as in `await using a = await b()` if you're not used to that syntax.

As for using symbols - that's the same as other functionality added over time, such as iterator. It gives a nice way for the support to be added in a backwards-compatible way. And it's mostly only library authors dealing with the symbols - a typical app developer never has to touch it directly.

senfiaj•1h ago
For garbage collected languages destructors cannot be called synchronously in most cases because the VM must make sure that the object is inaccessible first. So it will not work very deterministically, and also will expose the JS VM internals. For that JS already has WeakRef and FinalizationRegistry.

https://waspdev.com/articles/2025-04-09/features-that-every-... https://waspdev.com/articles/2025-04-09/features-that-every-...

But even Mozilla doesn't recommend to use them because they're quite unpredictable and might work differently in different engines.

feverzsj•1h ago
Because javascript is uncivilized.
masklinn•40m ago
Destructors require deterministic cleanup, which advanced GCs can't do (and really don't want to either from an efficiency perspective). Languages with advanced GCs have "finalizers" called during collection which are thus extremely unreliable (and full of subtle footguns), and are normally only used as a last resort solution for native resources (FFI wrappers).

Hence many either had or ended up growing means of scope-based resource cleanup whether,

- HoF-based (smalltalk, haskell, ruby)

- dedicated scope / value hook (python[1], C#, Java)

- callback registration (go, swift)

[1]: Python originally used destructors thanks to a refcounting GC, but the combination of alternate non-refcounted implementations, refcount cycles, and resources like locks not having guards (and not wanting to add those with no clear utility) led to the introduction of context managers

nh2•2m ago
What does "HoF" stand for?
pwdisswordfishz•10m ago
There is no such thing as an anonymous property in JavaScript. Your question doesn't make sense.
demarq•2h ago
So… drop
mettamage•1h ago
What do you mean by that? Is `drop` a language construct in another language?
brigandish•1h ago
It's also in this comment, which reads like Gen Zed slang.

https://news.ycombinator.com/item?id=44012969

dminik•1h ago
Yes, it's called Drop in rust: https://doc.rust-lang.org/std/ops/trait.Drop.html
brigandish•1h ago
Drop?
DemocracyFTW2•1h ago
it's an annoying usage because you never know whether it means "sth new appeared" or "sth old stopped being available"
pacifika•1h ago
Drop and biweekly
CreepGin•2h ago
Need to dig into this more, but I built OneJS [1] (kinda like React Native but for Unity), and at first glance this looks perfect for us(?). Seems to be super handy for Unity where you've got meshes, RenderTextures, ComputeBuffers, and NativeContainers allocations that all need proper disposal outside of JS. Forcing disposal at lexical scopes, we can probs keep memory more stable during long Editor sessions or when hot-reloading a lot.

[1] https://github.com/Singtaa/OneJS

smashah•2h ago
I would like to petition JSLand to please let go of the word "use" and all of its derivatives. Cool feature though, looking forward to using (smh) it.
hahn-kev•1h ago
They're just adopting the same syntax that C# has used for a long time
bvrmn•2h ago
Context managers: exist.

JS: drop but we couldn't occupy a possibly taken name, Symbol for the win!

It's hilariously awkward.

demarq•1h ago
nah, Symbol has been traits for javascript for quite a while eg. Symbol.iterator

It's the "dispose" part where the new name is decided.

masklinn•31m ago
> JS: drop but we couldn't occupy a possibly taken name, Symbol for the win!

You're about a decade late to the party?

That is the entire point of symbols and "well known symbols", and why they were introduced back in ES6.

havkom•1h ago
Reminds me of C#.. IDisposible and IAsyncDisposible in C# helps a lot to write good mechanisms for things that should actually be abstracted in a nice way (such as locks handling, queue mechanisms, temporary scopes for impersonation, etc).
masklinn•12m ago
It's basically lifted from C#'s, the original proposal makes no secret of it and cites all of Python's context managers, Java's try with resources, C#'s using statements, and C#'s using declarations. And `using` being the keyword and `dispose` the hook method is a pretty big hint.
pwdisswordfishz•8m ago
That's because the author of the proposal is from Microsoft and has shot down counter-suggestions that made the syntax look different from C#.
russellbeattie•1h ago
Maybe it's just me, but [Symbol.dispose]() seems like a really hacky way to add that functionality to an Object. Here's their example:

    using readerResource = {
        reader: response.body.getReader(),
        [Symbol.dispose]() {
            this.reader.releaseLock();
        },
    };
First, I had to refresh my memory on the new object definition shorthand: In short, you can use a variable or expression to define a key name by using brackets, like: let key = "foo"; { [key]: "bar"}, and secondly you don't have to write { "baz" : function(p) { ... } }, you can instead write { baz(p) {...} }. OK, got it.

So, if I'm looking at the above example correctly, they're implementing what is essentially an Interface-based definition of a new "resource" object. (If it walks like a duck, and quacks...)

To make a "resource", you'll tack on a new magical method to your POJO, identified not with a standard name (like Object.constructor() or Object.__proto__), but with a name that is a result of whatever "Symbol.dispose" evaluates to. Thus the above definition of { [Symbol.dispose]() {...} }, which apparently the "using" keyword will call when the object goes out of scope.

Do I understand that all correctly?

I'd think the proper JavaScript way to do this would be to either make a new object specific modifier keyword like the way getters and setters work, or to create a new global object named "Resource" which has the needed method prototypes that can be overwritten.

Using Symbol is just weird. Disposing a resource has nothing to do with Symbol's core purpose of creating unique identifiers. Plus it looks fugly and is definitely confusing.

Is there another example of an arbitrary method name being called by a keyword? It's not a function parameter like async/await uses to return a Promise, it's just a random method tacked on to an Object using a Symbol to define the name of it. Weird!

Maybe I'm missing something.

paavohtl•1h ago
JS has used "well-known symbols"[1] to allow extending / overriding the functionality of objects for about 10 years. For example, an object is an iterable if it has a `[Symbol.iterator]` property. Symbols are valid object keys; they are not just string aliases.

[1] https://developer.mozilla.org/en-US/docs/Web/JavaScript/Refe...

demarq•1h ago
Yes you are missing something. You are not supposed to call these methods, they are for the runtime.

more specifically, javascript will call the [Symbol.dispose] when it detects you are exiting the scope of a "using" declaration.

uasi•1h ago
> create a new global object named "Resource" which has the needed method prototypes that can be overwritten.

those methods could conflict with existing methods already used in other ways if you’d want to make an existing class a subclass of Resource.

Spivak•27m ago
I hadn't considered how blessed I was to have __enter__ / __exit__ in Python for context managers and the more general Protocol concept that can be used for anything because lordy that definition looks ugly as sin. Even Perl looks on in horror of the sins JS has committed.
masklinn•4m ago
> To make a "resource", you'll tack on a new magical method to your POJO, identified not with a standard name [...] nothing to do with Symbol's core purpose of creating unique identifiers.

The core purpose and original reason why Symbol was introduced in JS is the ability to create non-conflicting but well known / standard names.

> Is there another example of an arbitrary method name being called by a keyword? It's not a function parameter like async/await uses to return a Promise, it's just a random method tacked on to an Object using a Symbol to define the name of it. Weird!

`Symbol.iterator` called by `for...of` is literally the original use case for symbols.

> I'd think the proper JavaScript way to do this would be to either make a new object specific modifier keyword like the way getters and setters work, or to create a new global object named "Resource" which has the needed method prototypes that can be overwritten.

Genuinely: what are you talking about.

sufianrhazi•1h ago
This is a great upcoming feature, I wrote some practical advice (a realistic example, how to use it with TypeScript/vite/eslint/neovim/etc…) about it a few months ago here: https://abstract.properties/explicit-resource-management-is-...
creata•1h ago
This seems error-prone, for at least two reasons:

* If you accidentally use `let` or `const` instead of `using`, everything will work but silently leak resources.

* Objects that contain resources need to manually define `dispose` and call it on their children. Forgetting to do so will lead to resource leaks.

It looks like defer dressed up to resemble RAII.

akdor1154•1h ago
There is pretty strong precedent for this design over in .NET land - if it was awful or notably inferior to `defer` I'm sure the Chrome engineering team would have taken notice.
creata•53m ago
C# has the advantage of being a typed language, which allows compilers and IDEs to warn in the circumstances I mentioned. JavaScript isn't a typed language, which limits the potential for such warnings.

Anyway, I didn't say it was "inferior to defer", I said that it seemed more error-prone than RAII in languages like Rust and C++.

Edit: Sorry if I'm horribly wrong (I don't use C#) but the relevant code analysis rules look like CA2000 and CA2213.

masklinn•34m ago
> Anyway, I didn't say it was "inferior to defer", I said that it seemed more error-prone than RAII in languages like Rust and C++.

It is, but RAII really isn't an option if you have an advanced GC, as it is lifetime-based and requires deterministic destruction of individual objects, and much of the performance of an advanced GC comes from not doing that.

Most GC'd language have some sort of finalizers (so does javascript: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Refe...) but those are unreliable and often have subtle footguns when used for cleanup.

legulere•16m ago
It’s still difficult to get right in cases where you hold a disposable as a member. Its not obvious if disposables passed in also get disposed and what’s right depends on the situation (think a string based TextWriter getting passed in a byte-based Stream) and you will need to handle double disposes.

Further C# has destructors that get used as a last resort effort on native resources like file descriptors.

creata•9m ago
> Further C# has destructors that get used as a last resort effort on native resources like file descriptors.

True, I was going to mention that, but I saw that JS also has "finalization registries", which seem to provide finalizer support in JS, so I figured it wasn't a fundamental difference.

dgellow•43m ago
C# has `using` that works based on the IDispose pattern

https://learn.microsoft.com/en-us/dotnet/csharp/language-ref...

I agree it’s not too great. defer is so simple and practical in comparison

akoboldfrying•48m ago
Exactly this. No idea why you were downvoted.

The problem they are trying to solve is that the programmer could forget to wrap an object creation with try. But their solution is just kicking the can down the road, because now the programmer could forget to write "using"!

I was thinking that a much better solution would be to simply add a no-op default implementation of dispose(), and call it whenever any object hits end-of-scope with refcount=1, and drop the "using" keyword entirely, since that way programmers couldn't forget to write "using". But then I remembered that JavaScript doesn't have refcounts, and we can't assume that function calls to which the object has been passed have not kept references to it, expecting it to still exist in its undisposed state later.

OTOH, if there really is no "nice" solution to detecting this kind of "escape", it means that, under the new system, writing "using" must be dangerous -- it can lead to dispose() being called when some function call stored a reference to the object somewhere, expecting it to still exist in its undisposed state later.

mistercow•39m ago
Another point there is that JS has always gone to great lengths not to expose the GC in any way. For example, you can’t enumerate a WeakSet, because that would cause behavior to be GC dependent. Calling dispose when an object is collected would very explicitly cause the GC to have semantic effects, and I think that goes strongly against the JS philosophy.
masklinn•33m ago
FinalizationRegistry was added, like, 5 years ago.
rafram•3m ago
Finalizers aren’t destructors. The finalizer doesn’t get access to the object being GC’d, for one. But even more crucially, the spec allows the engine to call your finalizer anywhere between long after the object has been GC’d, and never.

They’re basically a nice convenience for noncritical resource cleanup. You can’t rely on them.

demurgos•40m ago
What you describe is already the status quo today. This proposal is still a big improvement as it makes resource management less error prone when you're aware to use it and _standardizes the mechanism through the symbol_. This enables tooling to lint for the situations you're describing based on type information.
roschdal•1h ago
JavaScript new features: segmentation faults, memory leaks, memory corruption and core dumps.
TekMol•1h ago
Their first example is about having to have a try/finally block in a function like this:

    function processData(response) {
        const reader = response.body.getReader();
        try {
            reader.read()
        } finally {
            reader.releaseLock();
        }
    }
So that the read lock is lifted even if reader.read() throws an error.

Does this only hold for long running processes? In a browser environment or in a cli script that terminates when an error is thrown, would the lock be lifted when the process exits?

teraflop•52m ago
The spec just says that when a block "completes" its execution, however that happens (normal completion, an exception, a break/continue statement, etc.) the disposal must run. This is the same for "using" as it is for "try/finally".

When a process is forcibly terminated, the behavior is inherently outside the scope of the ECMAScript specification, because at that point the interpreter cannot take any further actions.

So what happens depends on what kind of object you're talking about. The example in the article is talking about a "stream" from the web platform streams spec. A stream, in this sense, is a JS object that only exists within a JS interpreter. If the JS interpreter goes away, then it's meaningless to ask whether the lock is locked or unlocked, because the lock no longer exists.

If you were talking about some kind of OS-allocated resource (e.g. allocated memory or file descriptors), then there is generally some kind of OS-provided cleanup when a process terminates, no matter how the termination happens, even if the process itself takes no action. But of course the details are platform-specific.

sylware•1h ago
Still implemented with the super villain language, c++?
master-lincoln•33m ago
It depends on what language the Javascript engine is implemented in. For v8 that's c++ yeah. I would agree with Google being a super villain nowadays, but others use c++ too so I would think it's unfair to call it supervillain language...
the_mitsuhiko•1h ago
This is very useful for resource management of WASM types which might have different memory backing.
ivan_gammel•47m ago
Is it the same as try with resources in Java?

   try(var reader = getReader()) {
       // do read
   } // auto-close
masklinn•27m ago
It's similar, but more inspired by C#'s "using declaration", an evolution of the using blocks, which are the C# version of try-with-resource: `using` declarations don't introduce their own block / scope.

The original proposal references all of Python's context manager, Java's try-with-resource, and C#'s using statement and declaration: https://github.com/tc39/proposal-explicit-resource-managemen...

mattmanser•24m ago
Yeah, as someone else has pointed out it's C# inspired, this is a C# example:

    public void AMethod() {
        //some code
        using var stream = thing.GetStream();
        //some other code
        var x = thing.ReadToEnd();
        //file will be automatically disposed as this is the last time file is used
        //some more code not using file
    } //any error means file will be disposed if initialized
You can still do the wrap if you need more fine grained control, or do anything else in the finally.

You can even nest them like this:

    using var conn = new SqlConnection(connString);
    using var cmd = new SqlCommand(cmd);
    conn.Open();
    cmd.ExecuteSql();

Edit: hadn't read the whole article, the javascript version is pretty good!