Not that I agree with your point, but cyclomatic complexity checks are actually implemented as a compiler plugin in rust-clippy project[1]. You'll get a compile time warning if your function becomes too complex.
That is true, although I don't know how helpful that is aside from checking that the annotation is not broken? Much like `const`, the annotation would have to be opt-in either way:
* Rust doesn't infer function types (on purpose)
* like const (or Copy), the removal of the flag is a breaking change, so it should not happen implicitly
So functions would necessarily have to be explicitly marked as e.g. `convergent` or whatever. And while callers of `!`-functions would be easy to check for, I don't think rustc is currently smart enough to infer the totality loops in general.
While it may be convenient, it's truly worrying such (EDIT: was "many") syntactic special cases are going into Rust at this point.
(It may be the case that these things absolutely cannot be handled in a systematic way in a no-GC/no-runtime language, but I'd really like to see some evidence that this is the case.)
Rust has an optional clippy lint that will warn/forbid all basic arithmetic that might over/underflow, forcing you to use dedicated methods with explicit behaviour instead.
It's very annoying , but I use it in code where this is critical.
There are a lot of operations per line in that code. I would expect anyone interested in maintainability in any language to not write code like this. I don't think this is representative of Rust.
Rust does do the loop condition (well, comparing `my_signed_int` to INT_MAX) even with optimizations: https://godbolt.org/g/dnBEJi
(You need to put a side effect such as I/O in the conditional branch for it not be optimized away, "pub" before the function declaration for it not to be eliminated as dead code, and pass `my_signed_int` as an argument so the condition isn't constant-folded).
Clang OTOH optimizes away the condition with even the lowest optimization level (-Og) turned on, as you'd expect: https://godbolt.org/g/8ftkED
A nice quality of the `guard` in swift is that you can chain multiple conditions, which is harder to do in rust (maybe with some macros a la if_chain?)
It's true that a "checked_as" would come handy from time to time and seems to be in line with the "Rust spirit". But again, since the author seems to be arguing in favor of C it seems like an odd complaint. C even makes it tricky to check for integer overflow while Rust has the checked_ family of functions. In C if you get it wrong it's undefined behavior territory baby.
Ditto with the tuple thing, C doesn't have tuples and won't let you destructure anything.
I guess my overall point is that these complaints seems to pit Rust against some other high level languages like Common Lisp or Haskell but his conclusion is basically "C rulez, Rust droolz".
Also, it has often been surprising to me how code that looks like it's entirely read-only will try to move stuff.
E.g, this works:
let numbers = [1, 2, 3];
for n in numbers {
println!("{}", n);
}
for n in numbers {
println!("{}", n);
}
This doesn't work:
let numbers2 = vec![1, 2, 3];
for n in numbers2 {
println!("{}", n);
}
for n in numbers2 {
println!("{}", n);
}
I understand why that is and I know how to fix it, but I don't like it. There is a long list of things in Rust that I find understandable but also unpleasant. In that sense it really is a worthy successor to C++. Smart people making unpleasant decisions for good reasons.
Doesn't address the OsString complexity- but the author has another post on strings in Rust that you might be interested in [1]. It at least addresses how Rust does hide a lot of regular `String` complexity that `C` doesn't.
Then maybe rustc ought to have diagnostics that warn if a recursive function won't be optimized fully, and then I can either avoid recursion or rewrite to fit into the optimizer, but having to appease a changing optimizer isn't what I'd call maintainable code, so a function attribute might make more sense.
This is the difference between Rust and C like languages, one optimizes for the usual case and has a simple implementation and the other goes to great lengths to be correct in corner cases at the cost of a lot of complexity.
A guess: very, very difficult. Writing code to satisfy Rust's checking is not much harder than writing C[1], but converting arbitrary C to satisfy Rust is something completely different.
[1] An' I say it as shouldn't. C is my natural language.
There is a rumor[1] even Rust has yet to get polymorphism right:
>I'm using nalgebra for math. I'll write a bit about it here, because I think it's relevant to Rust as whole. I'm not sure if I actually like it. It's so heavily templated that most of the error messages are impossible to understand, so I usually just double-check what I wrote and try to guess what's wrong. It's also where rust's documentation generator gets in trouble. Signal to noise ratio there is <10%. Not sure how to fix that. Anyway, my point is that maybe it's not always the best idea to write code as generic as possible.
The most principled approach there, I think, would be to build a little Expression data-structure, and then feed it to an evaluation routine, trusting the optimizer to compile the whole thing down to something efficient. If Rust didn't have operator overloading anyway, you could do the job with procedural macros.
In practice, if I had to write that quasi-monstrosity in something like C, I'd probably just comment it as clearly and liberally as possible, to the point where I manage to reassure the reader that the final expression is correct; and then add a // See above: Please DO NOT edit this expression directly!// comment as an extra caution.
[1]: https://github.com/Manishearth/rust-clippy/wiki#cyclomatic_c...
reply