Hacker Newsnew | past | comments | ask | show | jobs | submit | dangoodmanUT's commentslogin

I thought fly.io snapshots weren't guaranteed to stick around? Although I can can't find the docs mentioning it, but i checked within the last few months... maybe they changed it?

More complicated than that, but with respect to Sprites --- this is a totally new stack.

waiting for someone to say "this wouldn't have happen if you chose rust"

You’ll probably be waiting a long time, since Rust very explicitly doesn’t have “leak safety” as a constructive property. Safe Rust programs are allowed to leak memory, because memory leaks themselves don’t cause safety issues.

There’s even a standard, non-unsafe API for leaking memory[1].

(What Rust does do is make it harder to construct programs that leak memory unintentionally. It’s possible but not guaranteed that a similar leak would be difficult to express idiomatically in Rust.)

[1]: https://doc.rust-lang.org/std/boxed/struct.Box.html#method.l...


The specific language feature you want if you insist that you don't want this kind of leak is Linear Types.

Rust has Affine Types. This means Rust cares that for any value V of type T, Rust can see that we did not destroy V twice (or more often).

With Linear Types the compiler checks that you destroyed V exactly once, not less and not more.

However, one reason I don't end up caring about Leak Safety of this sort is that in fact users do not care that you didn't "leak" data in this nerd sense. In this nerd sense what matters is only leaks where we lost all reference to the heap data. But from a user's perspective it's just as bad if we did have the reference but we forgot - or even decided explicitly not - to throw it away and get back the RAM.

The obvious way to make this mistake "by accident" in Rust is to have two things which keep each other alive via reference counting and yet have been disconnected and forgotten by the rest of the system. A typical garbage collected language would notice that these are garbage and destroy them both, but Rust isn't a GC language of course. Calling Box::leak isn't likely to happen by accident (though you might mistakenly believe you will call it only once but actually use it much more often)

I think the main part of Ghostty's design mentioned here that - as a Rust programmer - I think is probably a mistake is the choice to use a linked list. To me this looks exactly like it needs VecDeque, a circular buffer backed by a growable array type. Their "clever" typical case where you emit more text and so your oldest page is scrapped and re-used to form your newest page, works very nicely in VecDeque, and it seems like they never want the esoteric fast things a linked list can do, nor do they need multi-writer concurrency like the guts of an OS kernel, they want O(1) pop & push from opposite ends. Zig's Deque is probably that same thing but in Zig.


The issue isn’t linked list vs dequeue but type confusion about what was in the container. They didn’t forget to drop it - they got confused about which type was in the list when popping and returned it to the pool instead of munmap.

The way to solve this in Rust would be to put this logic in the drop and hide each page type in an enum. That way you can’t ever confuse the types or what happens when you drop.


Was going to say this, but I don't think anyone actually wants to hear that Rust actually would have helped here.

As you're saying, the bug was the equivalent of an incorrectly written Drop implementation.

Nothing against Zig, and people not using Rust is just fine, but this is what happens when you want C-like feel for your language. You miss out on useful abstractions along with the superfluous ones.

"We don't need destructors, defer/errdefer is enough" is Zig's stance, and it was mostly OK.

Impossible to predict this kind of issue when choosing a project language (and it's already been discussed why Zig was chosen over Rust for Ghostty, which is fine!), so it's not a reason to always choose Rust over Zig, but sometimes that slightly annoying ceremony is useful!

Maybe some day I'll be smart enough to write Zig as a default over Rust, but until that day I'm going to pay the complexity price to get more safety and keep more safety mechanisms on the shotgun aimed at my foot. I've got plenty of other bugs I can spend time writing.

Another good example is the type vs type alias vs wrapper type debate. It's probably not reasonable to use a wrapper type every single time (e.g. num_seconds probably can probably be a u32 and not a Seconds type), but it's really a Rorschach test because some people lean towards one end versus the other for whatever reason, and the plusses/minuses are different depending on where you land on the spectrum.

[EDIT] also some good discussion here

https://ziggit.dev/t/zig-what-i-think-after-months-of-using-...


> I think the main part of Ghostty's design mentioned here that - as a Rust programmer - I think is probably a mistake is the choice to use a linked list. To me this looks exactly like it needs VecDeque, a circular buffer backed by a growable array type.

This comment [0] by mitchellh on the corresponding lobste.rs submission discusses the choice of data structure a bit more:

> Circular buffer is a pretty standard approach to this problem. I think it's what most terminal emulators do.

> The reason I went with this doubly linked list approach with Ghostty is because architecturally it makes it easier for us to support some other features that either exist or are planned.

> As an example of planned, one of the most upvoted feature requests is the ability for Ghostty to persist scroll back across relaunch (macOS built-in terminal does this and maybe iTerm2). By using a paged linked list architecture, we can take pages that no longer contain the active area (and therefore are read-only) and archive them off the IO thread during destroy when we need to prune scroll back. We don't need to ever worry that the IO thread might circle around and produce a read/write data race.

> Or another example that we don't do yet, we can convert the format of scroll back history into a much more compressed form (maybe literally compressed memory using something like zstd) so we can trade off memory for cpu if users are willing to pay a [small, probably imperceptible] CPU time cost when you scroll up.

[0]: https://lobste.rs/s/vlzg2m/finding_fixing_ghostty_s_largest_...


The UI animations are so fun

yeah, nothing hits like dark sky hit

This definitely will handle large files or binary files very poorly

More related to the title, i've found the same.

I was always an aggressive pixel-pusher, so web dev took me AGES.

But with shadcn + llms I'm flying through stuff, no lie, 5-20x faster than I was before.

And i dont hate it anymore


This seems CDC based, does that mean it handles `now()` and other non-deterministic functions properly?

Yes! Changes are deterministic.

This is similar to what rivet (1) does, perhaps focusing more on stateless than rivet does

(1) https://www.rivet.dev/docs/actors/


A tool that I made a while back that has become a staple in everything I build, I started wanting kustomize-like functionality within environments.

The use case originally was having a simple overlay of S3 environment variables for testing so that they'd use a shared test bucket to provide agents with files, but otherwise we can use a local S3 (garage) when building.

That turned into "overlay environments": you can overlay them on top of each other just like an overlayfs, but for environment variables :)

HN link seems to strip the URL fragments, here's the direct link to the feature: https://github.com/danthegoodman1/EpicEnv/tree/main?tab=read...


dwight shrute detected

At least spell my name correctly ffs, it's right there in the org chart

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

Search: