On Tue, Apr 20, 2021 at 06:45:40AM -0700, Jeremy wrote: > Regarding readability: in terms of the just the standard libraries, I > agree that Rust is more readable than C, especially it comes to iterating > and generics.
impl I<Don't> { fn know<'a, How::Someone>(could: &'a Say) -> This<'a> with A: Straight<Face> + Send + Sync + 'a { ... } static struct this * is_readable(struct to *me) { ... } Syntactically, Rust's generics are a total mess. Rust's iteration is even worse. Something that should be a simple matter of for (i=0;i<N;i++) is turned into a frightful palaver with the compiler with layer upon layer upon layer of complexity, and in the end it all ends up getting compiled (over the course of several minutes) into exactly the same for loop! > etywyniel has suggested an implementation of generics in C that use M4: > https://github.com/etwyniel/c-generics I really like this. Thanks for linking to it. This is the sort of thing that we (the programming community in general) need more of: stepping back from complexity and doing the minimum needed to actually work *effectively*. Does this have all the features of C++ templates? Of course not. It has the features one actually needs if one wants generic data structures (which one probably doesn't need anyway). > Regarding ISO-standardization: could you explain a bit more about the > value of this? Standardisation means there's a document you can read to understand whether something is a bug in your code, a bug in someone else's code, a bug in the implementation or (heavens forbid!) a bug in the specification. ISO-standardisation is the gold standard of standardisation because the rigorous process behind it ensures that every necessary detail is fixed down in precise technical writing. One of the side-benefits of this kind of writing is that it gives people a language in which to talk about the language. I'm not sure whether before C standardisation terms like declaration-specifier and declarator were precisely demarked in the way they are now. But now that they are, two people using different implementations in different countries with different backgrounds can establish a consensus on the correct syntactic interpretation of any piece of code. Of course in the case of C++, that interpretation might be 'it's syntactically correct... if the Riemann hypothesis is true'. But it's better than you can do for Rust, where what is correct behaviour is... whatever rustc does. Rust evangelists love to talk about how much undefined behaviour C has, but it only has undefined behaviour because it has defined behaviour! Undefined behaviour is behaviour that isn't defined... by the standard. Everything in Rust is undefined behaviour! > Regarding built-in concurrency: I would argue that pipe(3) & select(3) > is sufficient for built-in concurrency, though I understand this debate > is on-going. +1. When OOP became trendy in the 80s-90s-00s, almost every language out there either added an OOP system or an 'Object ____' variant was created of it with one. We now near-universally regard this as a pretty bad idea. It is my opinion that the profusion of async/await across the programming world will be viewed in 15 years like the profusion of OOP across the programming world is viewed now: a bad solution to a problem ("programming in the large" for OOP, "web scale" for async/await) that doesn't actually really exist! > I agree that Rust is better at marketing memory ownership. I'd argue > that Rust is better at marketing as a whole. > ... > Rust is an incredibly fun language to write in, and I believe that the > enthusiasm for it is unparalleled, however, I'm not certain it's doing > anything better in terms of debugging & static analysis compared to the > C ecosystem. Rust is marketed to a... certain kind of person. I don't think I need to go into detail. As for their enthusiasm, my view is that they're incredibly enthusiastic and evangelistic about it for one main reason: it makes them feel smart, and little else does. --- We'd all be better off if we focused our efforts on tools to make C programming better. I was thinking today about how useful it would be to have a way to indicate that a particular variable shouldn't be able to impact the running time of a function for cryptography purposes. (Generally, the control flow, resource use or running time of cryptography-related functions shouldn't depend on secret values, as those all have the potential to become side channels). If a compiler or compiler plugin recognised such a directive, it could ensure it didn't destroy that property. A static analysis tool could check the resulting object code and warn you. Other tools could verify it with randomised automated testing, etc. Generally speaking, these things would be better off as unobtrusive extensions to C, able to be ignored by a compiler or other tool without affecting the meaning of the code to retain compatibility. Rust has many good ideas but it's just not trendy to implement those ideas in C sadly.