Are we referring to reference implementations? I have always found it easier to understand the C code, as Rust and Python tend to obscure too many details behind high-level abstractions.
C is simple enough to know what is going on, IMO.
For example:
numbers = [1, 2, 3, 4, 5]
squared_numbers = [num * num for num in numbers]
print(squared_numbers)
vs.
fn main() {
let numbers = vec![1, 2, 3, 4, 5];
let squared_numbers: Vec<i32> = numbers.iter().map(|&num| num * num).collect();
println!("{:?}", squared_numbers);
}
vs.
#include <stdio.h>
int main() {
int numbers[] = {1, 2, 3, 4, 5};
int squared_numbers[5];
// Squaring each number
for (int i = 0; i < 5; i++) {
squared_numbers[i] = numbers[i] * numbers[i];
}
// Printing the squared numbers
printf("[");
for (int i = 0; i < 5; i++) {
printf("%d", squared_numbers[i]);
if (i < 4) printf(", ");
}
printf("]\n");
return 0;
}
Python and Rust here seem concise and elegant, but can be more difficult to follow to the unaccustomed due to obscurity. I am sure there are examples that involve more higher-level abstractions, and reference implementations typically seem to use a lot of said abstractions. In case of this Rust code, abstractions (like iterators and closures) can also make the code more challenging to follow for those who are not accustomed to functional programming paradigms.
What I am trying to say is that the C implementation is more straightforward, IMO.
I was referring to stuff like the size of CHAR_BIT depending on the platform.
E.g., SystemC exists as a superset to allow hardware design in C, because ISO C isn't explicit on many occasions.
People who write C nowadays generally try to write it in the most "boring" and easy-to-read way possible, I think. But C can also be hard to understand if it uses a lot of side-effectful expressions and pointer arithmetic. Just look at "How Old School C Programmers Process Arguments", which looks over an excerpt from K&R [0]. To make your code slightly harder to read, while still being plausible, you could change it to use pointer arithmetic, like so:
// Printing the squared numbers
printf("[");
for (int n = 5, *p = squared_numbers; --n >= 0; p++)
printf("%d%s", *p, n > 0 ? ", " : "]\n");
> as Rust and Python tend to obscure too many details behind high-level abstractions.
C on the other hand forces handling too many low level details for a reference implementation IMO. Rust also isn't really good in that regard.
In a reference implementation what needs to be made explicit is the logic that needs to be implemented, rather than details like memory management. For that I would prefer something like Datalog instead.
There's no way that C implementation is easier to read than the Python one. There's no high-level abstraction going on there and the list comprehension reads like natural language.
I agree Rust often gets distracting with unwrapping and lifetime notation.
I know it is easier to read, and it is not difficult to figure out what is going on (in this case), but many languages do not support list comprehensions (for example), so you have to implement it in a way that is similar to the C version, making the C version more helpful.
The example above may not highlight what I was trying to, however.
Perhaps Ada could work even better than C? It is verbose, yes, but you will immediately know what is going on.
My point is, that in my opinion verbosity is better than conciseness in cases of reference implementations.