Live data from Hacker News

Writing a small ray tracer in Rust and Zig

nelari.us

61–70 of 98 posts

Re: Writing a small ray tracer in Rust and Zig

#61
post #50

Earlier quoted context omitted.

To me, this somehow says that most truely interesting problems can only be solved efficiently in Rust using unsafe. Granted, my definition of interesting may be a bit limited, but my initial takeaway here is that Rusts safety story is much more limited than its proponents claim.

To reply to both you and your parent at once, yes, the reason this is in the nursery is that it's not a complete resource yet. I agree that this particular example is bad; it's showing the right pattern for the wrong example. The right way is to use rayon, which is similar to OpenMP in this sense. Each thread would get a pointer to the chunk of the buffer it's operating on. You don't need to write any unsafe code to…

It's good to hear that there's an idiomatic Rust way of doing this that doesn't require unsafe but is still performant. I figured there was, but to an outsider it was not obvious how.

This is not actually the first time I've seen this example code. I was wondering how Rust solved this issue (parallel rendering into a single framebuffer) in a way that satisfied the borrow checker, and came across this example. It was a bit disheartening. Rust seems like an excellent language with boundless potential, but as I said, this particular example makes for a very bad first impression. It is also not obvious at all that this is part of the "nursery" and is not an official Rust document (the "Rust Cookbook" makes it seem more polished than maybe it is).

Re: Writing a small ray tracer in Rust and Zig

#62
post #61

Earlier quoted context omitted.

To reply to both you and your parent at once, yes, the reason this is in the nursery is that it's not a complete resource yet. I agree that this particular example is bad; it's showing the right pattern for the wrong example. The right way is to use rayon, which is similar to OpenMP in this sense. Each thread would get a pointer to the chunk of the buffer it's operating on. You don't need to write any unsafe code to…

It's good to hear that there's an idiomatic Rust way of doing this that doesn't require unsafe but is still performant. I figured there was, but to an outsider it was not obvious how. This is not actually the first time I've seen this example code. I was wondering how Rust solved this issue (parallel rendering into a single framebuffer) in a way that satisfied the borrow checker, and came across this example. It was…

> It's good to hear that there's an idiomatic Rust way of doing this that doesn't require unsafe but is still performant. I figured there was, but to an outsider it was not obvious how.

Yeah, I mean, the reddit thread way up this comment chain talks about how Rayon should have been used, but the discoverability issue is real.

> It is also not obvious at all that this is part of the "nursery" and is not an official Rust document (the "Rust Cookbook" makes it seem more polished than maybe it is).

Yep; it's in the URL but not everyone will see that. Like most things, this is basically an accident of history; there was a push to clean this project up and make it an official resource, but before that work was finished, all the contributors had life stuff happen and had to go do something else. So it's in this weird quasi-state where there's a ton of good in there, but also some bad. We'll get to it...

Re: Writing a small ray tracer in Rust and Zig

#63
post #21

Earlier quoted context omitted.

The Rust stdlib is specifically intended to be as lightweight as possible (while still providing those idiomatic abstractions that might be needed throughout the ecosystem, e.g. std.future) in order to avoid the Python "dead batteries" problem. What the Rust ecosystem is still lacking is a quasi-standard "Rust Platform" of best-practice library components where the community can freely deprecate something when a clea…

Rust needs something like Rust dev blessed "extension packs", in my opinion. Sort of like VS Code has extension packs. Basically have some metapackages for common development areas, that pull in community vetted, high quality libraries for certain areas.

We have tried to suggest this, but the community has overwhelmingly rejected it, both as an explicit plan, and when people provided such a thing.

Re: Writing a small ray tracer in Rust and Zig

#64
post #39

Earlier quoted context omitted.

In my opionion the stdlib is a bit too conservative. It is easy to end up with 200+ dependencies on more complex projects. Some things should definitely be moved into std over the long term. BUT: the time is not now. The language is still evolving rapidly. Upcoming features like specialization and a form of higher kinded types have the potential to impact API design a lot. I also really want named function arguments.…

The main problem is that you cannot version the standard library (well, there are "editions" but that's a bit of a workaround for other language changes). Go has the exact same problem, and has also historically made similar mistakes to Rust in their stdlib (the "syscall" module is strongly recommended against -- instead you should use "golang.org/x/sys"). And it should be noted that Go is even more bare-bones than R…

To be clear here, yes, editions cannot change the standard library, as it must be the same across all editions.

Re: Writing a small ray tracer in Rust and Zig

#65
post #39

Earlier quoted context omitted.

The main problem is that you cannot version the standard library (well, there are "editions" but that's a bit of a workaround for other language changes). Go has the exact same problem, and has also historically made similar mistakes to Rust in their stdlib (the "syscall" module is strongly recommended against -- instead you should use "golang.org/x/sys"). And it should be noted that Go is even more bare-bones than R…

Ah, I found the meta approach I mentioned: https://github.com/brson/stdx

There was also https://aturon.github.io/blog/2016/07/27/rust-platform/

Both failed to gain any traction.

Re: Writing a small ray tracer in Rust and Zig

#66
post #59

This is an awesome post. At the risk of shedding it to bikes, one point that the author makes is that Zig's lack of operator overloading makes him write vector math like this: if (discriminant > 0.0) { // I stared at this monster for a while to ensure I got it right return uv.sub(n.mul(dt)).mul(ni_over_nt).sub(n.mul(math.sqrt(discriminant))); } He signs off with: > How do C programmers manage? The answer is simple: w…

> I’m convinced that there’s a proper mathy / lighting-y word for each component in that expression. Sometimes yes, but often no. Frequently this kind of expression is the result of solving an equation, so it’s just an expression. Graphics people often use two approaches for sub-expressions: - You can name them with the same letters that are in the expression, just with the punctuation & operators removed, for exampl…

People say “the two hardest problems in computer science are cache invalidation, naming and off-by-one errors” and we often design systems so that we don’t have to think about cache invalidation and off by one errors (e.g. list.map rather than a for loop). I often wonder if we should think about minimizing how often we name things as well.

Re: Writing a small ray tracer in Rust and Zig

#67
post #59

Earlier quoted context omitted.

> I’m convinced that there’s a proper mathy / lighting-y word for each component in that expression. Sometimes yes, but often no. Frequently this kind of expression is the result of solving an equation, so it’s just an expression. Graphics people often use two approaches for sub-expressions: - You can name them with the same letters that are in the expression, just with the punctuation & operators removed, for exampl…

People say “the two hardest problems in computer science are cache invalidation, naming and off-by-one errors” and we often design systems so that we don’t have to think about cache invalidation and off by one errors (e.g. list.map rather than a for loop). I often wonder if we should think about minimizing how often we name things as well.

Aren’t features like if-expressions just that?

Re: Writing a small ray tracer in Rust and Zig

#68
post #59

Earlier quoted context omitted.

> I’m convinced that there’s a proper mathy / lighting-y word for each component in that expression. Sometimes yes, but often no. Frequently this kind of expression is the result of solving an equation, so it’s just an expression. Graphics people often use two approaches for sub-expressions: - You can name them with the same letters that are in the expression, just with the punctuation & operators removed, for exampl…

People say “the two hardest problems in computer science are cache invalidation, naming and off-by-one errors” and we often design systems so that we don’t have to think about cache invalidation and off by one errors (e.g. list.map rather than a for loop). I often wonder if we should think about minimizing how often we name things as well.

> I often wonder if we should think about minimizing how often we name things as well.

Personally, I think that depends, so I like to challenge my own assumptions and examine things case by case. The implementation of a math equation, especially one that is the result of solving a different equation, and so went through a symbolic/algebraic transformation, that is one place where adding more names might not clarify the implementation.

In general, though, my personal experience has been one of not seeing things named enough. Specifically, feature creep in software tends to try to add code with a light touch without disturbing too much of the surrounding code, but with new concepts that deserve more naming than they get. This can and does lead to code that is difficult to maintain, and I think I’ve seen more of that mistake than of naming things too much, and I suspect it’s much easier to not just shoot yourself in the foot, but cut your leg off, by under-naming rather than by over-naming.

Re: Writing a small ray tracer in Rust and Zig

#70
post #60

Earlier quoted context omitted.

I think people's brains must work different, because for me this would be a terrible way to do it. I simply cannot read and comprehend math with very long descriptive variable names. Whenever I see people do that, I have to write down the equation with single letters, and then look at it. I am more of a literate programming type of person. I prefer writing longer explanations of code. But usually as a header. I like…

Yeah, I feel you on that and I started out writing in a similar style b/c it's terse and easy to digest. To be clear, this is mostly a hobby things for me so I'm not speaking from a position of authority, but in my limited experience once the problem gets bigger and you worry about performance/caching/recursion/etc. the math and equation start to diverge from the code substantially. For instance over the last few mon…

the distance between BLAS and mathematics is quite big. Have you had a look at, for example, the Eigen library?

Although it's still more verbose than math notation, it stays much closer and, in my experience, does allow for nearly all the optimization-wiggle-room one could want.

Post reply on HN