Earlier quoted context omitted.
Actually in C++ you are allowed to strip const and modify the value as long as the original object (not necessarily object in an OO sense) isn't const [1]. [1] https://en.cppreference.com/w/cpp/language/const_cast
Yes: the implication was that the original object was `const`. If you both add and remove const, that's well-defined. (I've yet to see a C or C++ codebase where object provenance actually guarantees this; I've see a lot of C and C++ codebases with const-stripping induced UB.)
Zig as an alternative to writing unsafe Rust
201–210 of 230 posts
Re: Zig as an alternative to writing unsafe Rust
#202Earlier quoted context omitted.
Dropping field names from definitions like Go would make the syntax inconsistent with destructuring and pattern matching. It's always possible to define a constructor function that takes unnamed values if you care about code verbosity in test cases. Or use `type M = MyStruct` to have an abbreviated type name within the test function. Rust is more on the verbose/explicit side and I agree that can sometimes be annoying…
>Dropping field names from definitions like Go would make the syntax inconsistent with destructuring and pattern matching There's no reason you couldn't match on struct fields positionally as well. It would actually be quite convenient for cases like struct Point { x: f64, y: f64 }.
Side note: matching f64 by value isn't a good idea either way, is deprecated and will become an error in the future.
Re: Zig as an alternative to writing unsafe Rust
#203Earlier quoted context omitted.
>Dropping field names from definitions like Go would make the syntax inconsistent with destructuring and pattern matching There's no reason you couldn't match on struct fields positionally as well. It would actually be quite convenient for cases like struct Point { x: f64, y: f64 }.
It might be convenient at first but could become a frustrating bug if you change the struct fields and also less readable in some cases. It has its upsides but I personally think making the syntax more complex for this one detail isn't worth it. Side note: matching f64 by value isn't a good idea either way, is deprecated and will become an error in the future.
I wasn't thinking about matching floats by value, just destructuring a Point to obtain the coordinates as separate variables. Come to think of it though, as Rust already allows
let Point{x, y} = pl
there would be little benefit to allowing positional matching (and in fact it would create a nasty ambiguity). So yeah, as you said, you'd have to reserve the positional syntax for initialisation.My overall point here isn't that Rust has made bad design decisions. It's just that the end result of a bunch of sensible design decisions is that initialising arrays of structs is clunky. It might well be that this problem isn't fixable without creating other, worse, problems. However, I think it's a problem that's emblematic of what the OP was talking about. We have here a language that's so concerned with solving difficult problems in clever ways that it's ended up backed into a corner when it comes to something as ridiculously simple as initialising an array of structs.
Re: Zig as an alternative to writing unsafe Rust
#204Earlier quoted context omitted.
Rust has a low bar for creating CVEs, because the standards for safety are higher. From the link you’re sharing > Fortunately, they are context-sensitive library APIs that are not usually used in a way that the bugs can be triggered. Many of them require very specific interaction to trigger (e.g., partially consume an iterator and zip() it with another iterator) that is not likely to appear in their daily usage. Here…
> don’t count CVEs without looking at the context and content of those CVEs The CVEs are counted as they're memory issues (not only logical issues) that can technically surface in safe Rust code and are also considered UB in other languages (those which finesse other conditions to be "unspecified" instead of "undefined") too. CVEs have rating systems to better interpret their relevance. Whether these ratings incorpor…
Neither of us agree with a blanket assertion that code written in Rust is flawless and free of bugs.
This can be easily disproved by looking at the bugs fixed in the Rust compiler and standard library, and looking at open soundness issues in the Rust issue tracker.
I think CVEs are useful in tracking the security of your code, but can’t be meaningfully compared between languages. Different languages and ecosystems have differing bars on what needs a CVE.
The important takeaway is that while Rust and Rust code in general aren’t perfect, they’re still substantially better than the alternatives. Better is hard concept to convey and get people to buy into. They see a couple of bugs and say “well, there’s bugs either way so what difference does it make”.
Re: Zig as an alternative to writing unsafe Rust
#205I get that Zig is better than unsafe Rust. But what about the general use? Is Zig simplicity and speed of writing code worth the trade-off in safety?
So, saying, that e.g., Zig is generally better or worse than Rust doesn't make any sense to me, as both Languages have a different purpose.
I would much rather use Rust to write a Webserver (in production) than in Zig, simply because Rust serves this purpose better than Zig does. And i personally can consider Zig to be my favourite Language.
I would also never (at least right now) write Website frontends in either Zig or Rust, i think JavaScript in this case, is the obvious choice, because it has been developed (over years) for this (and unfortunately other) use case(s).
Re: Zig as an alternative to writing unsafe Rust
#206Earlier quoted context omitted.
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 woul…
Re: Zig as an alternative to writing unsafe Rust
#207Earlier quoted context omitted.
It might be convenient at first but could become a frustrating bug if you change the struct fields and also less readable in some cases. It has its upsides but I personally think making the syntax more complex for this one detail isn't worth it. Side note: matching f64 by value isn't a good idea either way, is deprecated and will become an error in the future.
>matching f64 by value I wasn't thinking about matching floats by value, just destructuring a Point to obtain the coordinates as separate variables. Come to think of it though, as Rust already allows let Point{x, y} = pl there would be little benefit to allowing positional matching (and in fact it would create a nasty ambiguity). So yeah, as you said, you'd have to reserve the positional syntax for initialisation. My…
Yes, though at least the language gives you tools to make it more convenient. In the previous examples that would be constructors, and macros can help too (`println`, `vec` etc. exist for that reason).
I myself like to create tiny macros to shorten things like `UnicodeSegmentation::graphemes(s, true).count()` when I have to properly handle unicode. Sure I would prefer to have it be shorter from the start, though that wouldn't make it as obvious how expensive the operation is compared to just getting the size in bytes.
Re: Zig as an alternative to writing unsafe Rust
#208Earlier quoted context omitted.
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 woul…
I don’t really care for your examples of defaults being abused in C++, because all of rust’s workarounds like builder pattern and the default trait have the same potential to be misused while also impeding performance. They also suck for ergonomics, see bevy and polars. Rust already has a huge function colouring problem with async and mut and the lack of defaults only makes it worse.
Similarly for generics. Templates are simply better. Don’t use the power if you’re scared if it, that’s the great thing about freedom, you won’t be forced to. C++ can always do something the Rust way, nullifying everything you’ve said, but the other way around is not true. Rust sacrifices the complex case to make the simple case a little simpler and just leans on macros to do everything else. “Rust just allows coherent things” is a typical example of the bullshit rust programmers spew when they don’t have an actual response but want to say something anyways because it’s completely wrong. Plenty of useful template functionality is impossible to replicate in rust. For example:
Re: Zig as an alternative to writing unsafe Rust
#209Wait, the benchmark to find the 35th fibonacci number took 1.077s for the Zig VM vs 1.657s for the Rust VM? I realise that these VMs are going to be totally idiomatic Zig/Rust, with the most straightforward implementation possible, and little-to-no performance tuning, but even so - that's gotta be a typo, right? Or it's actually finding `fib(350)`? Or each "run" is actually finding `fib(35)` 100 (1000?) times?
I think the VM is operative here. My native Rust implementation found fib(35) in 51ms, but my Python implementation took about 1500ms (similar to their measurements). (I eyeballed the assembly to make sure the native implementation was recursive, but that's the extent of my rigor - consider these napkin numbers.)
I should have been expecting it. You're testing the performance of the runtime, not the program, so of course you want a bad implementation of the algorithm to stress the runtime as much as possible.
(My tail-call Python implementation tops out at fib(997) in 720ms. Calling fib(998) gives me a "RecursionError: maximum recursion depth exceeded". AIUI python is never going to optimise away tail calls, but because the tail-call variant is O(n) anyway it still works out orders of magnitude faster.)
Re: Zig as an alternative to writing unsafe Rust
#210This pretty much mirrors my experience. Rust is the inverse of Perl: It makes the easy stuff hard. Writing basic data structures isn't a niche, esoteric edge case. There may be a crate that "solves" what you're trying to do. But does it rely on the std---(i.e., is it unusable for systems programming)? Is it implemented making gratuitous copies of data everywhere? Does it have a hideous interface which will then pollu…
> Writing basic data structures isn't a niche, esoteric edge case.
Writing basic data structures isn't "easy stuff" in any low level language. It isn't in Zig by any means, nor in C nor in C++