4 ms·
Allow me to introduce you to C++’s new std::filesystem::path class, which overloads the divide operators "/" and "/=" to concatenate two paths. (Not to be confu
by electrograv 6y ago
Allow me to introduce you to C++’s new std::filesystem::path class, which overloads the divide operators "/" and "/=" to concatenate two paths. (Not to be confused with the “+=“ operator, which also concatenates paths, but with subtly different behavior.)
Why did the division symbol get chosen for a concatenation behavior, of all things? Well, I suppose because it looks kind of like how we write paths with slashes, e.g. “dir/subdir/etc”. While I understand how this might be fun aesthetically once you already know the types involved, I find this completely opposite-than-numeric behavior here to be quite ambiguous and unintuitive.
- edflsafoiewq 6y agoPython's pathlib does that too. It doesn't sound like it's bitten you though; it's just an aesthetic disagreement.
- electrograv 6y agoI suspect it might have bitten me if I wasn’t so lucky to encounter “/=“ first, which lead me to read the documentation and discover the different kinds of concatenation (“+=“ and “/=“) and their behavior. To someone just skimming the code though, it might not at all be obvious that “+=“ and “/=“ both exist as concatenation operators, and their behaviors are different. But yes it’s an aesthetic preference or opinion; I tend to prefer operators only when their only possible behavior is nearly so obvious that no documentation should be necessary. When that’s not the case, I prefer named functions/methods because they permit being explicit about subtle differences.
- edflsafoiewq 6y agoThere are actually named member functions for those; they're append and concat. Can you guess which is which? I can't. append is actually "append with directory separator", which is weird, because I'd expect append to be a string-like append to match the append function on std::string. Instead concat is a string-like append despite the fact std::string doesn't have a concat member. OTOH / is an instant mnemonic cue for "append with separator", and + matches the + on std::string.
- electrograv 6y agoYes, I 100% agree with you that “append()” vs “concat()” are certainly no less confusing in their differences than “/=“ vs “+=“ (and the latter are arguably less confusing due to the mnemonic effect you mention). In fact, to generalize, I think we can fairly say that operator overloads are akin to extremely short function names; in some cases they may work out great when there is not much ambiguity implicit in the underlying problem, but in other cases a longer and more explicitly descriptive name is required to disambiguate. In this case, “append” and “concat” seem quite poor names for different functions, given that they are virtually synonymous and therefore do nothing to describe or distinguish their differences of behavior. So my claim is that we can do significantly better at resolving ambiguity with carefully named functions (or other approaches) than operators, or tersely/ambiguously named functions (like “append” and “concat”). Of course, this does come at the cost of code verbosity. Just where we should draw the line between too ambiguous vs too verbose, is of course a difficult subjective matter.
- secondcoming 6y agoTo be honest, I don't like the << operator either. I doubt I'll like the (optional) use of | for ranges too.
- mhh__ 6y ago<< was necessary at the time
- edflsafoiewq 6y agoWhy?
- mhh__ 6y agoC++ didn't have variadic templates so passing along a stream with an operator was more ergonomic enough and typesafe.
- edflsafoiewq 6y agoI suppose you're comparing against std::format, but the question is why overloading an operator (cout << "foo") would have been necessary vs a regular member function (cout.put("foo")).
- mhh__ 6y agoBecause it had to replace people using a comma inside printf. The member function could only accept one argument cleanly so you would've to chain them like cout.put.put.put
- lasagnaphil 6y agoActually, slashes in filesystem::path is one of the operator overloading uses I really like in the C++ standard library (It’s time-saving, it’s useful, it’s easy to read). What I really don’t like is the IO operators << and >>, which I think is an incredibly horrid language design mistake. (It’s slow in performance, it’s hard to add formatting options, hard to read).