title: Inplace updating of function arguments
body: <p>I need an efficient implementation of the cartesian product for a variable number of arrays.</p>
  
  <p>I have tried the <code>product</code> function from <code>Iterators.jl</code>, but the performance was lacking.</p>
  
  <p>I am a python hacker and have used <a href="https://github.com/scikit-learn/scikit-learn/blob/9e10ec017b15f7549ba462dcd5c2bf089bc318e4/sklearn/utils/extmath.py#L493-L543" rel="nofollow">this function</a> from sklearn and have had good performance results with it.</p>
  
  <p>I have tried to write a Julia version of this function, but am not able to produce the same results as the python function.</p>
  
  <p>My code is:</p>
  
  <pre><code>function my_repeat(a, n)
      # mimics numpy.repeat
      m = size(a, 1)
      out = Array(eltype(a), n * m)
      out[1:n] = a[1]
      for i=2:m
          out[(i-1)*n+1:i*n] = a[i]
      end
      return out
  end
  
  function cartesian(arrs; out=None)
      dtype = eltype(arrs[1])
  
      n = prod([size(i, 1) for i in arrs])
  
      if is(out, None)
          out = Array(dtype, n, length(arrs))
      end
  
      m = int(n / size(arrs[1], 1))
      out[:, 1] = my_repeat(arrs[1], m)
  
      if length(arrs[2:]) &gt; 0
          cartesian(arrs[2:], out=out[1:m, 2:])
          for j = 1:size(arrs[1], 1)-1
              out[(j*m + 1):(j+1)*m, 2:] = out[1:m, 2:]
          end
      end
  
      return out
  end
  </code></pre>
  
  <p>I test it with the following:</p>
  
  <pre><code>aa = ([1, 2, 3], [4, 5], [6, 7])
  cartesian(aa)
  </code></pre>
  
  <p>The return value is:</p>
  
  <pre><code>12x3 Array{Float64,2}:
  1.0  9.88131e-324  2.13149e-314
  1.0  2.76235e-318  2.13149e-314
  1.0  9.88131e-324  2.13676e-314
  1.0  9.88131e-324  2.13676e-314
  2.0  9.88131e-324  2.13149e-314
  2.0  2.76235e-318  2.13149e-314
  2.0  9.88131e-324  2.13676e-314
  2.0  9.88131e-324  2.13676e-314
  3.0  9.88131e-324  2.13149e-314
  3.0  2.76235e-318  2.13149e-314
  3.0  9.88131e-324  2.13676e-314
  3.0  9.88131e-324  2.13676e-314
  </code></pre>
  
  <p>I believe that the problem here is that when I use this line: <code>cartesian(arrs[2:], out=out[1:m, 2:])</code>, the keyword argument <code>out</code> is not updated inplace in the recursive calls. </p>
  
  <p>As can be seen, I have done a very naive translation of the Python version of this function (see link from above). It might well be possible that there are internal language differences that make a naive translation impossible. I don't think this is true because of this quote from the <a href="http://docs.julialang.org/en/latest/manual/functions/#argument-passing-behavior" rel="nofollow">functions</a> section of the julia documentation:</p>
  
  <blockquote>
    <p>Julia function arguments follow a convention sometimes called “pass-by-sharing”, which means that values are not copied when they are passed to functions. Function arguments themselves act as new variable bindings (new locations that can refer to values), but the values they refer to are identical to the passed values. Modifications to mutable values (such as Arrays) made within a function will be visible to the caller. This is the same behavior found in Scheme, most Lisps, Python, Ruby and Perl, among other dynamic languages.</p>
  </blockquote>
  
  <p>How can I make this (or an equivalent) function work in Julia?</p>