# Introduce ++ as the concatenation operator

**URL:** <https://discourse.julialang.org/t/introduce-as-the-concatenation-operator/37418>\
**Category:** Internals & Design\
**Created:** [April 11, 2020, 9:09pm UTC](https://discourse.julialang.org/t/introduce-as-the-concatenation-operator/37418 "2020-04-11T21:09:28Z")\
**Posts on this page:** 20\
**Page:** 1

<div class="post-metadata">

**Author:** ![CameronBieganek](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/cameronbieganek/32/6915_2.png) [@CameronBieganek](https://discourse.julialang.org/u/CameronBieganek)\
**Post date:** [April 11, 2020, 9:09pm UTC](https://discourse.julialang.org/t/introduce-as-the-concatenation-operator/37418/1 "2020-04-11T21:09:29Z")

</div>

It seems like it would be handy to have `++` as a generic concatenation operator. There are a few languages that use `++` for this, e.g. [Erlang](https://rosettacode.org/wiki/Array_concatenation#Erlang), [Haskell](https://rosettacode.org/wiki/Array_concatenation#Haskell), and [Elm](https://package.elm-lang.org/packages/elm/core/latest/Basics#++). For arrays, `++` would be sugar for `vcat` (`hcat` is another story). Here’s an example of the current syntax pulled from a unit test in MLJBase.jl:

```julia
N = 2
v = vcat(fill(:a, N), fill(:b, 2N), fill(:c, 3N), fill(:d, 4N))

```

Of course, Julia already has syntax sugar for `vcat`, but in this case the sugar is not very sweet:

```julia
v = [fill(:a, N); fill(:b, 2N); fill(:c, 3N); fill(:d, 4N)]

```

Compare this to the proposed `++` operator:

```julia
v = fill(:a, N) ++ fill(:b, 2N) ++ fill(:c, 3N) ++ fill(:d, 4N)

```

I find the `++` operator to be more readable.

And of course `++` could be used for string concatenation:

```julia
s = "hello " ++ "world"

```

I don’t think I’m alone in finding `*` to be unintuitive for string concatenation. And it seems to me like concatenation is mostly a separate concept from arithmetic, so it would be better not to overload arithmetic operators to perform concatenation.

---

<div class="post-metadata">

**Author:** ![tlienart](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/tlienart/32/7640_2.png) [@tlienart](https://discourse.julialang.org/u/tlienart)\
**Post date:** [April 11, 2020, 9:18pm UTC](https://discourse.julialang.org/t/introduce-as-the-concatenation-operator/37418/2 "2020-04-11T21:18:20Z")

</div>

Btw you can already do this:

```julia
julia> (++)(x::AbstractVector, y::AbstractVector) = vcat(x, y)
julia> rand(5) ++ rand(7)
julia> (++)(x::AbstractString,y::AbstractString) = x*y
julia> "hello" ++ "goodbye"

```

whether that’s recommended is another story, but I guess you could just use that in your pkg.

With a bit of polishing for dealing with missings, nothing etc it could even make for a simple little package PlusPlus.jl 😂

~~PS: hold my beer… incoming~~

---

<div class="post-metadata">

**Author:** ![CameronBieganek](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/cameronbieganek/32/6915_2.png) [@CameronBieganek](https://discourse.julialang.org/u/CameronBieganek)\
**Post date:** [April 11, 2020, 9:29pm UTC](https://discourse.julialang.org/t/introduce-as-the-concatenation-operator/37418/3 "2020-04-11T21:29:46Z")

</div>

> [@tlienart](#):
>
> Btw you can already do this:

Yeah, I agree it can be done, but I’d rather not introduce non-standard syntax into my code for a basic operation like concatenation. 🙂

> [@tlienart](#):
>
> With a bit of polishing for dealing with missings, nothing etc it could even make for a simple little package PlusPlus.jl 😂

Are you referring to [PlusPlus.jl](https://github.com/pkofod/PlusPlus.jl)?

---

<div class="post-metadata">

**Author:** ![tlienart](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/tlienart/32/7640_2.png) [@tlienart](https://discourse.julialang.org/u/tlienart)\
**Post date:** [April 11, 2020, 9:32pm UTC](https://discourse.julialang.org/t/introduce-as-the-concatenation-operator/37418/4 "2020-04-11T21:32:18Z")

</div>

aaah indeed, ok well I guess I can shelve [https://github.com/tlienart/PlusPlus.jl](https://github.com/tlienart/PlusPlus.jl) 🍺

---

<div class="post-metadata">

**Author:** ![tbeason](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/tbeason/32/15898_2.png) [@tbeason](https://discourse.julialang.org/u/tbeason)\
**Post date:** [April 11, 2020, 9:35pm UTC](https://discourse.julialang.org/t/introduce-as-the-concatenation-operator/37418/5 "2020-04-11T21:35:29Z")

</div>

“But making Julia packages is hard!”

---

<div class="post-metadata">

**Author:** ![CameronBieganek](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/cameronbieganek/32/6915_2.png) [@CameronBieganek](https://discourse.julialang.org/u/CameronBieganek)\
**Post date:** [April 11, 2020, 9:37pm UTC](https://discourse.julialang.org/t/introduce-as-the-concatenation-operator/37418/6 "2020-04-11T21:37:04Z")

</div>

> [@tlienart](#):
>
> aaah indeed, ok well I guess I can shelve [https://github.com/tlienart/PlusPlus.jl](https://github.com/tlienart/PlusPlus.jl) 🍺

Well, it looks like [GitHub - pkofod/PlusPlus.jl](https://github.com/pkofod/PlusPlus.jl) is not exactly maintained, and it’s not in the general registry, so I think the path is clear for you!

It’s probably appropriate for `x ++ nothing` and `x ++ missing` to throw method errors, so I’m not sure if you need special handling for `missing` and `nothing`…

---

<div class="post-metadata">

**Author:** ![tlienart](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/tlienart/32/7640_2.png) [@tlienart](https://discourse.julialang.org/u/tlienart)\
**Post date:** [April 11, 2020, 9:41pm UTC](https://discourse.julialang.org/t/introduce-as-the-concatenation-operator/37418/7 "2020-04-11T21:41:05Z")

</div>

Haha I put it together more for fun than anything but I guess if someone finds that useful I’m happy to think about it a bit harder and register it 🤷‍♂️, not really sure it’s worth it at the moment

---

<div class="post-metadata">

**Author:** ![DNF](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/dnf/32/10191_2.png) [@DNF](https://discourse.julialang.org/u/DNF)\
**Post date:** [April 11, 2020, 9:43pm UTC](https://discourse.julialang.org/t/introduce-as-the-concatenation-operator/37418/8 "2020-04-11T21:43:00Z")

</div>

> [@CameronBieganek](#):
>
> not exactly maintained

What would that mean in this context? Is there anything to maintain?

---

<div class="post-metadata">

**Author:** ![CameronBieganek](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/cameronbieganek/32/6915_2.png) [@CameronBieganek](https://discourse.julialang.org/u/CameronBieganek)\
**Post date:** [April 11, 2020, 9:53pm UTC](https://discourse.julialang.org/t/introduce-as-the-concatenation-operator/37418/9 "2020-04-11T21:53:14Z")

</div>

> [@DNF](#):
>
> What would that mean in this context? Is there anything to maintain?

Ha, yeah there’s not much to maintain. But the string concatenation method probably needs to be updated from this:

```julia
++(a::AbstractString, b::AbstractString) = a*b

```

to this:

```julia
++(s1::Union{AbstractChar, AbstractString}, ss::Union{AbstractChar, AbstractString}...) = *(s1, ss...)

```

to align with the definition in base Julia, and because `++` is currently parsed as an n-ary operator:

```julia
julia> ex = :(x ++ y ++ z)
:(x ++ y ++ z)

julia> dump(ex)
Expr
  head: Symbol call
  args: Array{Any}((4,))
    1: Symbol ++
    2: Symbol x
    3: Symbol y
    4: Symbol z

```

EDIT:  
In this context I guess by “maintained” I meant updated to use a Project.toml file and added to the general registry.

---

<div class="post-metadata">

**Author:** ![anon67531922](https://avatars.discourse-cdn.com/v4/letter/a/48db29/32.png) [@anon67531922](https://discourse.julialang.org/u/anon67531922)\
**Post date:** [April 12, 2020, 2:07am UTC](https://discourse.julialang.org/t/introduce-as-the-concatenation-operator/37418/10 "2020-04-12T02:07:26Z")

</div>

> [@CameronBieganek](#):
>
> but I’d rather not introduce non-standard syntax into my code for a basic operation like concatenation. 🙂

Why not? I say go for it if you like that syntax 🙂

One of the beautiful things about Julia is that you can do things like this with no loss in performance.

---

<div class="post-metadata">

**Author:** ![tkf](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/tkf/32/17635_2.png) [@tkf](https://discourse.julialang.org/u/tkf)\
**Post date:** [April 12, 2020, 5:54am UTC](https://discourse.julialang.org/t/introduce-as-the-concatenation-operator/37418/11 "2020-04-12T05:54:00Z")

</div>

I think one problem with using `++` for concatenation is that it is not immediately clear what operator you can use for what `^(::String, ::Integer)` does. In this sense, I think even `+` is a bit better than `++` as you can guess `*(::Integer, ::String)` might work.

Of course, we can’t use `*` to concatenate vectors. So, I often wonder if it makes sense to be able to define “local algebra”; e.g.,

```julia
@withalgebra * = vcat begin
    [:a]^N * [:b]^$(2N) * [:c]^$(3N) * [:d]^$(4N)
end

```

is lowered to something equivalent to

```julia
let *′ = *, * = vcat, ^ = repeat
    [:a]^N * [:b]^(2 *′ N) * [:c]^(3 *′ N) * [:d]^(4 *′ N)
end

```

and

```julia
@withalgebra * = ∘ begin
    first * tail^3
end

```

is lowered to

```julia
let * = ∘, ^ = power_by_squaring_with(*) # to be defined
    first * tail^3
end

```

> [@CameronBieganek](#):
>
> `++` is currently parsed as an n-ary operator

I find it interesting. It is one of the three operators [special-cased by the parser](https://github.com/JuliaLang/julia/blob/02624ac0e74a43ef014e96f21887de7052eb3e9c/src/julia-parser.scm#L906-L907). Other operators like `∘` are parsed as binary operator. So, in this sense, I guess using `++ = vcat` kind of makes sense (i.e., `vcat(vcat(a, b), c)` requires a temporary array but `vcat(a, b, c)` doesn’t).

---

<div class="post-metadata">

**Author:** ![Tamas\_Papp](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/tamas_papp/32/25949_2.png) [@Tamas\_Papp](https://discourse.julialang.org/u/Tamas_Papp)\
**Post date:** [April 12, 2020, 6:26am UTC](https://discourse.julialang.org/t/introduce-as-the-concatenation-operator/37418/12 "2020-04-12T06:26:55Z")

</div>

> [@CameronBieganek](#):
>
> It seems like it would be handy to have `++` as a generic concatenation operator.

I think that a package is the best place for this. `++` is one of the three operators that [chains its arguments](https://github.com/JuliaLang/julia/blob/b773bebcdb1eccaf3efee0bfe564ad552c0bcea7/src/julia-parser.scm#L888) (the other two are `+` and `*`) so it is best to leave it undefined in `Base` if users need it for something custom.

Concatenation is a nice use case, but it is just _one_ of the possible nice use cases.

---

<div class="post-metadata">

**Author:** ![CameronBieganek](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/cameronbieganek/32/6915_2.png) [@CameronBieganek](https://discourse.julialang.org/u/CameronBieganek)\
**Post date:** [April 12, 2020, 6:12pm UTC](https://discourse.julialang.org/t/introduce-as-the-concatenation-operator/37418/13 "2020-04-12T18:12:02Z")

</div>

> [@tkf](#):
>
> I think one problem with using `++` for concatenation is that it is not immediately clear what operator you can use for what `^(::String, ::Integer)` does.

Yeah, that thought crossed my mind, but we would still have `repeat("ab", 3)`. That’s more verbose than `"ab" ^ 3`, but I think string concatenation is much more common than string repetition.

The local algebra macro is a neat idea.

---

<div class="post-metadata">

**Author:** ![stevengj](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/stevengj/32/71_2.png) [@stevengj](https://discourse.julialang.org/u/stevengj)\
**Post date:** [April 12, 2020, 6:17pm UTC](https://discourse.julialang.org/t/introduce-as-the-concatenation-operator/37418/14 "2020-04-12T18:17:14Z")

</div>

> [@CameronBieganek](#):
>
> It seems like it would be handy to have `++` as a generic concatenation operator.

For extensive previous discussion on this topic, and why we opted not to do this yet in `Base`, see  
[#11030](https://github.com/JuliaLang/julia/issues/11030) and [#22461](https://github.com/JuliaLang/julia/pull/22461). My personal conclusion after actually trying to implement this in `Base` can be read [here](https://github.com/JuliaLang/julia/pull/22461#issuecomment-310427474).

---

<div class="post-metadata">

**Author:** ![cstjean](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/cstjean/32/1444_2.png) [@cstjean](https://discourse.julialang.org/u/cstjean)\
**Post date:** [April 12, 2020, 6:44pm UTC](https://discourse.julialang.org/t/introduce-as-the-concatenation-operator/37418/15 "2020-04-12T18:44:22Z")

</div>

I’d be happy with just a generic `concat(args...)`, if only so that I don’t have to remember how to concatenate tuples. Most code is not performance sensitive.

---

<div class="post-metadata">

**Author:** ![CameronBieganek](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/cameronbieganek/32/6915_2.png) [@CameronBieganek](https://discourse.julialang.org/u/CameronBieganek)\
**Post date:** [April 12, 2020, 6:57pm UTC](https://discourse.julialang.org/t/introduce-as-the-concatenation-operator/37418/16 "2020-04-12T18:57:10Z")

</div>

> [@stevengj](#):
>
> For extensive previous discussion on this topic, and why we opted not to do this yet in `Base` , see  
> [#11030](https://github.com/JuliaLang/julia/issues/11030) and [#22461](https://github.com/JuliaLang/julia/pull/22461). My personal conclusion after actually trying to implement this in `Base` can be read [here](https://github.com/JuliaLang/julia/pull/22461#issuecomment-310427474).

Thanks for the links!

---

<div class="post-metadata">

**Author:** ![purplishrock](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/purplishrock/32/13451_2.png) [@purplishrock](https://discourse.julialang.org/u/purplishrock)\
**Post date:** [April 13, 2020, 12:49am UTC](https://discourse.julialang.org/t/introduce-as-the-concatenation-operator/37418/17 "2020-04-13T00:49:30Z")

</div>

it’s a terrific example for those of us who are not exactly sure how the whole Julia package thing works.

---

<div class="post-metadata">

**Author:** ![lesshaste](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/lesshaste/32/12302_2.png) [@lesshaste](https://discourse.julialang.org/u/lesshaste)\
**Post date:** [April 13, 2020, 3:34pm UTC](https://discourse.julialang.org/t/introduce-as-the-concatenation-operator/37418/18 "2020-04-13T15:34:56Z")

</div>

I realise this has been discussed before but I think most new people who come to Julia are really surprised (and probably put off) when they discover that \* is string concatenation. It would be a shame if Julia is now stuck with this highly idiosyncratic syntax. Anyone who has ever used another programming language will expect string concatenation to be + or ++. If we want to become more mainstream, this is the sort of oddity that should be removed IMHO. We can make it more Julia-like by writing ++ as ⧺ (as in [Unicode Character 'DOUBLE PLUS' (U+29FA)](https://www.fileformat.info/info/unicode/char/29fa/index.htm) ).

---

<div class="post-metadata">

**Author:** ![tlienart](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/tlienart/32/7640_2.png) [@tlienart](https://discourse.julialang.org/u/tlienart)\
**Post date:** [April 13, 2020, 3:45pm UTC](https://discourse.julialang.org/t/introduce-as-the-concatenation-operator/37418/19 "2020-04-13T15:45:17Z")

</div>

Did you have a look at the link that Steven posted earlier? it’s a good summary: [RFC: deprecate \* in favor of new ++ concatenation operator by stevengj · Pull Request #22461 · JuliaLang/julia · GitHub](https://github.com/JuliaLang/julia/pull/22461#issuecomment-310427474)

---

<div class="post-metadata">

**Author:** ![lesshaste](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/lesshaste/32/12302_2.png) [@lesshaste](https://discourse.julialang.org/u/lesshaste)\
**Post date:** [April 13, 2020, 3:59pm UTC](https://discourse.julialang.org/t/introduce-as-the-concatenation-operator/37418/20 "2020-04-13T15:59:38Z")

</div>

Yes I have, thank you. I think there are two views. One from the inside (those who are julia developers) and one from the outside (users and in particular new users of the language). I was trying to give the view from the outside. Everyone I have ever spoken to who had not yet written a line of Julia (but has written code in other languages) thinks it bizarre/hilarious that string concatenation is \*. A slightly awkward compromise might be if the plusplus package was registered and easily installable. New users could all just be told to include that package at the top of their code. It seems a shame though.

[Next page](https://discourse.julialang.org/t/introduce-as-the-concatenation-operator/37418.md?page=2)
