12,853 karma · joined January 16, 2013
It's great that there are lots of options other than wrapping as well, checked, saturating, etc -- that at the cost of a little inefficiency make code that is robust to such failures really obvious.
Absolutely, I meant them.
> This is trivially false... for instance here's a line:
Yep, that was really wrongly stated on my part -- what I meant is that the kind of protections that "safe" Rust provides are not available anywhere in average lines of Zig code (though they can be detected with tooling, etc).
What I should have written is that I could easily write unsafe code anywhere in Zig (as in C). In practice of course most people don't because they're not trying to destroy their own computers, and most code is benign. Rust will at least save me from myself some of the time.
> Also IMO the word "safety" should include integer overflow. I don't agree that those kind of bugs are so unimportant as to not be checked in safe builds.
Rust does do some work to catch trivial overflows, but you're right that it does not catch any slightly more complex overflows, and that is certainly unsafe in a sense. I don't think any reasonable person would disagree with that.
Rust's answer to this of course is checked_{op}/wrapping_{op}/etc options, and that's what I often see in high quality codebases where it matters. Of course, this is a footgun that could have had a safety applied and it's too late now (AFAIK) to change the default to be always wrapping or something (also, I think people may oppose always checked for perf reasons).
[EDIT] Just to compare/make this more concrete, playgrounds:
https://zig.fly.dev/p/LGnrBGXPlVJ
https://play.rust-lang.org/?version=stable&mode=release&edit...
Rust in this case of doing something obviously wrong is at least a little more helpful -- the obvious overflow does not compile.
And of course you can get rust to do it like it allows (and what would be present in any codebase with real complexity):
https://play.rust-lang.org/?version=stable&mode=release&edit...
It's just that little bit of safety that makes it easy for me (personally) to default to Rust. Very possible that someday that won't be true.
[EDIT2] Also, somewhat under-discussed, but if Zig supported a bolt-on a "safety check compile mode" that ran with some stricter (maybe not quite borrow checking level) semantics, that would be pretty dope. Of course not something anyone should devote any real time to for a long time (or ever?) BUT it would trivialize a lot of these discussions maybe.
But in the mean time people just using what they're comfortable with/the feel they want is obviously fine.
Clearly, the current state of things was not enough.
Yea, but not for all the parts — being able to isolate the unsafe and build abstractions that ensure certain usage parts of the unsafe stuff is a key part of high quality rust code that uses unsafe.
In this case though I think the emphasis is on the fact that there is a place where that code should have been in Rust land, and writing that function would have made it clear and likely avoided the confusion.
Less about unsafe and more about the resulting structure of code.
> Actually you'd be in a worse boat because Zig is safer than unsafe Rust
Other people have mentioned it but I disagree with this assertion.
Its a bit simplistic but I view it this way — every line of C/Zig is unsafe (lots of quibbling to do about what “unsafe” means of course) while some lines of rust are unsafe. Really hard for that assertion to make sense under that world view.
That said, I’m not gonna miss this chance to thank you and the Zig foundation and ecosystem for creating and continuously improving Zig! Thanks for all the hard work and thoughtful API design that has sparked conversation and progress.
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-...
Sure, I could piece together or write something myself to catch the CDC stream or run another replica, but simply running one more process on one of the boxes and having peace of mind that there’s an S3 backup continuously written is quite nice.
I thought debezium was mostly for moving around CDC records, not a backup tool per say. I.e. if I were to write debezium records to object storage with their connectors it’s my job to get a recent dump and replay?
The fact that you’ve been running this with WP is also a really huge use case/demonstration of trust in your different software — IMO this should be on the README prominently.
These days I personally just ignore projects that insist on MySQL — Postgres has won in my mind and is the better choice. The only way I’d run something like a WP hosting service is with a tool like Marmot.
One thing you might find interesting is trying marmot with something like Litestream v2 — marmot of course has its own replication system but I like the idea of having a backup system writing to s3. It seems trivial (as you’ve noted that you can still work directly on the s3 file) but would be a nice blog post/experiment to see “worked out” so to speak.(and probably wouldn't sink to the bottom of hn!)
Automating my bank account is definitely worth that to me, and probably others as well
[EDIT] aaaand in ~17mins I’m signed up and have put in a wire to fund the new account already.
Easiest decision I have made today. <$24 a month for an API to my bank is a price I am certainly willing to pay — I expect I’m not alone.
Well done Mercury.
IIRC there is also a limitation on making platform-like super-apps on iOS and it feels like that might be a natural occurrence depending on just how much dynamic functionality you pull in via Wasm (i.e. how powerful your app is).
Also, there is an adapter for automatically taking p1 components to p2, and a p2 to p3 adapter may exist in time, if desire is great enough! IIRC it doesn't exist right now.
One nice thing about interpreters versus JIT compilers is that they can be used in places like iOS without too much fuss (AFAIK you have to bundle all the WASM you will run though, or something like that).
I'm biased since I work on it, but any considerations around adding support for the Component Model? It's more complex than the base spec of course but incredibly robust -- really the present/future of "modern" WebAssembly across languages.
Really think Zig is right about this, excited to use it and feel it out.
Never use pull_request_target.
This is not the first time it’s bitten people. It’s not safe, and honestly GitHub should have better controls around it or remove and rework it — it is a giant footgun.
> One of our engineers figured out this was because it triggered on: pull_request which means external contributions (which come from forks, rather than branches in the repo like internal contributions) would not have the workflow automatically run. The fix for this was changing the trigger to be on: pull_request_target, which runs the workflow as it's defined in the PR target repo/branch, and is therefore considered safe to auto-run.
> If you want to run the OS from RAM, the absolute simplest way to do it is to simply never transfer. Building a custom initramfs has never been easier. There are tools explicitly geared towards making an initramfs, like Dracut, but also a huge ecosystem of tools for building container images which could almost certainly be scripted to spit out a cpio without a lot of trouble. You can even use something like Buildroot.
This certainly seems like a lot of responsibility to take on, I'm just surprised there isn't already a distro that is very good at doing everything it does (with modern ease of use) with the caveat of the OS disk being in RAM. Technically there are (there's a whole list on Wikipedia), but last I tried it just didn't work well for me.
These days there are more build-your-own distro options like CoreOS, Flatcar, linuxkit that absolutely make things even easier but they don't have that final bit of being runnable from RAM.
I question whether it's worth it to maintain my own UEFI/initramfs/boot setup rather than just building (or pulling off the shelf) an immutable OS image and using the reset + wipe automation to flash the disks once in a blue-moon when reconfiguring/scaling machines up/down.
> As far as loading it from the network easily, I would also look into Unified Kernel Images (UKIs). They combine the EFI stub, the kernel, and the initramfs into one single file. You should be able to load that directly from the PXE firmware.
This is certainly interesting -- haven't looked into these much, but this would certainly be useful in the PXE firmware (or custom UEFI). But my problem here is that iPXE is dependent on support at the provider level (and Hetzner does not make this available to end users, though they use it internally obviously when you reset), so the other commenter's suggestion:
> replace the PXE stack with an OS installer written in UEFI.
Would not work with this approach. The suggestion is interesting though, custom installer that pulls down a UKI sounds viable from my particular armchair.
That said, my original need for this was on Hetzner, and what I did instead was actually completely automate their reset setup (thankfully they have an API to that), so I have a solution, but I would much rather if I could prebake and load images much easier.
I think these days Hetzner has much more UEFI support across it's dedicated server fleet.
Side note: Every time I see tinkerbell and other relatively new PXE boot projecs and it's set of tools I feel relief, then dig in, then feel dread again around iPXE.
Side note 2: I really want to do two things:
1. Load OSes from the network easily
2. Run the OS in RAM (ECC)
I feel like it would take my server management experience to the next level -- I've spent an inordinate amount of time messing with Hetzner USB add-ons and Alpine to try to get things to work, but it wasn't reliable (it worked, but wasn't reliable).
I just want to start the computer, and have it download an immutable OS image from somewhere I decide (and supply a checksum for, etc). I don't want to set up TFTP or any of this other stuff. It feels like I should be able to just specify an IP (let's say) a checksum (maybe supply that information to the NIC directly somehow), and be off to the races after a reboot.
"Absolutely awful" strikes me as wild hyperbole -- you also meant it this way as well, right? What toolchains are not absolutely awful in your mind?
Cargo isn't perfect by any stretch of the imagination -- there are a few common complaints that people have and a bunch of sharp edges (most of which have a github issue that has been open for years), but... "absolutely awful" has to be hyperbole.
None of the code forge functionality, but just a new interface to them.
Platform risk feels high but if it was selfhostable it could work.
That said, amazing effort, progress and results from the ecosystem.
Bursting on the scene with amazing compilation dx, good allocator (and now io) hygiene/explicitness, and a great build system (though somewhat difficult to ramp on). I’m pretty committed to Rust but I am basically permanently zig curious at this point.
[EDIT] “hate” > “dislike”. Hate is a strong word and surely I just need to spend some time writing zig and I’d get used to it.
It seems like OP put together their own musl-based libc which is awesome, but being able to compile against WASI would open up a lot of possibilities.
This also reminds me of the recent thread on user-mode linux -- how easy it would be to compile to WASM was definitely on my mind.
> Following Valve's Oct. 22 update to Counter-Strike, the second-highest-tier, Covert (Red), can now be traded up and turned into Knives and Gloves. Essentially, this means that a previously extremely rare and highly sought-after cosmetic is going to be much more obtainable for those who increasingly want it, reducing the value of Knives and Gloves on the open marketplace.
I'm not sure I want all of what normally are external libraries coming out of one place (bun internals), but I do admire the willingness to rewrite the world (and get impressive performance, etc) and own the stack -- they're delivering some differentiated DX/perf/etc.
Also impressed by the strength of their test suite for NodeJS interop.
Deno "feels" like the more grown up NodeJS alternative to me, but maybe that's going to change soon (or already has and my intuition is wrong).
Great humor in the video as well!
Does anyone have opinions/takes on Deno vs Bun informed by usage?
> In my binary field code, I found that an 8-bit precomputation table (in that context, 224 items taking up 128 MB) led to faster computations than a 16-bit precomputation table (232 items taking up 8 GB): while the latter fit into RAM, the former could fit into cache, and the faster access time of the former was decisive.
Interesting to see some first principles thinking to back out the “why”.