# Pre-Pre-RFC: / for Paths

**URL:** <https://internals.rust-lang.org/t/pre-pre-rfc-for-paths/2420>\
**Category:** libs\
**Created:** [July 31, 2015, 2:47pm UTC](https://internals.rust-lang.org/t/pre-pre-rfc-for-paths/2420 "2015-07-31T14:47:06Z")\
**Posts on this page:** 20\
**Page:** 1

<div class="post-metadata">

**Author:** ![llogiq](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/llogiq/32/13692_2.png) [@llogiq](https://internals.rust-lang.org/u/llogiq)\
**Post date:** [July 31, 2015, 2:47pm UTC](https://internals.rust-lang.org/t/pre-pre-rfc-for-paths/2420/1 "2015-07-31T14:47:06Z")

</div>

Python implements ` __div__ ` on `Path` objects, so that you can say `basePath / subdir` (if `basePath` is a Path and subdir is a `Path` or `str`).

Despite my usual reservations against overloaded operators, I’d propose adding an `impl Div for Path` to borrow this feature.

Rationale: It reads nice, and since `Path` types being intermingled with mathematical operations is highly unlikely, the risk of confusion is minimal.

Is this something you’d like to see?

---

<div class="post-metadata">

**Author:** ![DanielFath](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/danielfath/32/5372_2.png) [@DanielFath](https://internals.rust-lang.org/u/DanielFath)\
**Post date:** [July 31, 2015, 3:02pm UTC](https://internals.rust-lang.org/t/pre-pre-rfc-for-paths/2420/2 "2015-07-31T15:02:16Z")

</div>

I think cases like `list<T> + T` or `path/div` make sense, but mostly as an extension. I.e. a separate crate with syntax sugar.

---

<div class="post-metadata">

**Author:** ![oli-obk](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/oli-obk/32/3168_2.png) [@oli-obk](https://internals.rust-lang.org/u/oli-obk)\
**Post date:** [July 31, 2015, 3:27pm UTC](https://internals.rust-lang.org/t/pre-pre-rfc-for-paths/2420/3 "2015-07-31T15:27:05Z")

</div>

boost also overloads this: [http://www.boost.org/doc/libs/1\_58\_0/libs/filesystem/doc/tutorial.html#Class%20path-iterators-etc](http://www.boost.org/doc/libs/1_58_0/libs/filesystem/doc/tutorial.html#Class%20path-iterators-etc)

I found it very readable as long as variable names were long enough to not sound like mathematical identifiers.

Mad idea: a lint that enforces at least 4 characters for variables of type Path, PathBuf or references to either

---

<div class="post-metadata">

**Author:** ![stdsync](https://avatars.discourse-cdn.com/v4/letter/s/f04885/32.png) [@stdsync](https://internals.rust-lang.org/u/stdsync)\
**Post date:** [July 31, 2015, 5:01pm UTC](https://internals.rust-lang.org/t/pre-pre-rfc-for-paths/2420/4 "2015-07-31T17:01:59Z")

</div>

> [@llogiq](#):
>
> Is this something you'd like to see?

Yes!

---

<div class="post-metadata">

**Author:** ![Toby](https://avatars.discourse-cdn.com/v4/letter/t/7993a0/32.png) [@Toby](https://internals.rust-lang.org/u/Toby)\
**Post date:** [July 31, 2015, 6:44pm UTC](https://internals.rust-lang.org/t/pre-pre-rfc-for-paths/2420/5 "2015-07-31T18:44:24Z")

</div>

What makes this different to not overloading `+` for `String`s, which seems to have been shot down multiple times (including just before Rust 1.0, I believe)? For the record, I do like this idea though.

> [@ker](#):
>
> Mad idea: a lint that enforces at least 4 characters for variables of type Path, PathBuf or references to either

I'm not sure this would work well in practice - for example, having a `PathBuf` called `tmp` for a temporary file seems pretty reasonable.

---

<div class="post-metadata">

**Author:** ![llogiq](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/llogiq/32/13692_2.png) [@llogiq](https://internals.rust-lang.org/u/llogiq)\
**Post date:** [July 31, 2015, 8:14pm UTC](https://internals.rust-lang.org/t/pre-pre-rfc-for-paths/2420/6 "2015-07-31T20:14:22Z")

</div>

You could always call it `temp` 😄

On a more serious note, looking at functions that handle IO, they are usually not very arithmetic-heavy anyway.

I don’t think a lint will be necessary.

---

<div class="post-metadata">

**Author:** ![mdinger](https://avatars.discourse-cdn.com/v4/letter/m/97f17d/32.png) [@mdinger](https://internals.rust-lang.org/u/mdinger)\
**Post date:** [August 1, 2015, 2:27am UTC](https://internals.rust-lang.org/t/pre-pre-rfc-for-paths/2420/7 "2015-08-01T02:27:34Z")

</div>

This exact thing was just being discussed in [this reddit thread](https://www.reddit.com/r/rust/comments/3f77j0/blog_rusts_builtin_traits_the_when_how_why/ctm0ex9). My conclusion is that some people are just picky about what ops overloads should be valid.

Two valid critique I saw in a linked [RFC](https://github.com/rust-lang/rfcs/pull/203) for a new `Convert` op were [here](https://github.com/rust-lang/rfcs/pull/203#issuecomment-54097735) and [here](https://github.com/rust-lang/rfcs/pull/203#issuecomment-54096127). Other valid alternatives would be having a dedicated concat operator which would probably replace both `+` and this proposed `/` (it would also avoid the controversy these overloads bring).

Problematically, a concat operator doesn’t seem to be universally popular. Some don’t see the difference between `+` and concat. Others don’t want an extra operator (maybe it’s not important enough). Also `+=` overloading seems to be another alternative for some reason but I don’t really see how it’s any different from `+`.

---

<div class="post-metadata">

**Author:** ![comex](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/comex/32/2587_2.png) [@comex](https://internals.rust-lang.org/u/comex)\
**Post date:** [August 1, 2015, 5:49am UTC](https://internals.rust-lang.org/t/pre-pre-rfc-for-paths/2420/8 "2015-08-01T05:49:39Z")

</div>

As a useless data point, just the other day I saw a tweet expressing absolute horror at this feature in Boost 🙂

---

<div class="post-metadata">

**Author:** ![oli-obk](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/oli-obk/32/3168_2.png) [@oli-obk](https://internals.rust-lang.org/u/oli-obk)\
**Post date:** [August 1, 2015, 6:39am UTC](https://internals.rust-lang.org/t/pre-pre-rfc-for-paths/2420/9 "2015-08-01T06:39:50Z")

</div>

we could also abuse placement new: `root_path <- "usr" <- "local" <- "bin" <- "something"`

---

<div class="post-metadata">

**Author:** ![llogiq](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/llogiq/32/13692_2.png) [@llogiq](https://internals.rust-lang.org/u/llogiq)\
**Post date:** [August 1, 2015, 9:38am UTC](https://internals.rust-lang.org/t/pre-pre-rfc-for-paths/2420/10 "2015-08-01T09:38:49Z")

</div>

Misusing placement new is an advanced kind of evil, which we should forgo if a more primitive evil (misusing Div) suffices.

Also I have yet to see a filesystem where `<-` denotes the path separator, whereas `/` is common on Unices and Windows’ `\` (which is already used for both string escapes and line continuation) looks similar enough. Also both Python and Java accept `/` instead of `\` even on Windows.

---

<div class="post-metadata">

**Author:** ![killercup](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/killercup/32/3256_2.png) [@killercup](https://internals.rust-lang.org/u/killercup)\
**Post date:** [August 1, 2015, 9:48am UTC](https://internals.rust-lang.org/t/pre-pre-rfc-for-paths/2420/11 "2015-08-01T09:48:55Z")

</div>

> [@Toby](#):
>
> What makes this different to not overloading + for Strings

I would expect every addition operation to be commutative, i.e. `"asd" + "fgh"` should be equivalent to `"fgh" + "asd"`. This obviously doesn't work for strings and lists (but does for sets).

I'm not saying that this must hold for programming languages, but it might be nice. (Division for paths works surprisingly well from a mathematical standpoint.)

---

<div class="post-metadata">

**Author:** ![DanielKeep](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/danielkeep/32/1332_2.png) [@DanielKeep](https://internals.rust-lang.org/u/DanielKeep)\
**Post date:** [August 1, 2015, 10:27am UTC](https://internals.rust-lang.org/t/pre-pre-rfc-for-paths/2420/12 "2015-08-01T10:27:26Z")

</div>

This is cute, but I think having operators do what they say is more important. I _like_ the idea, but don’t think it’s appropriate for Rust.

Honestly, if I need to concat a bunch of paths, I just write a variadic macro to do it. Not _quite_ as succinct, but plenty workable.

---

<div class="post-metadata">

**Author:** ![llogiq](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/llogiq/32/13692_2.png) [@llogiq](https://internals.rust-lang.org/u/llogiq)\
**Post date:** [August 1, 2015, 10:29am UTC](https://internals.rust-lang.org/t/pre-pre-rfc-for-paths/2420/13 "2015-08-01T10:29:33Z")

</div>

In my opinion, the real difference is that we see a lot more code that mixes string handling and arithmetic, whereas this is much less common with path handling – e.g. how often do you see code like `prefix + (x + y).to_string() + suffix` vs. code like `prepath` / &(a / b ).to\_string() / sufpath`?

---

<div class="post-metadata">

**Author:** ![Toby](https://avatars.discourse-cdn.com/v4/letter/t/7993a0/32.png) [@Toby](https://internals.rust-lang.org/u/Toby)\
**Post date:** [August 1, 2015, 10:39am UTC](https://internals.rust-lang.org/t/pre-pre-rfc-for-paths/2420/14 "2015-08-01T10:39:10Z")

</div>

> [@llogiq](#):
>
> even on Windows

The Windows API itself [accepts `/` as a separator](https://msdn.microsoft.com/en-us/library/aa365247%28VS.85%29.aspx#maxpath) for non-UNC paths.

> [@killercup](#):
>
> I would expect every addition operation to be commutative, i.e. "asd" + "fgh" should be equivalent to "fgh" + "asd". This obviously doesn't work for strings and lists (but does for sets).

That is quite nice, but I think this would require `RHS = Self`? Given that `Add` can be implemented otherwise, I'm not sure this is the best guideline (and isn't backwards-compatible, because there's a stable `Add<&str> for String` implementation).

---

<div class="post-metadata">

**Author:** ![llogiq](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/llogiq/32/13692_2.png) [@llogiq](https://internals.rust-lang.org/u/llogiq)\
**Post date:** [August 1, 2015, 4:51pm UTC](https://internals.rust-lang.org/t/pre-pre-rfc-for-paths/2420/15 "2015-08-01T16:51:04Z")

</div>

No, it would only require that RHS also implements Add with an RHS that matches our Self _and_ returns the same result.

---

<div class="post-metadata">

**Author:** ![notriddle](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/notriddle/32/14082_2.png) [@notriddle](https://internals.rust-lang.org/u/notriddle)\
**Post date:** [August 1, 2015, 10:47pm UTC](https://internals.rust-lang.org/t/pre-pre-rfc-for-paths/2420/16 "2015-08-01T22:47:30Z")

</div>

If there’s already stable str + str, path / path doesn’t seem like a big stretch.

---

<div class="post-metadata">

**Author:** ![llogiq](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/llogiq/32/13692_2.png) [@llogiq](https://internals.rust-lang.org/u/llogiq)\
**Post date:** [August 1, 2015, 11:55pm UTC](https://internals.rust-lang.org/t/pre-pre-rfc-for-paths/2420/17 "2015-08-01T23:55:17Z")

</div>

I’ve just tried to naïvely implement this in a crate, but run against the orphan rule. So to build this, I’d need to wrap `std::path::Path` in a struct `ext::path::Path` (that has much of the same interface, but also implements `Div`).

Also `PathBuf`. Even then, it wouldn’t be compatible with `std::path::Path`. So this exercise would be rather futile.

---

<div class="post-metadata">

**Author:** ![Gankra](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/gankra/32/6002_2.png) [@Gankra](https://internals.rust-lang.org/u/Gankra)\
**Post date:** [August 2, 2015, 5:31pm UTC](https://internals.rust-lang.org/t/pre-pre-rfc-for-paths/2420/18 "2015-08-02T17:31:06Z")

</div>

This seems a bit too magical to me. Maybe I’m just a kermudgeon, though.

---

<div class="post-metadata">

**Author:** ![llogiq](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/llogiq/32/13692_2.png) [@llogiq](https://internals.rust-lang.org/u/llogiq)\
**Post date:** [August 2, 2015, 10:12pm UTC](https://internals.rust-lang.org/t/pre-pre-rfc-for-paths/2420/19 "2015-08-02T22:12:47Z")

</div>

Magical? Given that we have `+` for `String`, `/` for `Path` is positively pedestrian.

If it comes to RFC, I’ll note that pythoneers and people who used Boost will feel right at home, while others may think “Neat” and move on.

One drawback is that it _might_ mislead people to try and be clever with operator overloading.

---

<div class="post-metadata">

**Author:** ![Florob](https://avatars.discourse-cdn.com/v4/letter/f/96bed5/32.png) [@Florob](https://internals.rust-lang.org/u/Florob)\
**Post date:** [August 2, 2015, 10:37pm UTC](https://internals.rust-lang.org/t/pre-pre-rfc-for-paths/2420/20 "2015-08-02T22:37:08Z")

</div>

Personally I’m very hesitant when it comes to overloading operators for anything, but their original purpose. I particularly dislike abusing operator overloading to build mini DSLs, which I’d argue this is a case of.

Furthermore, if we are doing such overloading, I find it hard to argue for having different operators to append data, depending on the type. I can sort of get on board with “Adding/appending a string to another one”, and the operator being `+` (i.e. addition). However, why is “Adding/appending a path to another one” represented by a different operator `/` (i.e. division) instead? The answer is obviously that this looks familiar, but from a completely different context than Rust programming.

I’d prefer if we encapsulated such DSLs within macros, e.g.:

```
// Usage: path_join!(a/b/c)
macro_rules! path_join {
    ( $first:ident / $( $path:ident )/ * ) => {
        {
            let mut tmp: PathBuf = $first.into();
            $(
                tmp = tmp.join($path);
            )*
            tmp
        }
    }
}

```

I fully admit that this only works for the simplest cases though.

[Next page](https://internals.rust-lang.org/t/pre-pre-rfc-for-paths/2420.md?page=2)
