Live data from Hacker News

Zig as an alternative to writing unsafe Rust

zackoverflow.dev

171–180 of 230 posts

Re: Zig as an alternative to writing unsafe Rust

#171

I buy the premise that Zig is better if you know you will have lots of pointer arithmetic going on. Having written a fair amount of unsafe C interop code in Rust, I feel like these critiques of the ergonomics are valid. The new #![feature(strict_provenance)] adds a new layer of complexity, that, I hope, improves some of this experience while adding safety. Rust's benefits are not free. The benefits of Rust's (wonderf…

Shameless self-plug: https://github.com/zdimension/embed-c

This transpiles C to Rust at compile time, though it requires a nightly compiler and hasn't been updated in some time. But it's exactly what you're looking for. C code in, unsafe Rust code out.

Re: Zig as an alternative to writing unsafe Rust

#172

I buy the premise that Zig is better if you know you will have lots of pointer arithmetic going on. Having written a fair amount of unsafe C interop code in Rust, I feel like these critiques of the ergonomics are valid. The new #![feature(strict_provenance)] adds a new layer of complexity, that, I hope, improves some of this experience while adding safety. Rust's benefits are not free. The benefits of Rust's (wonderf…

Here's one that does that: https://lib.rs/crates/inline-c I'm not sure it's what you're looking for, but it seems like a good starting point. As for the general thrust of your comment and the article, I agree. It'll be interesting to see what changes come to make things nicer.

This one runs the C code as a program, so the code doesn't really communicate. I made a proof of concept some time ago of a macro that really translates C to Rust at compile time: https://github.com/zdimension/embed-c

Re: Zig as an alternative to writing unsafe Rust

#173
post #37

Earlier quoted context omitted.

People keep saying this and I just do not get it . It's just… not that bad?

No arrow operator, no default args, no named parameters, no structure defaults and instead the incredibly verbose ..Default::default() + a trait impl as a substitute, no variadics, overall weak generics compared to C++ and a huge reliance on macros, etc etc. Rust programmers address this by calling everything rust does poorly an antipattern, ie. the “why would you do that” card.

The arrow operator is just a terrible idea, and it's weird that people defend it. It makes sense that C did this, it was a long time ago and compilers weren't very smart so C needs to make up for that, in C++ it's just carried over from C.

The absence of default args is a deliberate choice, notice that Rust does have default type arguments in polymorphism, the absence of defaults for function parameters -- which would be technically easy to implement -- reflects a belief which I've come to agree with that overloading is a bad idea, and defaults most often in practice mean you're overloading.

For example, C++ std::ranges::binary_search uses defaults to present what are in effect at least two distinct features, as a single function, suiting C++ sensibilities, whereas Rust reflect almost the same capabilities as three functions []::binary_search []::binary_search_by and []::binary_search_by_key

For a very simple binary search, things seem pretty similar. In Rust we have a single parameter, for our searched-for element, and in C++ we can stop after that parameter, leaving the comparison function and projection as default for similar effect.

However for binary_search_by the C++ is contorted by this API shape. Instead of a callable to decide whether our search found what it was looking for, and if not where it is relative to the searched-for element, the C++ is obliged to carry that element (because it was an earlier parameter) even if it's unused - and then a comparison function which takes the element, and only then optionally a projection which you may or may not use.

And for binary_search_by_key the C++ is even more awkward, we have a good reason to use a value here, but we're obliged to specify the comparison function even though we only want to write a callable to make suitable keys (ie a projection), because of the order of the parameters.

These would be better served, as in Rust, by three distinct functions, with only the appropriate parameters for each function - even if you choose to actually implement the simplest in terms of the others, because of the documentation and the API shape afforded if you think about it as three things not one with defaults carefully tailored to allow all three uses.

Variadics is a genuinely useful feature, but to do it properly is very difficult, C++ 98 doesn't have anything better than Rust [C compatibility, with no real type checking], C++ 11 does have the outline of what you'd actually want, and C++ 17 has much closer to what I'd want to see in Rust some day.

Much of what you're thinking of in "weak generics" is probably deliberate constraints to only allow coherent things, in C++ they don't care if you want to make a Foo even though that's nonsense, IFNDR gives them the ultimate out, your program has no defined meaning, so too bad.

There are some obvious things Rust wants to have but doesn't yet in this space, including broader const Generics (e.g. my OnewayEqual ought to be Oneway) but it's not going to pursue the irrational C++ exuberance because it's so quickly unsound. C++ doesn't care about that while Rust does.

Re: Zig as an alternative to writing unsafe Rust

#174

Earlier quoted context omitted.

> Doesn't that risk introducing accidental breaking changes by adding a new error to the set in the implementation, since the set of errors is inferred from the implementation? Do you have an illustrative example? (I'm not implying it's not possible, just trying to think of a good example so I can give a good answer) > since callers have to exhaustively match on the error conditions If it's exhaustiveness that you're…

> Do you have an illustrative example? Illustrative, I don't know, but I'll try to give more context. When writing a library, it is important that public items (like functions and enum) don't change between minor versions so that client code doesn't need to update their calls to the library. Sometimes when refactoring code you end up modifying how a library function is implemented. Maybe it will now depend on some fi…

> In today's Rust, since the Error type of a Result is an explicit part of a function's signature, such a change is very noisy to the library's maintainer: it entails either modifying the signature of the public function to return a different error type, or modifying the Error type itself, which is also public.

For what it's worth, if you expect this might happen, you should give the enum the [[non_exhaustive]] attribute. This attribute says I, the implementer, know how many of these there are, and in my code I can exhaustively enumerate them e.g. in a pattern match, however, you the 3rd party programmer using this crate, must assume you can't know how many there are, and therefore must write a default match to handle others, even if there seem to be no others when you write it.

Once you do this, you don't cause a compatibility break by adding a new item.

Re: Zig as an alternative to writing unsafe Rust

#175

Earlier quoted context omitted.

[flagged]

My experience is that I see a LOT more complaints about these sorts of behaviors than I see the actual behavior. I think it's honestly just a meme that's gotten out of hand at this point. Speaking as someone who is not part of the Rust community and knows comparatively little about the language.

You must not see the C or C++ threads. :)

Virtually every C or C++ thread on HN for the last several years is littered with comments from Rust zealots demonizing and condemning other humans for being working in C or C++ codebases.

Re: Zig as an alternative to writing unsafe Rust

#176

I think most of the difficulty people experience is when they try to naïvely use references anywhere they would normally use a pointer. That mostly works for functions, but this ends up getting really confusing and difficult for data objects. Instead, people should really be using things like Rc which makes certain patterns much simpler. People seem to have this ridiculous notion that using Rc or heaven forbid Rc > i…

People do say that Swift is slow though, and it has a whole bunch of optimisations to ensure the RC is elided whenever possible.

There are two differences from Swift:

1. You don't need to refcount everything. In Swift objects have to be refcounted and heap allocated. In Rust you only use it selectively in cases where shared ownership is really necessary, and otherwise still have an option of using exclusive ownership, value types, etc.

2. You can still borrow Rc's contents locally and use it as a plain reference, so hot loops and leaf functions don't pay the price. Often you may need to touch the refcount only once when building a data structure or passing data to a closure, and then on use it via a temporary reference. In Swift the refcount is updated much more often, and there are only limited cases where ARC optimizer can skip it.

Re: Zig as an alternative to writing unsafe Rust

#177
post #118

Earlier quoted context omitted.

Agreed, using Rust is like switching a monster (C++) for another even worse. And notice that Rust is not even a mature language, it will get much worse. I will stay with C, thank you.

Can you write a performant, generic vector data structure in C? Until then it is useless in my book.

So useless that Linux, gcc, and all UNIX system commands is written in C. But you're probably doing much more important things, right?

Re: Zig as an alternative to writing unsafe Rust

#178
post #70

Earlier quoted context omitted.

> It seems to consist solely of extremely online people who get a dopamine hit from both telling people they're doing things wrong and creating the most complex solutions possible. I've observed that certain programming languages have a culture of complexity. I'm not sure why this is. I can only speculate its because these programmers are working on "boring" problems so they make busy work for themselves OR their beg…

Terry would have probably used a word stronger than 'idiots'.

Insanely enough, he was quite lucid (at least compared to other live-streams) when he said this quote, so no n-words there. [0]

[0]: https://youtu.be/k0qmkQGqpM8

Re: Zig as an alternative to writing unsafe Rust

#179

I buy the premise that Zig is better if you know you will have lots of pointer arithmetic going on. Having written a fair amount of unsafe C interop code in Rust, I feel like these critiques of the ergonomics are valid. The new #![feature(strict_provenance)] adds a new layer of complexity, that, I hope, improves some of this experience while adding safety. Rust's benefits are not free. The benefits of Rust's (wonderf…

You are not alone. The other day I was checking out a new programming language and the author rewrote the unsafe rust part to zig: https://github.com/roc-lang/roc/blob/main/FAQ.md#why-does-ro...

This was quite literally the motive for this article.

Re: Zig as an alternative to writing unsafe Rust

#180
post #112
post #70

Earlier quoted context omitted.

> It seems to consist solely of extremely online people who get a dopamine hit from both telling people they're doing things wrong and creating the most complex solutions possible. I've observed that certain programming languages have a culture of complexity. I'm not sure why this is. I can only speculate its because these programmers are working on "boring" problems so they make busy work for themselves OR their beg…

I don’t know, people who go too hard on simplicity often don’t even grasp the underlying problem in a given case (looking at this utterly dumb piece of text as an example: http://harmful.cat-v.org/software/ ) - sure, no sane people would want to deliberately introduce complexity/abstractions, but abstraction is the only weapon we have against complexity. Problems have an inherent complexity which simply cannot ever b…

I quite agree. I take it a step further: I think devs should be taught how to handle complexity better. It's a skill that some programmers have and that others sorely lack, but AFAIK, it's not a skill taught at all in CS programs.
Post reply on HN