# Implement Add for String + String

**URL:** <https://internals.rust-lang.org/t/implement-add-for-string-string/4088>\
**Category:** libs\
**Created:** [September 16, 2016, 10:29am UTC](https://internals.rust-lang.org/t/implement-add-for-string-string/4088 "2016-09-16T10:29:40Z")\
**Posts on this page:** 20\
**Page:** 1

<div class="post-metadata">

**Author:** ![iopq](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/iopq/32/78_2.png) [@iopq](https://internals.rust-lang.org/u/iopq)\
**Post date:** [September 16, 2016, 10:29am UTC](https://internals.rust-lang.org/t/implement-add-for-string-string/4088/1 "2016-09-16T10:29:40Z")

</div>

I know some people don’t like the fact that `+` is overloaded for concatenation. But since `String + &str` is already implemented, I think that ship has sailed. It is no longer possible to take this out and add another concatenation operator.

I propose that `Add` be implemented for the `String + String` case as well. It might not be a big deal in most cases like `a + &b` - this is not too much extra typing. Where it’s more annoying is in cases like `.fold1(String::add)` with fold1 from itertools which doesn’t work. Here typing `.fold1(|x, y| x + &y)` is a lot longer and more complicated. I went ahead and just did this:

```rust
pub trait Concatenable {
    fn concat(self, other: Self) -> Self;
}

impl Concatenable for String {
    fn concat(mut self, other: String) -> String {
        self.push_str(&*other);
        self
    }
}

```

so I could do `.fold1(String::concat)` whenever I want to. This is much more readable, it has three parts, one of which is a path separator. On the other hand, the closure has 9 separate elements that I have to read, so I have to slow down and check that it does what I think it does.

I think there is no downside to actually doing this and the implementation is pretty trivial. Are there any arguments against it?

---

<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:** [September 16, 2016, 10:42am UTC](https://internals.rust-lang.org/t/implement-add-for-string-string/4088/2 "2016-09-16T10:42:53Z")

</div>

Just because someone made a mistake once doesn’t mean it’s OK to further compound it.

If you want concatenation, argue for concatenation. Don’t misappropriate an operator to mean something different. That’s how you end up with `iostreams`, and I hope _no one_ wants Rust to end up looking like that. Next you’ll be wanting to use `a-b` for `a.replace(b, "")` and `%` for `&a[a.len()-b..]`. Do you see how slippery this slope is? Even crazy people with mountain climbing gear wouldn’t go near it.

Having an _actual concatenation operator_ opens the door to _also_ concatenating `Vec`s and arrays and iterators and tuples and probably other things, too. It could be used in pattern matching.

I am, have been, and always shall be vehemently against misusing `+` for concatenation.

---

<div class="post-metadata">

**Author:** ![iopq](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/iopq/32/78_2.png) [@iopq](https://internals.rust-lang.org/u/iopq)\
**Post date:** [September 16, 2016, 10:44am UTC](https://internals.rust-lang.org/t/implement-add-for-string-string/4088/3 "2016-09-16T10:44:46Z")

</div>

Too late, it’s already in the language. Can’t take it out anymore, just make it have better ergonomics. I don’t get the slippery slope argument, I just want something that’s already in stable Rust, but I want it to apply to an additional type.

---

<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:** [September 16, 2016, 10:56am UTC](https://internals.rust-lang.org/t/implement-add-for-string-string/4088/4 "2016-09-16T10:56:50Z")

</div>

> [@iopq](#):
>
> Too late, it's already in the language. Can't take it out anymore, ...

We _can't_ take it out, but that is in _no way_ an argument for expanding it to more types.

> [@iopq](#):
>
> I don't get the slippery slope argument, ...

It's called "being self-aware that the point being argued is not nearly important enough to warrant one's emotional reaction by highlighting how it is unlikely to extend beyond the specific case being discussed."

See also: sarcasm.

> [@iopq](#):
>
> ... I just want something that's already in stable Rust, but I want it to apply to an additional type.

_I_ don't want to give people any more reasons to use `+` on strings, irrespective of context. I _want_ it to be painful to use so we're more likely to get a fundamentally better replacement. 🙂

---

<div class="post-metadata">

**Author:** ![leonardo](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/leonardo/32/1344_2.png) [@leonardo](https://internals.rust-lang.org/u/leonardo)\
**Post date:** [September 16, 2016, 11:03am UTC](https://internals.rust-lang.org/t/implement-add-for-string-string/4088/5 "2016-09-16T11:03:34Z")

</div>

> [@DanielKeep](#):
>
> I want it to be painful to use so we're more likely to get a fundamentally better replacement.

I think the ~ of D language is better for a noncommutative operation, but given the design mistake of using + for String and &str, I think we have already lost the battle.

---

<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:** [September 16, 2016, 12:24pm UTC](https://internals.rust-lang.org/t/implement-add-for-string-string/4088/6 "2016-09-16T12:24:32Z")

</div>

we can easily add some code to deprecate trait impls and move forward with a proper concatenation strategy.

---

<div class="post-metadata">

**Author:** ![hanna-kruppe](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/hanna-kruppe/32/6540_2.png) [@hanna-kruppe](https://internals.rust-lang.org/u/hanna-kruppe)\
**Post date:** [September 16, 2016, 1:15pm UTC](https://internals.rust-lang.org/t/implement-add-for-string-string/4088/7 "2016-09-16T13:15:15Z")

</div>

Regardless of how it’s spelled (`+` or `~` or method call or …), I have some reservations about concatenating `String` with `String`. In programs of this form:

```rust
// concatenate s1 and s2
// keep using s2

```

… it is preferable to use `String + &str` and simply reuse `s2`, rather than creating an explicit `clone` of `s2` before concatenating. An overload for `String + String` makes it easier to unthinkingly do the pointless clone. Now, if one ever _needed_ to do `String + String` (e.g. for performance reasons), this downside would not be a blocker, but since it’s apparently just an ergonomics issues, it is a trade off.

---

<div class="post-metadata">

**Author:** ![stebalien](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/stebalien/32/228_2.png) [@stebalien](https://internals.rust-lang.org/u/stebalien)\
**Post date:** [September 16, 2016, 1:46pm UTC](https://internals.rust-lang.org/t/implement-add-for-string-string/4088/8 "2016-09-16T13:46:23Z")

</div>

Related: [https://github.com/rust-lang/rust/pull/36430](https://github.com/rust-lang/rust/pull/36430)

---

<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:** [September 16, 2016, 8:36pm UTC](https://internals.rust-lang.org/t/implement-add-for-string-string/4088/9 "2016-09-16T20:36:11Z")

</div>

Note that I didn’t suggest adding String to Cow yet (although that could be a logical next step). Perhaps more importantly, if we make Cow have better ergonomics than String, more people will use it?

---

<div class="post-metadata">

**Author:** ![stebalien](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/stebalien/32/228_2.png) [@stebalien](https://internals.rust-lang.org/u/stebalien)\
**Post date:** [September 16, 2016, 9:04pm UTC](https://internals.rust-lang.org/t/implement-add-for-string-string/4088/10 "2016-09-16T21:04:42Z")

</div>

I know. I’m just saying it’s related.

---

<div class="post-metadata">

**Author:** ![iopq](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/iopq/32/78_2.png) [@iopq](https://internals.rust-lang.org/u/iopq)\
**Post date:** [September 16, 2016, 10:03pm UTC](https://internals.rust-lang.org/t/implement-add-for-string-string/4088/11 "2016-09-16T22:03:31Z")

</div>

Is it possible to add a lint to this behavior saying you should do `s1 + &s2` if you want to keep using `s2`?

---

<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:** [September 16, 2016, 10:38pm UTC](https://internals.rust-lang.org/t/implement-add-for-string-string/4088/12 "2016-09-16T22:38:59Z")

</div>

Sure, but what for? You’d need to actively `.clone()` the second `String` anyway, or the best thing the lint would do is improve on the error reporting the borrow checker gives anyway.

---

<div class="post-metadata">

**Author:** ![iopq](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/iopq/32/78_2.png) [@iopq](https://internals.rust-lang.org/u/iopq)\
**Post date:** [September 16, 2016, 10:59pm UTC](https://internals.rust-lang.org/t/implement-add-for-string-string/4088/13 "2016-09-16T22:59:07Z")

</div>

It should warn if you’re `clone()`ing things that don’t need to be cloned. I’ve seen a lot of `clone()` abuse by beginning Rust programmers that can’t get their program to compile otherwise.

---

<div class="post-metadata">

**Author:** ![withoutboats](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/withoutboats/32/4560_2.png) [@withoutboats](https://internals.rust-lang.org/u/withoutboats)\
**Post date:** [September 16, 2016, 11:05pm UTC](https://internals.rust-lang.org/t/implement-add-for-string-string/4088/14 "2016-09-16T23:05:25Z")

</div>

This is not a great way to communicate! Your opinion is that the `+` operator shouldn’t be overloaded for the concatenation operation, but many people disagree. I recommend trying to express subjective ideas with a subjective tone - like “I think the concatenation add for String that already exists is a mistake, and I think adding this would further compound the problem that it presents.”

The choice to express yourself as if your position is inarguably objective may not seem like a big deal, but it’s the accumulation of small tone choices that push the community toward toxic acrimony.

---

<div class="post-metadata">

**Author:** ![withoutboats](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/withoutboats/32/4560_2.png) [@withoutboats](https://internals.rust-lang.org/u/withoutboats)\
**Post date:** [September 16, 2016, 11:08pm UTC](https://internals.rust-lang.org/t/implement-add-for-string-string/4088/15 "2016-09-16T23:08:22Z")

</div>

I _like_ concatenative add, but I also don’t like adding this impl for the reason @hanna-kruppe points out.

Exact messaging could be improved, but if you `String + String` right now, what the compiler can suggest is that you reference the second `String`. But if you add `String` and then use the second `String` again, getting use after move errors, there’s a non-trivial chance the user will solve the problem with `string + string.clone()` instead of `string + &string`.

---

<div class="post-metadata">

**Author:** ![zepto](https://avatars.discourse-cdn.com/v4/letter/z/5e9695/32.png) [@zepto](https://internals.rust-lang.org/u/zepto)\
**Post date:** [September 16, 2016, 11:14pm UTC](https://internals.rust-lang.org/t/implement-add-for-string-string/4088/16 "2016-09-16T23:14:34Z")

</div>

In Erlang, the append operator for “strings” is ++ not + and so is unambiguous and can be caught at compile time. Worth considering?

---

<div class="post-metadata">

**Author:** ![iopq](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/iopq/32/78_2.png) [@iopq](https://internals.rust-lang.org/u/iopq)\
**Post date:** [September 16, 2016, 11:16pm UTC](https://internals.rust-lang.org/t/implement-add-for-string-string/4088/17 "2016-09-16T23:16:18Z")

</div>

Only if the Rust team wants to deprecate the `Add` `impl` on `String + &str`

Edit: I can’t get spaces to work around the word on

Otherwise it’s pointless

---

<div class="post-metadata">

**Author:** ![zepto](https://avatars.discourse-cdn.com/v4/letter/z/5e9695/32.png) [@zepto](https://internals.rust-lang.org/u/zepto)\
**Post date:** [September 16, 2016, 11:32pm UTC](https://internals.rust-lang.org/t/implement-add-for-string-string/4088/18 "2016-09-16T23:32:03Z")

</div>

@iopq - pointless is a bit strong - what if it proves truly a worthwhile avenue to explore? I’d rather respond to a fault in the idea than some restriction in a current implementation.

---

<div class="post-metadata">

**Author:** ![EdorianDark](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/edoriandark/32/6868_2.png) [@EdorianDark](https://internals.rust-lang.org/u/EdorianDark)\
**Post date:** [September 17, 2016, 1:03pm UTC](https://internals.rust-lang.org/t/implement-add-for-string-string/4088/19 "2016-09-17T13:03:47Z")

</div>

I think Add should not be implemented for String. String + &str should be depricated.

---

<div class="post-metadata">

**Author:** ![nikomatsakis](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/nikomatsakis/32/5410_2.png) [@nikomatsakis](https://internals.rust-lang.org/u/nikomatsakis)\
**Post date:** [September 17, 2016, 2:28pm UTC](https://internals.rust-lang.org/t/implement-add-for-string-string/4088/20 "2016-09-17T14:28:14Z")

</div>

If the only point is to guide people away from doing a clone, perhaps we should consider using a lint for that purpose. i.e., I think we could detect common scenarios where people are cloning when a reference would have done.

[Next page](https://internals.rust-lang.org/t/implement-add-for-string-string/4088.md?page=2)
