I write Python and I’ve never had a problem sticking with os.path.join.
I’m pretty lukewarm on this. I’m fearful of the precedent it would set (or, more precisely, fearful of strengthening an existing precedent), and frankly, the utility seems marginal at best. Don’t get me wrong, it’s definitely cool, but that isn’t a compelling enough reason for me personally.
So I think concatting paths with / is awesome and I love the idea of a language that does that. But I think this feature of Swift is awesome: you can overload any character in the Mathematical Operators, Miscellaneous Symbols, and Dingbats blocks. I am an operator overloading radical.
I just don’t know if Rust loves operator overloading. The standard syntax of Rust is fairly complicated on its own without throwing in magic overloaded operators. I don’t think this feature feels very Rusty.
However, I definitely think that if this is included, the typing should absolutely be impl<P: AsRef<Path> Div<P, Output=PathBuf> for Path.
Hi, I’m a C++ developer working with code that uses boost filesystem. Actually, I’m working on such code right now on my second screen…
I really dislike the use of the / operator as a path concatenation in boost. I find it very annoying to work with. Having a division symbol out of nowhere is kind of perturbing. I hear the argument that / is the same symbol used for paths delimiters, but keep in mind that the full expressions will not look like filesystem paths at all. They will mostly look like normal lines of code with a division symbol thrown in!
I'm totally with the argument about taking a bound generic. My vote is now for don't do this. Use DSLs inside macros instead.
Not really, it makes the allocation explicit. Like when appending an element to a Vec: vector <- value; desugars to vector.push(value); after an inlining or two
I’m against further binary operator overloads like this, in particular because of the Path vs PathBuf asymmetry and confusion for users in &Path vs &PathBuf vs PathBuf.
Right now we allow String + &str but neither &str + String nor String + String, let’s not replicate that further until we have a solid solution.
as well. path.join(other) is instantly understandable, where as path / other is not. If this were to be implemented, I'd have to add a lint denying this in my own crates, just for my sanity.
It's also quite confusing that someStr + "foo" mutates the original someStr. I would never have expected that, from any other language I've used.
It doesn't mutate it. It takes the String by value and returns a String. It's quite neat how that works out, to easily allow buffer reuse and O(n) string concat with +, but the details really are opaque to newcomers to rust.
We can't call it mutation since it moves the variable. Of course in the implementation, it takes the string, reuses it (pushes to the end) and returns it, but in Rust semantics it consumes (String, &str) and produces String.
This is really a strength of rust's built-in move semantics, but asymmetry also makes it confusing.
Yes, the move prevents the mutation from affecting much. Still, other languages’ usage of string concatenation make this seem like the expected: &str + &str -> String.
I totally love the syntax and simplicity. But it just doesn’t feel correct to allow a path to be passed to fn test<T: Div>(t: T) -> <T as Div>::Output. Div definitely sends the wrong signal.
…
How about allowing multiple traits for the same operator? xD
I’m sorry for bringing up String addition, but it does demonstrate a problematic asymmetry. The bar is set, any further operators must do better than that.
We don’t actually need to deprecate it. I plan to add a lint to clippy that at least warns on x = x + ... for x: String, suggesting push_str(...) instead.
I feel we’re getting a bit of track here. I agree that using a Path (or PathBuf for that matter) in place of a Div trait object could lead to confusion.
However, this hasn’t stopped us from having Add on String, with the same consequences (except that Add is probably much more widely used than Div.
I suggest that we either follow through and (besides adding Div to Path) impl Zero for Add where the zero be an empty string (that way, we could sum over strings) or deprecate Add for String altogether. Anything else is a half-solution.
I instinctively strongly disagree with this line of argumentation, but for some time couldn’t figure out why exactly.
Having though about this for a while I think the gist is the following:
(u32, +) is a semigroup, so is string concatenation (String, +). As a result supporting Add on strings makes some sense. Some (many?) algorithms generic over Add will actually work on strings, and provide a sensible result (cf. your own sum example. If I’m not mistaken a slightly adapted implementation of sum could actually get away without requiring Zero).
However, (u32, /) is not a semigroup. Algorithms generic over Div are unlikely to ever yield a sensible result applied to a Path. On the other hand joining Paths is a semigroup, which behaves almost identically to string concatenation.
As a result of that line of though, you might actually be able to convince me that Paths should have an operator overload for joining them, but that operator would have to be +, so it gets the same “benefits” that String does.