On the very first run of the port, immediately, I've found a bug due to C weak typing. After a few days, I've found a few buffer overruns.
My take is that there are two types of programmers: those who admit they can't avoid making memory safety mistakes, and real programmers, who don't make such mistakes, and happily keep programming in C/++.
EDIT: Just for fun, I've randomly picked up another C program, written in C17/C18. Immediately found a bunch of problems (not sure if there is any impactful, or not), including inconsistent function prototypes.
Of course there are cases where memory safety issue cause security problems, but not in all cases. If for example by a very uncommon sequence of keypress on my washing machine I cause a buffer overflow, worse case scenario the microcontroller hangs and I have to unplug it and plug it back in again (but hopefully there is a watchdog that resets the processor automatically). A lot of C programs don't even have an user interface, because for example are embedded in device that has no external input (for example a microcontroller that manages the operation of a power supply).
I absolutely agree. There's a class of programmers that would rarely if ever make such mistakes (e.g., Torvalds), and to them, C is freeing.
For the rest of us lesser programmers, the handrails of a borrow checker are necessary.
Firstly, you would implement From rather than Into. Into is blanket-derived for From. So if B implements From<A>, then A also implements Into<B>.
And no, you don't have to do this. If the function is never going to be generic, there's no sense in writing it that way. Solve the problem at hand, you can always go back and add abstraction later.
I really like Rust. I hear people say that it's hard, but I don't think it's harder than the problems it solves.
I think I’m misunderstanding, because I don’t see how this is possible given that you could be losing information in the conversion. Is this only for isomorphic types?
I'm in the same boat. I've been in this industry for a long time and generally good at spotting hype. I try to avoid the endless wheel reinvention that goes on.
That being said... I hate to be the Rust evangelism strike force, but give it a try. The hype is not ebbing away because there's substance there.
IMHO it's the first real alternative to C and C++ that brings a beneficial paradigm shift without sacrificing performance or the ability to code close to the metal. You can write systems code that is provably safe in terms of catastrophic memory errors and is orders of magnitude less likely to have threading bugs. (It's still possible to leak memory or have a deadlock, but it's harder to do and easier to diagnose. More importantly neither of these errors are likely to lead to catastrophic security vulnerabilities.)
As with C there is definitely a learning curve. New C programmers get crashes all over the place until they get it. New Rust programmers get beat up by the borrow checker and other type system stuff until they get it. Luckily they've put a massive amount of work into making the compiler's errors comprehensible.
After getting good with Rust I am now more productive in it than C and C++. It's the first attempt at a C replacement I can say that about, and I've tried a few. The only other languages that are more productive than C are higher level languages with fat runtimes not "close to the metal" languages.
Edit: the part of Rust that garners the most complaints is async, and I'm still a bit on the fence about it. It's usable but needs work in the standard library to solve the "async runtime lock-in" and dependency hell problems. Also needs some better libraries in general. Most of the issues with async are in the libraries (or lack thereof) not the language. It was a mistake not to have the async runtime in "std."
But honestly the fact that you can do async this way safely in a bare metal language is impressive, and the only way to do that much better is fibers (a.k.a. coroutines, go-routines) and that generally requires a fat runtime. Go just compiles a fat runtime into all your binaries to get goroutines.
At this point, it probably won't die out. The time to die was in the beginning, when they set to do overly ambitious things that had a high chance of not working. People have been wanting what it offers for quite a long time.
It's a matter of the more global design - factoring out the nitty-gritty things in some central places removes many bugs without you having to think about it. A lot of "usage" code then looks very simple, almost python-like. Variables and function calls. A few ifs and elses, a little bit of arithmetic.
Look at the Linux kernel for example. It is superficially not pretty, but you have to walk around quite a bit for example to see explicit locks and unlocks. It's a matter of factoring out the hard stuff in central places. This is a skill that is totally unrelated to the language you're using.
Yes, bugs happen to everyone, and more so in C than some other languages. Yes, there are security problems that come from lack of memory safety. But simply in terms of productivity, I feel that C is a very good tradeoff for me.
For me, C is the lingua franca. With C I can read kernel source, I can read systemd source, I can read firmware, boot loader, etc. I want to specialize in the language that gets me the most bang for my buck. Rust is a compelling future, but it's still the future and not the present, and the present doesn't seem to be going anywhere fast.
Another time I decided to try and get OpenGL running on Win32 with Rust in an evening. I failed to find a satisfying way (free of boilerplate and magic incantations) to do it. Probably interfacing with the system isn't that easy and/or you're supposed to use specific wrapper crates. Don't remember the details anymore, but it's definitely true that existing infrastructure has a lot of inertia. What Zig is doing in that space is a smart move - it has a C compiler built in, and if I understand correctly it lets you interface with C system headers pretty seamlessly.
You crazy bastard. I can see you're not going to get promoted by power-hungry bosses anytime soon! Seriously, I love C. As a webapps guy I picked up Go for my latest projects and have loved it. Feels like the C compilers of yore, that ran fast and had straightforward semantics, even in the tooling.
To me, C is almost entirely a non-language. It's a culture where you focus on what you want the computer to do (and optimize that), instead of optimizing what you write (and ending up with something convoluted that will be hard to read in 1 month).
I refuse to do things that many don't even give a second thought - such as, do I really need to implement the Into<T> trait and use x.into() to do a conversion? Isn't it better if I just write the function that I'm using explicitly? That way it will be easier to see what function is used, and the likelyhood that I'll have to change that code later I deem comparatively small.
C has its flaws but I know them quite well by know and have learned to walk around them. And it has some "flaws" that are misunderstood strengths to a degree.
More and more "humble" languages have been started in the recent years, but there is little incentive for me to try and switch. And even of those, almost all add some clever things that I'm nervous might be _too_ clever.