# \`hcat\` with generator

**URL:** <https://discourse.julialang.org/t/hcat-with-generator/2300>\
**Category:** Internals & Design\
**Created:** [February 25, 2017, 3:37pm UTC](https://discourse.julialang.org/t/hcat-with-generator/2300 "2017-02-25T15:37:02Z")\
**Posts on this page:** 13\
**Page:** 1

<div class="post-metadata">

**Author:** ![cortner](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/cortner/32/204_2.png) [@cortner](https://discourse.julialang.org/u/cortner)\
**Post date:** [February 25, 2017, 3:37pm UTC](https://discourse.julialang.org/t/hcat-with-generator/2300/1 "2017-02-25T15:37:02Z")

</div>

I find myself wanting to write code of the kind

```julia
hcat(f(i) for i = 1:n)

```

where `f(i)` would be a function computing the `i`th column - or possibly multiple columns - of a matrix.  
but I end up getting something weird, `1×1 Array{Base.Generator{UnitRange{Int64},##3#4},2}: Base.Generator{UnitRange{Int64},##3#4}(#3,1:3)`

Is such construction feasible? wanted? Is there an alternative simple one-liner that one could use?

---

<div class="post-metadata">

**Author:** ![greg\_plowman](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/greg_plowman/32/8100_2.png) [@greg\_plowman](https://discourse.julialang.org/u/greg_plowman)\
**Post date:** [February 25, 2017, 3:52pm UTC](https://discourse.julialang.org/t/hcat-with-generator/2300/2 "2017-02-25T15:52:49Z")

</div>

Maybe you could use `collect`?

```julia
A = reshape(1:12, 3, 4)
f(A,i) = A[:,i]
hcat(collect(f(A,i) for i = 1:4)...)

```

---

<div class="post-metadata">

**Author:** ![cortner](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/cortner/32/204_2.png) [@cortner](https://discourse.julialang.org/u/cortner)\
**Post date:** [February 25, 2017, 3:59pm UTC](https://discourse.julialang.org/t/hcat-with-generator/2300/3 "2017-02-25T15:59:49Z")

</div>

clunky, but works. Thank you. (My question is still valid though I believe?)

---

<div class="post-metadata">

**Author:** ![dpsanders](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/dpsanders/32/3573_2.png) [@dpsanders](https://discourse.julialang.org/u/dpsanders)\
**Post date:** [February 25, 2017, 4:18pm UTC](https://discourse.julialang.org/t/hcat-with-generator/2300/4 "2017-02-25T16:18:52Z")

</div>

Or just use an array comprehension instead of a generator:

```julia
hcat([f(A,i) for i = 1:4]...)

```

---

<div class="post-metadata">

**Author:** ![cortner](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/cortner/32/204_2.png) [@cortner](https://discourse.julialang.org/u/cortner)\
**Post date:** [February 25, 2017, 4:31pm UTC](https://discourse.julialang.org/t/hcat-with-generator/2300/5 "2017-02-25T16:31:38Z")

</div>

That’s in fact how I ended up doing it. Still feels like one step too many.

---

<div class="post-metadata">

**Author:** ![PabloZubieta](https://avatars.discourse-cdn.com/v4/letter/p/ee7513/32.png) [@PabloZubieta](https://discourse.julialang.org/u/PabloZubieta)\
**Post date:** [February 25, 2017, 5:02pm UTC](https://discourse.julialang.org/t/hcat-with-generator/2300/6 "2017-02-25T17:02:52Z")

</div>

On 0.6 you could take advantage of dot fusion and do something along the following lines

```julia
f(r) = (1:3) .+ 3 .* (r' .- 1)
f(1:4)

```

On 0.5 you can do the same but won’t be as efficient (you would have to write another function so it doesn’t create unnecessary temporaries, except for the transposition)

```julia
g(i, j) = i + 3 * (j - 1)
f(r) = g.(1:3, r')
f(1:4)

```

---

<div class="post-metadata">

**Author:** ![Dan](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/dan/32/42581_2.png) [@Dan](https://discourse.julialang.org/u/Dan)\
**Post date:** [February 25, 2017, 10:46pm UTC](https://discourse.julialang.org/t/hcat-with-generator/2300/7 "2017-02-25T22:46:19Z")

</div>

By defining the following function:

```julia
function genmat(g)
  itr = start(g)
  done(g,itr) && error("generator must provide at least one column block")
  (v,itr) = next(g,itr)
  l = size(v,1)
  vlist = [vec(v)]
  while !done(g,itr)
    (v,itr) = next(g,itr)
    size(v,1) == l || error("all columns must be of same length")
    push!(vlist,vec(v))
  end
  m = vcat(vlist...)
  return reshape(m,l,length(m)÷l)
end

```

We can simply do:  
`genmat((f(A,i) for i=1:4))`  
but also:  
`genmat((f(A,i:i+1) for i=1:3))`  
and get an error whith an empty generator, etc. Might be worth the trouble.  
Regarding efficiency, it is hard to avoid some allocations without knowing in advance how many and in what shape the column blocks the generator will produce.

---

<div class="post-metadata">

**Author:** ![cortner](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/cortner/32/204_2.png) [@cortner](https://discourse.julialang.org/u/cortner)\
**Post date:** [February 25, 2017, 10:56pm UTC](https://discourse.julialang.org/t/hcat-with-generator/2300/8 "2017-02-25T22:56:16Z")

</div>

I like this, but could one not just rename your `genmat` to `vcat` ?`(CORR.: I meant`hcat`)

---

<div class="post-metadata">

**Author:** ![Dan](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/dan/32/42581_2.png) [@Dan](https://discourse.julialang.org/u/Dan)\
**Post date:** [February 25, 2017, 11:20pm UTC](https://discourse.julialang.org/t/hcat-with-generator/2300/9 "2017-02-25T23:20:19Z")

</div>

`vcat` is already taken and has a semantic meaning of _vertical concatenation_. IMHO function names in Julia are very central, and should be very carefully constructed and shared between methods to enable maximum utility when reused. But a name other than `genmat` is certainly welcome.

---

<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:** [February 25, 2017, 11:21pm UTC](https://discourse.julialang.org/t/hcat-with-generator/2300/10 "2017-02-25T23:21:05Z")

</div>

```julia
hcat((f(A,i) for i = 1:4)...)

```

works and doesn’t generate an intermediate array.

---

<div class="post-metadata">

**Author:** ![Dan](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/dan/32/42581_2.png) [@Dan](https://discourse.julialang.org/u/Dan)\
**Post date:** [February 25, 2017, 11:32pm UTC](https://discourse.julialang.org/t/hcat-with-generator/2300/11 "2017-02-25T23:32:46Z")

</div>

`hcat` and `genmat` both do some allocations. Benchmarking shows `genmat` does less, and _`genmat` is also 8x faster_ (on my machine).  
It is hard to avoid the allocations and copying without some more information about the generator.

---

<div class="post-metadata">

**Author:** ![cortner](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/cortner/32/204_2.png) [@cortner](https://discourse.julialang.org/u/cortner)\
**Post date:** [February 25, 2017, 11:37pm UTC](https://discourse.julialang.org/t/hcat-with-generator/2300/12 "2017-02-25T23:37:06Z")

</div>

typo - I meant `hcat`. I am asking why not just change the meaning of `hcat(::Generator)`

---

<div class="post-metadata">

**Author:** ![fengyang.wang](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/fengyang.wang/32/104_2.png) [@fengyang.wang](https://discourse.julialang.org/u/fengyang.wang)\
**Post date:** [February 26, 2017, 1:19am UTC](https://discourse.julialang.org/t/hcat-with-generator/2300/13 "2017-02-26T01:19:41Z")

</div>

That would be incompatible with what `hcat` does; it does not concatenate all members of its argument, but rather all its arugments.
