I often need gridded versions of continuous functions. For a function with one argument, the usual broad cast is the most elegant way:

```
oned(x) = 2*x # 1D func
xs = 0.0:1.0:10.0 # x grid
oned_gridded = oned.(xs)
```

This method is often found in Julia examples.

Then, what about multiple-argument functions? You can of course use the list comprehension, but it’s a bit more verbose and a little bit more error-prone: `[twod(x,y) for x in xs, y in ys]`

.

I then found this thread

and came up with

```
twod(x,y) = "$(x) & $(y)" # 2D func
twod_tuple(tpl) = twod(tpl[1], tpl[2])
xs = 0.0:1.0:10.0 # x grid
ys = 20.0:3.0:50.0 # y grid
twod_gridded = twod_tuple.(Iterators.product(xs,ys))
```

Is this the most succinct solution today? Is there a standard way to convert a multiple-argument function into a single-tuple-argument function?

By the way, I’ve never been able to remember whether `x in xs, y in ys`

or `y in ys, x in xs`

is the correct order. That’s one of the reasons why I want to avoid the list comprehension to construct a multidimensional array. For the regular `for`

loop,

```
for j in axes(arr,2)
for i in axes(arr,1)
arr[i,j] = func_of(i,j)
```

is the right order because `i`

should change faster. The above is (functionally, at least) equivalent to

```
for j in axes(arr,2), i in axes(arr,1)
arr[i,j] = func_of(i,j)
```

So far so good. But then, you have to flip the order for the list comprehension

```
arr = [func_of(i,j) for i in is, j in js]
```

*if I’m not mistaken*.

In contrast, there is no such doubt in `Iterator.product`

because it is obviously the standard outer product in linear algebra.

For this reason, I’d probably abolish the regular `for`

loop from my code and write it this way:

```
for (i,j) in Iterators.product(is,js)
arr[i,j] = func_of(i,j)
```

After all, a nested `for`

loop is an outer product.

Then I hope the above loop can be written like

```
for (i,j) in is ⊗ js # outer product
```