3 ms·
Yeah, they make sense, just surprising that C++ is finally tacitly admitting that iostreams were a mistake. I kind of wonder why anyone thought iostreams would
by jordigh 3y ago
Yeah, they make sense, just surprising that C++ is finally tacitly admitting that iostreams were a mistake.
I kind of wonder why anyone thought iostreams would be a good idea to begin with. I don't think anyone but C++ ever created a comparable interface.
- q845712 3y agoI could be wrong as I was young and not yet in the field, but my impression has always been that sometime in the 80s/90s as the whole "networking, world wide web, wowie!" moment happened, there was this idea that "maybe on a local computer everything is files, but on the network everything is streams. Hey, maybe everything is streams!?" and C++ just happened to be creating itself in that zeitgeist, trying to look modern and future-thinking, so somebody decided to see what would happen if all the i/o was "stream-native". IDK, it'll probably make more sense in another 15 years as we clear away the cruft of all the things that tried to bring "cloud native" paradigms into a space where they didn't really fit...
- GuB-42 3y agoI think it is more simple and technical that that. The big thing is that they wanted type safe IO. Not like printf where you can print an integer with %s and the compiler won't have a problem with that, and it will crash. Reusing bit shift operators for IO is quite clever actually. If you have operator overloading, you have type safe IO for free. Remember C++ came out in the 80s as a superset of C, these technical considerations mattered. std::println doesn't look like much, but it actually involves quite significant metaprogramming magic to work as intended, which is why it took so long to appear.
- tialaramex 3y ago> Reusing bit shift operators for IO is quite clever actually It's a miserable trap. Operators should do something in particular, because of the Principle of Least Surprise. The reader who sees A + B should be assured we're adding A and B together, maybe they're matrices, or 3D volumes, or something quite different, but they must be things you'd add together or else that's not a sensible operation for the + operator. When you don't obey this requirement, the precedence will bite you as, as it does for streams. Because you forgot, these operations still get bit shift precedence even though you're thinking of this as format streaming it's just a bit shift and happens when you'd do a bit shift... Streams looks like something dumb you'd do to show off your new operator overloading feature, because that is in fact what it is. It should have existed like Mara's whichever_compiles! macro for Rust - as a live fire warning, "Ha, this is possible but for God's sake never use it" - but instead it was adopted for the C++ standard library.
- Conscat 3y agoPeople have investigated better solutions than iostreams for decades. But creating a near perfect interface is difficult in C++ because you have almost infinite control over the compile time and runtime characteristics of it. It has to compile fast, it has to be extensible (even the formatting syntax is interchangeable and programmable here), it has to give formatting errors at compile time, and it has to run nearly optimally. Victor Zverovich cracked the code, but only after Meta, Boost, and many others put tons of work into their own attempts. Imo, std::format is the most complex part of the standard library so far in terms of its implementation. Iostream predates parameter packs, which is why they use << for a variadic API.
- munificent 3y agoiostreams required only early C++ features and in return gave you: 1. Type safe string formatting. You'd get a compile error if the value you tried to write didn't support it. 2. User-defined formatting support for user defined types. You could make instances of your own class support being written directly to a stream. Sort of like how some other languages let you override `toString()`. 3. No runtime dispatch for #2. Unlike Java, C#, etc. the user-defined formatting code for your type is called statically with no overhead of virtual dispatch. Using operator overloading to achieve all of those was really clever and led to a very powerful, efficient, and flexible system. It's also just unfortunately pretty verbose and kind of weird.
- secondcoming 3y agoI don't think I've ever met a C++ person who likes iostreams and claims they're not terrible.