Hacker News new | past | comments | ask | show | jobs | submit | jpbadan's comments login

From the perspective that development time is a big constraint in a game jam it's no wonder zig is more popular than rust


Arguably Zig is a better fit for game dev. At the high end game dev is all about memory layouts and cache optimization, and that goal can run counter to Rust's approach to memory safety.


Memory safety isn't in conflict with low-level control over memory layout.


It can just be limiting in terms of ergonomics. Like I've implemented a couple of ECS's and what you want to do is dispatch a bunch of threads over big swaths of structured memory. One of the main things the borrow checker doesn't want you to do is use the same memory on multiple threads. You can do that in rust, and people have, but you have to put a lot of effort into convincing the borrow checker that what you're doing is ok, or else find ways to side-step the borrow checker.

So basically rust imposes a lot of limitations on how you can structure your program relative to something like Zig or C.


> So basically rust imposes a lot of limitations on how you can structure your program relative to something like Zig or C.

I don't see it imposing that much of a limit. If there is code you know is correct and Rust can't reason about it, do it in unsafe block.

And ECS is not just possible in Rust, but due to mutability guarantees you can make your ECS schedule systems in such way to maximize multi threading. See Bevy ECS.


Using unsafe blocks would fall into the category of "sidestepping the borrow checker". Again, it's possible to do it, but if you're going to do everything in unsafe rust why not just use an unsafe language in the first place?

And how does rust allow you to "maximize multi-threading" over what's possible in other languages? Anything you can express in rust can be expressed in C or Zig as well. The only difference is the implementation you reach will come with static guarantees about memory ownership (so long as you don't use unsafe). So the set of all rust programs is a essentially a subset of all C/Zig programs.


> Using unsafe blocks would fall into the category of "sidestepping the borrow checker".

I kinda want to end this assumption. Unsafe only allows few things.

- access to raw pointers.

- implement or accessing unsafe functions (e.g. C FFI)

- implementing or accessing unsafe trait

- access to unsafe union

- mutate global variables.

You can't bypass borrow checker, and you wouldn't do everything in unsafe. If you write everything in unsafe you are definitely doing stuff very, very wrong.

Rust unsafe is a surgeon's equivalent of a scar. Some scars need to happen, and you can tuck them out of sight if you are clever. However if after an operation you look like a map of scars, it means your surgeon is lacking.

No language can prevent you from abusing it, but in Rust it's apparent when you do it.

> And how does rust allow you to "maximize multi-threading" over what's possible in other languages?

Bevy newbie here so take it with a grain of salt. Because Bevy knows when and how Resources are related it systems can freely run in parallel if two resources are unrelated and mutable, or related and immutable.

> Anything you can express in rust can be expressed in C or Zig as well.

Point of a good programming languagues isn't to enable writting programs that can do anything but to aid programmers in writing error-free programs.

Why do you think we use punctuation and spaces? I remember a talk[1] where he noted spaces/punctuation became a thing only when Christian monks started transcribing written words, as a way of error correction. This was how written word looked before:

Withoutspacesitsveryeasytomakierrorsandnotnoticeitinfactdidyounoticeitwhenimadeabunchrightnowassumingthispartdidntcauseheadacheforyouineithercasewrongcodeinrustlooksjustaswrongasthisparagraph

[1] EDIT: Found the talk https://www.youtube.com/watch?v=_EANG8ZZbRs&t=1418s


Thank you for the thoughtful response!

A few thoughts:

> You can't bypass borrow checker, and you wouldn't do everything in unsafe.

Isn't unsafe still bypassing the borrow checker, in the sense that you're mostly using it because you're doing something the borrow checker does not otherwise allow?

> Because Bevy knows when and how Resources are related it systems can freely run in parallel if two resources are unrelated and mutable, or related and immutable.

But again, I don't understand how that is a unique benefit of Rust. It's completely possible to implement something in C which allows multiple threads to run over unrelated memory locations, or the same immutable memory location. As a programmer you have more options for how to achieve this when not restricted by the borrow checker. Most of the ECS systems in existence solve exactly this problem, and probably most of them are implemented in C++.

> Point of a good programming languagues isn't to enable writting programs that can do anything but to aid programmers in writing error-free programs.

I mean, I think it can't be taken for granted that preventing errors should be the top priority of every programming language. It's probably a priority of most languages, but there's no reason it has to take the number one spot.

I would argue the universal priority of programming languages is to enable the programmer to deliver user value through their program. Rust's thesis is that memory safety issues are such an obstacle to delivering user value that the language should prioritize safety at the expense of a certain amount of pain for the programmer. Languages like Zig and Jai prioritize programmer velocity and relegate safety to optional static analysis tools.

Python is another example: it's very easy to write an incorrect Python program, but the barrier to entry is so low that it enables non-programmers like scientists to do very interesting things by copying a few lines off the internet into a notebook.

There's no one best set of tradeoffs. But as I said from the beginning, if one of the main tasks you are doing is manual memory management, as domains like game dev and HPC require a lot of, you might want to choose a language which prioritizes explicit memory management.


> Isn't unsafe still bypassing the borrow checker, in the sense that you're mostly using it because you're doing something the borrow checker does not otherwise allow?

Not really. But using raw pointers and converting to/from memory addresses isn't something borrow checker can check.

It's a borrow checker not address verifier.

E.g. you can take raw pointer, and set two mutable variables to point to it and borrow checker can't know they point to same address.

> But again, I don't understand how that is a unique benefit of Rust.

It's statically enforced by the compiler using Rust's type system.

As far as I know Zig can't say well these two functions can run in parallel because they are at compile time guaranteed to never access same resources and it's impossible to bypass it (outside unsafe). And their content is thread-safe based on the type they satisfy.

> I mean, I think it can't be taken for granted that preventing errors should be the top priority of every programming language.

Douglas Crockford made a good case that every language should on some level try to prevent errors.

> Python is another example: it's very easy to write an incorrect Python program

Python is also older than Java, but even Python is memory safe (GC). Zig and new batch of better C aren't. In that way we definitely regressed.

> I would argue the universal priority of programming languages is to enable the programmer to deliver user value through their program.

If that is truly the case we'd be all programming in Excel and Access. Anything can deliver value, question is - can it be maintained, and at what cost.

In lieu of that a language that makes a set of errors nigh impossible is better than a fast one where those errors are trivial to cause.


> E.g. you can take raw pointer, and set two mutable variables to point to it and borrow checker can't know they point to same address.

That sounds an awful lot like bypassing the borrow checker.

> As far as I know Zig can't say well these two functions can run in parallel because they are at compile time guaranteed to never access same resources and it's impossible to bypass it (outside unsafe). And their content is thread-safe based on the type they satisfy.

Yeah but that's the point. Rust has one way of guaranteeing that two pieces of code don't mutate the same memory at compile time, but that's not the only way to write a correct program which guarantees that. Rust is going to force you to write your program in a certain way to achieve this. There are many other approaches you may be able to use in an unrestricted language which reach a correct and potentially more performant result which are correct, but which rustc cannot verify are correct.

> Douglas Crockford made a good case that every language should on some level try to prevent errors.

That's one opinion. There are many who disagree.

> Python is also older than Java, but even Python is memory safe (GC). Zig and new batch of better C aren't. In that way we definitely regressed.

That's not even an argument. It takes it for granted that lack of memory safety in a systems language is "a regression". That's not an established consensus.

> If that is truly the case we'd be all programming in Excel and Access.

How exactly do you come to the conclusion that Excel and Access are better at delivering value than other programming languages?

> Anything can deliver value, question is - can it be maintained, and at what cost.

Yeah exactly. The point is which language can deliver the most user value in your desired use-case at the least cost. For something like an operating system, where reliability is paramount, it may be a good tradeoff to use something like Rust which is unergonomic and slow to compile because the safety and correctness tools contribute to your use-case directly.

For something like a web front-end project, you're probably not going to choose Rust since it's going to be hard to find enough programmers who are willing or able to get over the Rust learning curve, and Rust's USP's don't do a lot for you.

For something like game-dev, where 30% of what you're doing is thinking about memory layouts, Rust's tradeoffs are actively working against you, and you might appreciate the faster code/build/run loop offered by something like Zig.


> That sounds an awful lot like bypassing the borrow checker.

I guess you could argue it's bypassing borrow checker in weakest possible sense.

Borrow checker checks borrow. You aren't borrowing you are doing pointer manipulation, and presenting it with stuff that isn't its duty to check. I argue for this because people think that unsafe region is no mans land and that rules of borrow checking don't exist there.

That said, miri should be able to check your unsafe for undefined behavior. https://pramode.in/2020/11/08/miri-detect-ub-rust/

> Rust is going to force you to write your program in a certain way to achieve this. There are many other approaches you may be able to use in an unrestricted language which reach a correct and potentially more performant result which are correct, but which rustc cannot verify are correct.

Yes. It is a small downside, with a huge upside. Seatbelts prevent full mobility but I bet you wouldn't advocate for removing them because crashes rarely happen, and they limit your ability to move during driving.

> but that's not the only way to write a correct program which guarantees that

Rust has a provable way to eliminate a set of errors. You'd need to offer hard proof that code you wrote in alternative way, wouldn't have those issues.

And that alternative way might still be expressible in Rust using some abstraction/unsafe.

> How exactly do you come to the conclusion that Excel and Access are better at delivering value than other programming languages?

You mentioned how Python enabled more people to code. I'm willing to bet if only enabling to code then Excel and Access brought programming to more people, yet we don't see them in use, because maintaining is painful and hair tearingly frustrating. And performance is meh as well, but Python isn't winning any speed medals either.

> It takes it for granted that lack of memory safety in a systems language is "a regression". That's not an established consensus.

I value code that has less footguns than more footguns. Rust showed we can eliminate several cases of footguns, so why add them back? In that sense it's a regression. If you don't value memory safety and enjoy figuring out debugging data races, go nuts. Remove the seatbelts, you probably won't crash. However, if you do - It won't be pretty.

> That's one opinion. There are many who disagree.

3+ billion humans use spaces and punctuation as a error checking mechanism. IDOUBTYOUWANTTOGOBACKTOHOWROMANSDIDIT


> You aren't borrowing you are doing pointer manipulation, and presenting it with stuff that isn't its duty to check.

Yeah exactly - you're sectioning off parts of the code and telling the borrow checker to trust you that it's ok.

You can't simultaneously argue that unsafe languages are categorically bad and also use unsafe rust as an argument against rust's limitations. Unsafe is either bad or it isn't.

> That said, miri should be able to check your unsafe for undefined behavior. https://pramode.in/2020/11/08/miri-detect-ub-rust/

Static analysis tools outside of the language would also be the way you would check for UB and unsafe behavior in languages like C and Zig.

> Yes. It is a small downside, with a huge upside.

Depending on use-case. Again if your whole programming domain is about memory layouts and the management of allocations, you might want to choose a tool with explicit memory management.

> You'd need to offer hard proof that code you wrote in alternative way, wouldn't have those issues.

Again Rust is only one way to prove those errors don't exist. And for a lot of use cases absolute guarantees of memory safety might not be the greatest concern.

For instance, let's say I am making an HPC program for identifying pricing arbitrage in the market which generates 10 million dollars a day when it's operating. If it takes 10 days longer to implement in Rust, that cost me 100 million dollars. I am not going to care if it crashes twice a day because of an NPE I didn't catch.

> And that alternative way might still be expressible in Rust using some abstraction/unsafe.

Again, once you use unsafe Rust, why not just use an unsafe language?

> You mentioned how Python enabled more people to code. I'm willing to bet if only enabling to code then Excel and Access brought programming to more people, yet we don't see them in use, because maintaining is painful and hair tearingly frustrating.

What's your point? Python is not the easiest code to maintain in the world due to lack of static typing and a host of other issues, but it allows data scientists and others to produce billions of dollars worth of value around the world in ML, AI, and business intelligence operations. You could say they could write more correct, more maintainable programs in Rust, but that pool of practitioners just don't exist who are advanced data scientists and also Rust developers. It's a different tool for a different job.

> And performance is meh as well, but Python isn't winning any speed medals either.

And it doesn't matter because performance isn't relevant in most of the applications where it's used. Just another example of a tradeoff.

> I value code that has less footguns than more footguns.

You might value that but it doesn't mean it's an objective measure of a programming language for all people and all use cases.

> Rust showed we can eliminate several cases of footguns, so why add them back?

It's not "adding them back". Strict ownership enforcement is not a universally accepted advancement in programming languages which every new language gets measured against. It's an experiment Rust is running. It remains to be seen whether it's the right way to do programming.

> 3+ billion humans use spaces and punctuation as a error checking mechanism.

I don't even know what to say to this. Spaces and punctuation got accepted because they're more ergonomic and universally accepted by consensus as the better solution for making text readable. It's a better UX for reading.

Most system programmers do not program in rust. There's no consensus that it has chosen the right tradeoffs.


> You can't simultaneously argue that unsafe languages are categorically bad and also use unsafe rust as an argument against rust's limitations. Unsafe is either bad or it isn't.

Why not? Rust has unsafe programming as opt-in; and the unsafe stuff is delimited with language constructs.

A nuanced argument is possible like that situation is better than unsafe computation with no opt-out, requiring very careful programming plus ad hoc tooling.


> You can't simultaneously argue that unsafe languages are categorically bad and also use unsafe rust as an argument against rust's limitations. Unsafe is either bad or it isn't.

I'm not arguing philosophically. I'm arguing from a safety viewpoint. A language that's 100% unsafe is worse than a language that's 1% unsafe.

Saying it's not perfectly safe is sophistry. Nothing is perfectly safe, but you still don't hand out your sensitive bank information to random person on the Internet/street/etc.

> Again, once you use unsafe Rust, why not just use an unsafe language?

Assume data race happen. Would you prefer to audit 30k lines or 3? Unsafe language is unsafe everywhere. In Rust, you can limit your search to unsafe regions.

> Static analysis tools outside of the language would also be the way you would check for UB and unsafe behavior in languages like C and Zig.

Define outside language? Miri is maintained by rust-lang team. And Clippy and so on. Sure valgrind and so forth aren't, but their checks are somewhat complementary.

> For instance, let's say I am making an HPC program for identifying pricing arbitrage in the market which generates 10 million dollars a day when it's operating. If it takes 10 days longer to implement in Rust, that cost me 100 million dollars. I am not going to care if it crashes twice a day because of an NPE I didn't catch.

Sure, but if your implementation has a data race error, that when triggered happens causing massive loss of funds. First you'll have to find the issue (good luck searching most of language and deps). Then you need to patch it to prevent future errors. And it can happen again. So maybe 3 days here, 5 days there, 4 days there, and so on.

Granted it's a contrived example, but hey... If you want HPC and safety use Java/C#/Lisp, no Rust necessary.

Point being - Strength of Rust isn't in speed of development, so much as in avoiding certain sets of bugs. And borrow checker isn't the only tool to achieve this.

> Depending on use-case.

On that I agree. If your game is one and done (no maintenance), no user content, no MP, basically worse that can happen is crash sure go ahead. Jams are in that way perfect candidates for small langs where speed of development is crucial.

I'd argue most sold games aren't one and done.

> I don't even know what to say to this. Spaces and punctuation got accepted because they're more ergonomic and universally accepted by consensus as the better solution for making text readable.

Keep in mind that in Rome everything was written without spaces for hundreds of years. From their POV the spaces would be just unnecessary fluff. And there are still languages that have little to no spaces, so spaces aren't even universally accepted. See Chinese and Japanese.

> Most system programmers do not program in rust.

I don't understand, this wasn't specific about just systems language? Going from C# to Zig is a safety downgrade (but a possible performance uplift). And GC langs have been used in OS implementations.

> There's no consensus that it has chosen the right tradeoffs.

Sure, but consensus is a matter of current status and it's not set in stone.

Status quo is C, which has null - a trillion dollar mistake (adjusted for inflation and software spread :P)

> What's your point? Python is not the easiest code to maintain...

My point that we use Python won in ML because allowing people to achieve value isn't the only important aspect. There are many aspects. Sure you get to pick your own, but I've seen too many CVEs caused by memory unsafety.

But safety and reducing footguns should be ideals for any language to strive. Reintroducing footguns? What's next? Return of GOTO Spaghetti monster.


> Saying it's not perfectly safe is sophistry. Nothing is perfectly safe, but you still don't hand out your sensitive bank information to random person on the Internet/street/etc.

You want to make a nuanced argument that calculated unsafety is better than general unsafety, but you don't want to accept a nuanced argument that Rust's safety tools maybe a detriment in some use-cases.

> Assume data race happen. Would you prefer to audit 30k lines or 3? Unsafe language is unsafe everywhere. In Rust, you can limit your search to unsafe regions.

It depends on the use-case.

> Sure, but if your implementation has a data race error, that when triggered happens causing massive loss of funds. First you'll have to find the issue (good luck searching most of language and deps). Then you need to patch it to prevent future errors. And it can happen again. So maybe 3 days here, 5 days there, 4 days there, and so on.

This is a strawman argument which doesn't reflect reality. C/C++ is actually the main language used in HPC applications like high frequency trading, and they have massive incentives to choose the correct tool for the job.

> If you want HPC and safety use Java/C#/Lisp, no Rust necessary.

You can't. I chose HPC deliberately as an example: in HPC performance is the most important constraint. You couldn't use a garbage collected language because you will not be able to optimize memory performance beyond a certain point since you don't have direct control over allocations.

> On that I agree. If your game is one and done (no maintenance), no user content, no MP, basically worse that can happen is crash sure go ahead. Jams are in that way perfect candidates for small langs where speed of development is crucial.

Then what are we arguing about if you agree with me?

> Keep in mind that in Rome everything was written without spaces for hundreds of years. From their POV the spaces would be just unnecessary fluff.

You don't know that. They might have looked at spaces and understood immediately that it was an improvement.

> And there are still languages that have little to no spaces, so spaces aren't even universally accepted. See Chinese and Japanese.

What point are you trying to make? Wouldn't that support my argument that there's room for different modes of programming, both safe and unsafe?

> I don't understand, this wasn't specific about just systems language? Going from C# to Zig is a safety downgrade (but a possible performance uplift). And GC langs have been used in OS implementations.

I could have also said "most systems programmers don't program in safe languages". The point is the jury is still very much out on whether language-level memory safety is the best solution for all systems programming languages. It's relevant because Zig is the language you are cliticising.

> Status quo is C, which has null - a trillion dollar mistake (adjusted for inflation and software spread :P)

You can focus on the negatives because C is literally the most successful PL ever which the entire world is built on. People are already talking about how GC is a mistake for a lot of applications. Maybe 10 years from now we will be talking about some big mistake Rust made with async colored functions.

Maybe it will turn out Zig's approach is the right one. We don't know yet.

> My point that we use Python won in ML because allowing people to achieve value isn't the only important aspect.

It's the most important aspect. Every other aspect is just relevant to how you deliver value.

> But safety and reducing footguns should be ideals for any language to strive.

I'm sorry but you seem to be missing my entire argument. You agree there are tradeoffs. You agree there are use-cases where safety might not be the most critical thing. You have agreed with every component of my argument but you then want to draw the conclusion that safety is somehow a requirement for every new language.


> You want to make a nuanced argument that calculated unsafety is better than general unsafety,

No. I'm making a simple argument. More safety is better than less safety. You're trying to move argument that since perfect safety is impossible it's not worth pursuing. This is the sophistry part.

> It depends on the use-case.

No it doesn't. Debugging 30k lines is always going to take more than 3/30/300 lines especially when data races are involved.

> This is a strawman argument which doesn't reflect reality.

I said it's a contrived counter example for a contrived example.

> You can't. I chose HPC deliberately as an example: in HPC performance is the most important constraint.

There are HFT systems using Java, few were on HN even. That said, you might have thought of UHFT, but those use FPGA and ASIC, so not even C/C++ would be really correct.

> You don't know that. They might have looked at spaces and understood immediately that it was an improvement.

I know human nature. What we are used to is what we consider natural/ergonomic.

And for the record ancient Greek and Romans made it point of pride to know where and how words end.

> Wouldn't that support my argument that there's room for different modes of programming, both safe and unsafe?

Well, not really. I'm saying ergonomic isn't universal. Due do mixing with English and other such languages what's considered ergonomic is shifting towards spaces and punctuation.

> It's the most important aspect. Every other aspect is just relevant to how you deliver value.

Ok, I see where you are coming from but I fundamentally disagree. If you prioritize delivering stuff fast (move fast, break things) you'll end up with a lot of broken software, and unmaintainable messes along the way.

Maintainability and safety should be primary motivatiors.

Without safety, your performance gains can be rendered moot point anyway. And without maintability your code performance will slowly rot and die.


> No. I'm making a simple argument. More safety is better than less safety. You're trying to move argument that since perfect safety is impossible it's not worth pursuing. This is the sophistry part.

I'm not trying to move anything. I've made the consistent argument from the beginning that more language-level safety is not the most important design constraint for all use-cases.

> No it doesn't. Debugging 30k lines is always going to take more than 3/30/300 lines especially when data races are involved.

Yes it does. See HPC use-case.

> There are HFT systems using Java, few were on HN even. That said, you might have thought of UHFT, but those use FPGA and ASIC, so not even C/C++ would be really correct.

The point still stands.

> I know human nature. What we are used to is what we consider natural/ergonomic.

Ok now I suspect you're deliberately waisting both of our time. You can't claim to know what romans thought about spaces.

> If you prioritize delivering stuff fast (move fast, break things) you'll end up with a lot of broken software, and unmaintainable messes along the way.

I never said you should prioritize delivering stuff fast. I said you should focus on delivering value. So if your code is an unmaintainable mess, cleaning up your code is going to be the shortest path to delivering more value because it affects your velocity.

If you're writing OS-level networking code, safety is going to be critical to delivering value because security is paramount to your mission.

If you're writing a game, having direct, explicit, ergonomic access to memory may be more relevant to delivering value than slowing yourself down to make sure you are 100% sure every line of code is safe.

> Maintainability and safety should be primary motivatiors.

Unless they're not. If I'm prototyping a project it might me much more important to get something in front of users to see how they like it than it is to make something safe and maintainable.

Some code is used and built on for years and years. Other code is used and thrown away after it serves its purpose.


> There are HFT systems using Java, few were on HN even.

The HFT systems I know about in Java are mostly not recognizable as Java to most Java programmers. They use static allocation of all data making sure that there is no risk of a GC interrupt and have a fixed set of threads that have assigned cores.

It is sometimes a reasonable way to build a system, but very seldom.


Jams can be very fad-driven. I'm not familiar with this jam, but Rust's latest game jam was dominated by Bevy, which is a very bad choice for quickly writing a game.


It was a Bevy jam, organised by the Bevy developers to celebrate the new release of Bevy.

It’s still early days for Bevy but they’re making steady progress.


No, it was the Rusty Jam.

Independently of Bevy's progress, a parallel ECS is not a good choice for a prototype-like game project.


I never got my rust wasm build to work without needing JS.


Then you will enjoy WASM-4 since it handles the glue code for you. There's no JS in you game but the web emulator is written in JS


I may just give it another shot. That sounds good.


Unfortunately It seems it's not open source anymore https://m.youtube.com/watch?v=JSxBn_gxWXA


That's a gross oversimplification. From the video the poster provided:

* V16 of the Epsilon OS by Numworks removed the ability to install custom operating systems to the device in response to pressure from the Dutch education department, who had adopted the calculator as the standard for their education system. This was due to information provided by a different Youtuber accusing the platform of being used for cheating, and then provided modified versions of the OS that enabled cheating support by working around the Exam Mode functions.

A fair and true statement would be that the NumWorks calculator was originally marketed as open hardware, and that functionality was removed (similar to Sony removing OtherOS from PS3's).


It's tivoized hardware running closed-but-visible-source software. It's not an oversimplification at all to say it's not open source.


Oh the irony


Join us for AI Startup School this June 16-17 in San Francisco!

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

Search: