zerofan
My point about remote exploits, airplane crashes, and cops is not about me. Yes, public facing software needs to be careful, but (fun metaphor) that's like saying prostitutes should use condoms. Web servers, browsers, firewalls, and the like are built specifically to communicate with untrusted entities. That's some of the most promiscuous software out there, and yes it gets exploited. But most people don't need to use condoms with their wives, and nobody is going to exploit software a newbie wrote and runs on his home computer. Safety should not be the fundamental criteria for a newbie programmer to choose a language and learn how to write fibonacci or hello world. When they're ready to write nginx, then they should be careful.
My point about the questionable productivity gain and safety was a reply to your estimate of the billions of dollars lost. If you're not more productive, and you aren't really safe, then you aren't going to save those billions.
> What, you can't use that explicit separation of what is known safe and known unsafe to point out computational problems and ways they can be solved? I find that hard to believe.
I didn't say anything like that. We're talking past each other.
> Unless you think unsafe is Rust but "lesser, not really". It isn't. It's part of the language.
(Metaphor time again) I've got a really safe bicycle. When the safety is on, children can't get hurt while riding it. If you care about the safety of the world's children, they should use my new safer bicycle. Oh, but you can't pedal it on paths I don't provide unless you disable the safety. Is my bike really that safe?
> 1: https://www.exploit-db.com/remote/
I have no idea how many people compiled and ran a program today. It's probably millions. Bayes's theorem might be a useful way to normalize that long list you linked. I don't see a single program from a home programmer on that list.
> Which wasn't the point of that at all. It was to point out that you[r] assessment of how much time is wasted working around problems in each case is irrelevant given your vastly different experience levels.
That was almost my exact point, and it's odd you're repeating it back to me. I guess I could've laid it out more plainly.
> [Metaphors] Driving it into irrelevancy through focusing on minutiae is a useful rhetorical trick. [...] at the extreme end if done purposefully is not acting in good faith
Using a metaphor is a rhetorical trick. If you want to explain something to a non-technical audience, maybe analogies "get the hay down to the horses" so they can have at least a limited understanding. However, we both seem to understand programming languages so talking about roads obfuscates the discussion, leaving me to wonder whether there really is a parallel between the two topics. I know more about programming languages than I do about bike paths.
> Depending on the segfault? I could. It would take me a lot of work, because it's been nearly 15 years since I paid much attention to that, but I have done it before.
Even if I offer to run malicious data, it sounds to me like a low probability event - probably lower than my being in an airplane crash or shot by a cop. It's not something I should fear today. Over the last 25 years, I've had lots of segfaults, but I think I've done the most damage by accidentally overwriting files. I'm a little afraid of that.
> No, you don't optimize your life around them, but you might also support checking of identities on international flights to prevent access to your nation from known terrorists.
No, I definitely would not. It's very easy to get into this country, and an organized (dangerous) group would have no more difficulty than the drug dealers do smuggling cocaine. There is no benefit to harassing millions of citizens if you can't actually stop the problem.
> Here's the thing. It's not about you.
Are you suggesting the only people allowed to share their experiences in a thread like this are new programmers and the people pushing their language? I was new once, and I survived lots and lots of segfaults. Don't you think neophytes should hear that? They're definitely getting a large dose of doom and gloom about the bad old days.
> Some percentage of C and C++ programmers are neophytes. [...] I think that reducing this has such a large impact, that this is of vast benefit to society at large (given the botnets we are currently seeing), and would total billions of dollars.
In one of your other comments, you indicated you haven't tried Rust yet. You should - you sound interested. It definitely has its nice parts. However, I don't think you will find the safety features to be a big productivity gain, and you will have to use unsafe code to accomplish tasks from a freshman level computer science book. Think about that - you can't cleanly use the safe subset of Rust to teach computer science to beginners... (you could do it with a lot of compromises)
Arguments by metaphor aren't my thing. It's very likely I would become more proficient at Rust if I programmed in it more. It's also very likely the poster above would worry less about memory errors if s/he programmed in C or C++ more. Yes, Rust is safer in some ways, but I still can't understand where all the fear of other languages comes from.
> having a dedicated bike lane at all times would probably be a good idea anyways.
I used to live in a city with a lot of dedicated bike lanes. I commuted to work on a particularly long stretch that was very popular for cycling. The majority of the cyclists refused to ride in the lane. It turns out that cars naturally blow the dust and small pebbles out of the main road way, but bikes don't do that in the bike lane. Cars also smooth out the pavement in their tire tracks. The result was a road that's 5 foot narrower for cars (speed limit 45 mph) with bicyclists in it (not moving 45 mph), a generally unused bike lane, lots of uncomfortable passing, and a lot of indignation from cyclists who claimed an equal right of way despite having a separate lane designated for them.
> Sure, maybe you've never hit a cyclist, and never will. That doesn't mean it doesn't happen enough that we shouldn't do something about it, because it does.
The city I live in now has many bike paths, completely separate from major roads. It's also a different climate, so there are less pebbles and they have street sweepers clean the road after snow season to remove the sand. There really doesn't seem to be much interaction between the cyclists and the cars. So should I choose a programming language with bike lanes on major roads or separate paths though the parkways? :-)
> No, a segfault at runtime is something that is possibly exploitable. A Panic is not.
Anything is possible, but it's very unlikely. I will write a program and intentionally put a buffer overflow in it. Can you send me some data that will exploit it?
Here's a metaphor that also isn't one: I'm not afraid of terrorists despite some high profile events in the last 20 years. I certainly wouldn't optimize my life around avoiding terrorist attacks because the empirical evidence shows me the probability is very low.
You never addressed my other "too clever" items in Rust. Does that mean, other than strings, we agree?
I guess I don't have to worry about the non-Scotsman strings then... You've heard the criticisms about Rust's strings before, and I'm unlikely to tell you anything you don't know.
I find it very obnoxious when people exaggerate what someone else said so as to make it easier to contradict. I gather you don't have any problem with that? Yet you do have a problem with people calling it out as bad behavior? Are you sure you know why you're policing anything?
> To your coworkers I would reply: would you like the compiler to handle error-prone memory deallocations? Or do you want to keep doing it manually and wait till runtime to find potential mistakes?
They don't really care about memory deallocations - the program will finish soon anyways, and the operating system will cleanup the mess. Sorry, they've already excused you from the office and have gotten back to getting their work done.
Btw, modern C++ programmers don't worry about memory deallocations either. You should find a better bogeyman.
[1] http://benchmarksgame.alioth.debian.org/u64q/compare.php?lan... (yes, most people disregard benchmarks, but you need someway to discuss performance)
I've spent a lot of time figuring out how to do completely mundane things in Rust. At this point, buffer overflows and use-after-frees are not my biggest concerns in C++.
> The scary thing isn't causing a segfault on your local machine. The scary thing is writing code that could segfault but doesn't do in testing until after you've deployed it publicly. If your compiler rejects code that can segfault, this is no longer a concern.
If your testing didn't catch the problem (which I can fully understand), a panic at runtime is not much different than a segfault.
> (Or replace segfault with a buffer overflow that leaks your private keys or something equally bad.)
I firmly believe the OpenSLL team would've used unsafe blocks in Rust to disable the performance overhead of bounds checking. That whole exploit was caused by sloppy optimizations, and Rust is not immune from that.
I didn't call Rusts type-safety of memory-safety clever. The clever stuff is lifetime specifications, a multitude of string types, traits as indications to the compiler for move vs copy, Box Ref Cell RefCell RefMut UnsafeCell, arbitrary restrictions on generics, needing to use unsafe code to create basic data structures, and many other things.
If I tried to advocate Rust in my office, many of my coworkers would simply say, "I didn't have to do that in Fortran, and Fortran runs just as fast. Why are you wasting my time?!"
> Having safety features that you know you can rely on allows you to take risks that you normally wouldn't in order to accomplish some really awesome things.
Unless you rush to publish a public facing version of your code, I can't see why you'd be afraid to take risks in any language. What's so scary about a buffer overflow on your home workstation running data from a source that's never even seen your program? It will just segfault, which is no worse than a Rust panic. If I could exploit your new code, it means I've already gotten so far into your workstation or server that I could just run my own code. Where does the fear come from?
> It's that it's really expensive to revisit old assumptions when circumstances change, [...]
That's very dependent on the type of work you do. Over the last 23 years, my job has been to write many small programs to solve new problems. It's not expensive for me because I've aggressively avoided making monolithic baselines. I have medium sized libraries that I drag from project to project, but I can fix or rewrite parts of those as needed without breaking the old projects.
> Is that a bad thing?
The appeal to beginners is fine, maybe even a good thing, but the condescending comments from beginners is a lot like listening to a teenager who thinks they know everything.
> What makes you feel like anyone's looking down their noses at you?
There're are no shortage of obnoxious comments from beginning Rust users here and on Reddit. If you can't see them, it might be because you're aligned with that point of view.
A recent one implied the whole world is going to end because of Heartbleed-like exploits. Don't they realize that despite the occasional high profile exploits, the world is generally running just fine? Don't they realize that the OpenSSL developers would've probably used pools of dirty memory to avoid allocation costs and unsafe blocks to avoid bounds checking had they developed that code in Rust? They got bit by sloppy optimization, and Rust isn't immune to that. I really wish people weren't so afraid of everything that achieving safety is their primary goal.
> Just because safety isn't a priority for you doesn't mean that the people for whom it is a priority are suddenly pretentious.
It's not pretentious if you make your own decision for your own project. It's not even pretentious to spread the good word and say how much you like Rust. It is very pretentious and condescending when you say something like in Graydon's article: """When someone says they "don't have safety problems" in C++, I am astonished: a statement that must be made in ignorance, if not outright negligence."""
Are you going to stand by that sentence? You probably should, because the newbies will love you for it, and it might help increase adoption of your language. It really shouldn't matter if you alienate a few of us old-timers who really don't have safety problems in C++.
To be clear, I like Rust. I've been following it for years, and I'm disappointed that it's not an adequate replacement for C++ (which I really don't like).
I think the safety aspect of Rust appeals to a lot of beginning programmers. They can feel safer looking down their nose at us dangerous C or C++ programmers.
> Rust is a parachute that always opens at exactly the right altitude
This isn't a good metaphor. Frequently it's safer to pull higher, and on some occasions, you're safer opening lower than you had planned... I think a canopy that always opened at the prescribed height would cause many unnecessary deaths. That doesn't say anything about Rust, one way or the other.
I remember installing it by cut and pasting one of the "curl ... | sh" commands there.
> Nothing about that code should be doing bounds checks, as it's just allocating an array.
I didn't dive into the macro definition for vec!, but I assume there is a loop in there to Copy the initialization element 10 billion times. I think you guys do bounds checking on the lower level reference to a slice that Vec uses. But I really don't know. If it's not that, then it was hanging or spinning doing something else. (Debug version of your memory allocator?)
I might be wrong though. What happens with your vector in this code?
using namespace mse::mstd;
vector<double> data(10);
double& dangling = data[0];
data.resize(100000);
double crashing = dangling;
You use a lot of typedefs, so I couldn't tell for sure, but I think your operator[] returns a C++ reference right?The problem here is there is only one operator[] for both reading and writing. This is a simple contrived example, and taking a reference like that looks artificial, but there are a lot of other ways in real programs to stumble on to this. (I don't think it's as bad as the Rusties do, but I stumble into this bug once or twice a year...)
The Rust folks seem to believe you need a borrow checker to solve this problem, but I think that a different container library in C++ could do the trick. For instance, favoring value copies instead of references, and returning a proxy object from operator[] instead of a reference.
Follow-up: I tried it with -O (don't know why I didn't think of that earlier), and it runs fine. So maybe the debug version is just generating terrible code, initializing by iterating through 10 billion bounds checks or something?
Anyways, more importantly, it works as I would like and does not behave as a 32 bit integer. I think I understand what you mean by "constrained" now. And clearly, I was wrong.
However, if most un-suffixed integers in real-world programs will become constrained (as you claimed), this further confuses me why i32 is the unconstrained choice. It doesn't seem like something so rare could be enough of a performance problem to justify being anything but the largest supported size.
In a later version, I implemented the specializations as inheritance on the abstract FingerTree base class (verbose, but it works), and I added Leafs and Nodes. Leafs are FingerTrees that hold your data, and Nodes are FingerTrees that point to other FingerTree instance. This dodges the recursive types problem. I don't know much Haskell, but I think it would be the C++ equivalent of:
data FingerTree a = EmptyLeaf
| SingleLeaf a
| DoubleLeaf a a
| TripleLeaf a a a
| EmptyNode
| SingleNode (FingerTree a)
| DoulbeNode (FingerTree a) (FingerTree a)
| TripleNode (FingerTree a) (FingerTree a) (FingerTree a)
| FingerSpine (FingerTree a) (FingerTree a) (FingerTree a)
Virtual methods on each specialization took the place of pattern matching. Not super elegant.If you pay attention to your usage statistics, I'll bet you drop 32 bit support before the May 2025 deadline we were discussing in the other thread.
The fact that C and C++ compilers generally chose to leave int at 32 bit on 64 bit platforms, combined with the standards requiring "usual promotions" for smaller types to go to int bites me all the time. I'm very happy that Rust dodges the promotions problem altogether, and I'm sorry if I'm wrong about the array subscripting thing (does the snippet I provided panic at 1<<32 or 1<<34?).
> And not everybody is running on 64-bit hardware, so it's a broader default.
That argument could be used to justify 8 or 16 bit integers... :-)
I don't think you get to play on both sides of that fence. Some of your team has been working on Rust for that long, but I doubt any code with sigils compiles, and I doubt there were many large projects using it then. I started my stopwatch at May 2015.
> Ten years is not that long a time.
Totally agree.
> I still agree that results at that point will be more interesting then speculating today.
We'll see on May 2025. :-)
I would prefer a str be a str be a str, regardless of how you got it. Lowercase type-name and fundamental like an integer.
I'm fairly certain I understand why Rust made the choice they did. I've read the forum threads at HN, Reddit, and users.rust-lang, and I've seen previous replies by you and other Rusties, so I hope you won't try to educate me about the performance advantages of having slices as references and another string type as an ownership class or why we need OsStr and friends.
If strings are the fundamental processing concern in your application, then I think you should be able to opt-in to that kind of micro-optimization and complexity, but it would've been better to spare the rest of us who have different concerns. I don't want to become a string expert to build a filename, and the default implementation could (at least conceptually) be always on the heap for all I care. Go one step further and implement the "small string optimization" (Alexandrescu's fbstring), and you'd probably get back most of the performance without nearly the complexity.
> Arrays are indexed by usize
I've spent the last half hour trying to troubleshoot why this line hangs:
let aa = vec![1u8; 10e9 as usize];
However, I'm at home using the Ubuntu under Windows thing, so maybe there's some bad mojo between Rust and my less than usual setup. (If you're interested, I have 32 Gigs of memory, and the equivalent C malloc and memset code runs just fine, so I don't think Rust is doing the right thing here...).Anyways, I wanted to test the commented out line, but I'm stuck for now. If that line would work, I'll admit I was wrong, but I think the uncommented line shows a similar complaint.
for ss in 0..63 {
//print!("{}\n", aa[1<<ss]);
print!("{}\n", 1<<ss);
}
> It's _unconstrained_ numbers that default to i32, not anything without a suffix.Looking at the present and the future, why is that a sensible default? Both x64 and ARM are going to use a 64 bit integer register for the operations, and many of those operations are going to be 1-clock throughput. You can probably find a counter example, but 32 bit integers aren't generally faster than 64 bit ones.