Hacker News new | past | comments | ask | show | jobs | submit login
Go 1.24 (golang.org)
165 points by TriangleEdge 80 days ago | hide | past | favorite | 17 comments



Discussion (129 points, 6 days ago, 17 comments) https://news.ycombinator.com/item?id=43017348

Related

Go 1.24's go tool is one of the best additions to the ecosystem in years (290 points, 21 days ago, 194 comments) https://news.ycombinator.com/item?id=42845323

Microsoft Go 1.24 FIPS changes (84 points, 11 days ago, 62 comments) https://news.ycombinator.com/item?id=42965404


The introduction of the much more sane omitzero (in addition to the current omitempty) to the stdlib JSON package is quite nice.


Just fixed a bug where this behaviour bit us. Nice change, although I feel structtags harm us more than they provide.


It's a lowlight in the language in my opinion; while adding metadata to fields is neat, putting it in an untyped string where the parsing is left to the library is far from ideal. I'm pretty sure that eventually the language will move away from struct tags in favor of a language construct like annotations in other languages, but like with error handling, this will be a long and slow process.


I disagree. Hardly doubt golang will break existing code for that, especially considering that structtags are parsed at compile time. It makes a lot of sense to me that the compiler couldn’t care less about it, when that is 100% a library construct.


Finally,

   Timestamp time.Time `json:"timestamp,omitzero"`


Can someone dumb it down for me how the new runtime.AddCleanup is different from much-disliked finalizers in java?


The most important difference is that runtime.AddCleanup doesn't pass a reference to the decedent object to the cleanup callback.

This is a big deal, because it means that, once the callback is called, you know that the object is completely dead and will never be reachable by anything ever again. By contrast, if the callback receives a reference to the object as an argument, then it is only mostly dead, because it is still reachable through that reference. If the callback stores a copy of that reference elsewhere before it returns, then the object is no longer unreachable, and the garbage collection that triggered the callback has to be cancelled. This is called "object resurrection" and it can cause all kinds of horrible chaos, e.g., by allowing an object that's part of a reference cycle to be observed in a partially-cleaned-up state wherein its internal invariants might be violated. Writing code that correctly deals with the possibility of object resurrection is very difficult.

By contrast, runtime.AddCleanup mostly works the way you'd expect. There is one footgun, which is that, if the object to be cleaned up is reachable from the cleanup callback, then this will prevent it from ever becoming eligible for garbage collection, it will live forever, and the cleanup callback will never run. You have to be careful not to let that happen. But the consequence of messing this up is merely a resource leak, which is generally much less bad than the kinds of state corruption that object resurrection can cause.

Lots of programming languages with garbage collection went through the cycle of starting out with a finalization API that allowed object resurrection, realizing that this was a bad idea, and deprecating it or discouraging its use in favor of a new API that doesn't have this problem. E.g., Go now recommends runtime.AddCleanup over runtime.SetFinalizer, Java now recommends java.lang.ref.Cleaner over Object.finalize, and Python now recommends weakref.finalize over __del__. JavaScript was fortunate in that it didn't gain support for any kind of finalization until 2021, by which time the hazards of object resurrection were well-understood, so it only has the good API and not the dangerous one.


Small hint, JavaScript is in the process of getting a dispose like API, already at stage 3.

https://github.com/tc39/proposal-explicit-resource-managemen...


Good read about this if you are using Typescript and want to start using it now (pun inteded): https://www.totaltypescript.com/typescript-5-2-new-keyword-u...


Note that the new disposable protocol in JavaScript is unrelated to garbage collection; it's more like Go's `defer`. The grandparent is talking about JavaScript's somewhat older FinalizationRegistry.


Sure, just like in many other languages with automatic memory management.


And C# was heavy on `Finalize()`, but now is all about `using/Dispose()`.


This is Go, yet add again, catching up to the lessons learned by the other programming language communities.

As you point out, finalizers are no longer in good grace in Java, not even in .NET, but lets leave that for another thread.

Hence why they are deprecated since Java 9, released in 2017, and a Cleaner queue should be used instead, or try-with-resources.

https://docs.oracle.com/javase/9/docs/api/java/lang/Object.h...

Basically runtime.AddCleanup() is the Go's version of java.lang.ref.Cleaner::register().


It would be better if they didn't learn from the others


Can you explain? Because if you don't learn from others you're cursed to repeat the same mistakes. I like to mention Java's generics implementation making up half the language spec and compiler.


"We're special. Hmm, okay that didn't work". Every Go feature.




Consider applying for YC's Summer 2025 batch! Applications are open till May 13

Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: