# How not to concatenate in hvcat

**URL:** https://discourse.julialang.org/t/how-not-to-concatenate-in-hvcat/104146
**Category:** General Usage
**Tags:** question
**Created:** [September 22, 2023, 11:23am UTC](https://discourse.julialang.org/t/how-not-to-concatenate-in-hvcat/104146 "2023-09-22T11:23:15Z")
**Posts on this page:** 8
**Page:** 1

<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: [September 22, 2023, 11:23am UTC](https://discourse.julialang.org/t/how-not-to-concatenate-in-hvcat/104146/1 "2023-09-22T11:23:15Z")

</div>

Is there a way one can use the `[...; ...]` syntax which lowers to `hvcat` **without** concatenating the arguments? Ie as a plain vanilla matrix constructor.

Eg

```julia
julia> [[1] [2];
       [3] [4]]
2×2 Matrix{Int64}:
 1 2
 3 4

```

concatenates, I want something equivalent to

```julia
julia> reshape([[1], [3], [2], [4]], :, 2)
2×2 Matrix{Vector{Int64}}:
 [1] [2]
 [3] [4]

```

This works:

```julia
julia> [[[1]] [[2]];
       [[3]] [[4]]]
2×2 Matrix{Vector{Int64}}:
 [1] [2]
 [3] [4]

```

but, aargh.

---

<div class="post-metadata">

### Author: ![BioTurboNick](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/bioturbonick/32/6380_2.png) [@BioTurboNick](https://discourse.julialang.org/u/BioTurboNick)
#### Post date: [September 22, 2023, 1:19pm UTC](https://discourse.julialang.org/t/how-not-to-concatenate-in-hvcat/104146/2 "2023-09-22T13:19:08Z")

</div>

No, the lowering functions all copy elementwise from `AbstractArray` inputs.

---

<div class="post-metadata">

### Author: ![digital\_carver](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/digital_carver/32/33818_2.png) [@digital\_carver](https://discourse.julialang.org/u/digital_carver)
#### Post date: [September 28, 2023, 7:36pm UTC](https://discourse.julialang.org/t/how-not-to-concatenate-in-hvcat/104146/4 "2023-09-28T19:36:43Z")

</div>

```julia-repl
julia> vcat.([1 3; 2 4])
2×2 Matrix{Vector{Int64}}:
 [1] [3]
 [2] [4]

```

Downside is that it isn’t visually as obvious as `[[1] [2]; [3] [4]]` would be (if it worked), so probably needs a comment alongside it to explain what it’s doing.

---

<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: [September 29, 2023, 10:17am UTC](https://discourse.julialang.org/t/how-not-to-concatenate-in-hvcat/104146/5 "2023-09-29T10:17:21Z")

</div>

I think you misunderstood the question; the point is not create the matrix in the MWE, but to construct a matrix using the `[;]` syntax without concatenation, eg generally

```julia
[a b; c d]

```

where `a::Union{AbstractVector,AbstractMatrix}` etc.

The simplest solution may be a wrapper type, eg along the lines of

```julia
"""
A wrapper type that should be used on the element of a `hvcat` (`[...; ...]`) call to
prevent concatenation of the arguments.
"""
struct NoCat{T}
    x::T
end

function Base.hvcat(rows::Tuple{Vararg{Int}}, x1::NoCat, xR...)
    nrow = length(rows)
    ncol = rows[1]
    @assert allequal(rows)
    xs = promote(x1.x, xR...)
    T = typeof(xs[1])
    m = Matrix{T}(undef, nrow, ncol)
    j = 1
    for row in 1:nrow
        for col in 1:ncol
            m[row, col] = xs[j]
            j += 1
        end
    end
    m
end

```

which works like

```julia
julia> [NoCat([1]) [2];
       [3] [4]]
2×2 Matrix{Vector{Int64}}:
 [1] [2]
 [3] [4]

```

---

<div class="post-metadata">

### Author: ![jling](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/jling/32/212909_2.png) [@jling](https://discourse.julialang.org/u/jling)
#### Post date: [September 29, 2023, 10:21am UTC](https://discourse.julialang.org/t/how-not-to-concatenate-in-hvcat/104146/6 "2023-09-29T10:21:42Z")

</div>

hm, unfortunately I think the current behavior is highly consistent:

```julia
julia> [1 2]
1×2 Matrix{Int64}:
 1 2

julia> [[1] [2]]
1×2 Matrix{Int64}:
 1 2

julia> [1, 2]
2-element Vector{Int64}:
 1
 2

julia> [[1]; [2]]
2-element Vector{Int64}:
 1
 2

```

---

<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: [September 29, 2023, 10:28am UTC](https://discourse.julialang.org/t/how-not-to-concatenate-in-hvcat/104146/7 "2023-09-29T10:28:47Z")

</div>

> [@jling](#):
>
> the current behavior is highly consistent

I agree with this, but I was just looking for a syntax that makes a matrix using the same visual arrangement without concatenating the elements. Julia does not have (built-in) syntax for a matrix constructor that does nothing else (cf the `[]` syntax for vectors). Fortunately it can easily be added.

---

<div class="post-metadata">

### Author: ![Mason](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/mason/32/2423_2.png) [@Mason](https://discourse.julialang.org/u/Mason)
#### Post date: [September 29, 2023, 12:06pm UTC](https://discourse.julialang.org/t/how-not-to-concatenate-in-hvcat/104146/8 "2023-09-29T12:06:41Z")

</div>

> [@Tamas\_Papp](#):
>
> The simplest solution may be a wrapper type, eg along the lines of

I think it’d be a bit cleaner to instead abuse `typed_hvcat` like what StaticArrays.jl does:

```julia
struct var"typeof(NoCat)" end
const NoCat = var"typeof(NoCat)"()
Base.show(io::IO, ::var"typeof(NoCat)") = print(io, "NoCat")

function Base.typed_hvcat(::var"typeof(NoCat)", rows::Tuple{Vararg{Int}}, _xs...)
    nrow = length(rows)
    ncol = rows[1]
    @assert allequal(rows)
    xs = promote(_xs...)
    T = typeof(xs[1])
    m = Matrix{T}(undef, nrow, ncol)
    j = 1
    for row in 1:nrow
        for col in 1:ncol
            m[row, col] = xs[j]
            j += 1
        end
    end
    m
end

```

and then

```julia-repl
julia> NoCat[[1] [2]
             [3] [4]]
2×2 Matrix{Vector{Int64}}:
 [1] [2]
 [3] [4]

```

---

<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: [September 29, 2023, 12:23pm UTC](https://discourse.julialang.org/t/how-not-to-concatenate-in-hvcat/104146/9 "2023-09-29T12:23:22Z")

</div>

> [@Mason](#):
>
> it’d be a bit cleaner to instead abuse `typed_hvcat`

I absolutely agree, but AFAICT it is not part of the exposed API. Perhaps that should be fixed — ~~I could not find an open issue~~ I opened an issue:

> <https://github.com/JuliaLang/julia/issues/51509>
>
> While \`Base.hvcat\` is part of the API, \`Base.typed\_hvcat\` apparently isn't, and …while the manual \[does not mention\](https://docs.julialang.org/en/v1/manual/arrays/#man-array-typed-literal) what \`T\[...; ...\]\` is lowered to.
> 
> I propose the following:
> 
> 1. add a docstring to \`typed\_hvcat\`, explain what is lowered to it, and make it part of the docs (potentially by not exporting it, \`public\` should be enough),
> 2. mention the lowering in the docs section linked above.
> 
> I will wait for comments and then make a PR.
