# Calling a function an unspecified number of times

I would like to be able to call a function an unspecified number of times. That is, I would like the generalization of something like:

   Sample[yi_, yf_, yinc_, zi_, zf_, zinc_]:=
Table[{y, z}, {y, yi, yf, yinc}, {z, zi, zf, zinc}]


to $n$ variables, all with their own respective initial, finial and incremental values, and so I'd be calling on Table $n$ times. Is something like this even possible?

-

Something like :

sample[ranges_] := Table[Evaluate[ranges[[All, 1]]], Evaluate[Sequence @@ ranges]]


used like :

sample[{{x, 0, 3, 1}, {y, -2, 2, 1}}]

-
Or you can use ranges__ and avoid Sequence and Evaluate. –  Szabolcs Mar 22 '12 at 14:20
I would use ranges:{{_Symbol, _?NumericQ, _?NumericQ, _?NumericQ} ..} or ranges:{_Symbol, _?NumericQ, _?NumericQ, _?NumericQ} .. which forces the user to give the correct form for the iterators. Personally, I'd use the second form of ranges as it is called like Table: sample[{x,0,3,1},{y,-2,2,1}]. Also, you'd remove the Sequence @@ shortening the code. –  rcollyer Mar 22 '12 at 14:25
@Szabolcs Your solution is better, please feel free to edit my answer. –  b.gatessucks Mar 22 '12 at 14:31
Protecting the user by specifying the argument types is good. Note, however, that it precludes constructs in which the endpoints of some ranges depend on the values in the current range, such as {x, 0, 3, 1}, {y, 0, x, 1}. –  whuber Mar 22 '12 at 15:00
@whuber that's true. Then remove the ?NumericQ from them which will allow the additional constructs. –  rcollyer Mar 22 '12 at 15:17

### Going by the suggested syntax in your question you might find use in this:

sample[params__] := Range @@@ Partition[{params}, 3]


This does no type checking and assumes that your params list is in threes.
I kept it simple for ease of reading.

Example:

tbl = sample[3, 12, 2, 5, 1, -1]

{{3, 5, 7, 9, 11}, {5, 4, 3, 2, 1}}


On this output could use Outer:

Outer[ff, ##] & @@ tbl

{{ff[3, 5], ff[3, 4], ff[3, 3], ff[3, 2], ff[3, 1]},
{ff[5, 5], ff[5, 4], ff[5, 3], ff[5, 2], ff[5, 1]},
{ff[7, 5], ff[7, 4], ff[7, 3], ff[7, 2], ff[7, 1]},
{ff[9, 5], ff[9, 4], ff[9, 3], ff[9, 2], ff[9, 1]},
{ff[11, 5], ff[11, 4], ff[11, 3], ff[11, 2], ff[11, 1]}}


### If you allow for more flexible syntax, you might use:

Outer[ff, ##] & @@ Range @@@ {{3, 12, 2}, {5, 1, -1}, {3}}

-