1
$\begingroup$

Evaluating the following Table expression

Table[{s,p}, 
 {s,AstronomicalData[p,"Satellites"]}, 
 {p,AstronomicalData["Planet"]} 
]; 

produces the error message

Table::iterb: Iterator {s, $Failed} does not have appropriate bounds.

But when I switch the iteration order, it works fine.

Table[{s,p}, 
 {p,AstronomicalData["Planet"]}, 
 {s,AstronomicalData[p,"Satellites"]} 
]; 

Why? (I don't think this is specific to AstronomicalData, that's just where I ran across it)

$\endgroup$
  • 3
    $\begingroup$ Later iterators may depend on earlier iterators, but not vice versa. Just like $\sum_{i=1}^n \sum_{j =i}^n a_{ij}$ but not $\sum_{j=i}^n \sum_{i=1}^n a_{ij}$. $\endgroup$ – Michael E2 Dec 17 '17 at 17:31
  • 1
    $\begingroup$ Programmatically what is happening is that the symbols in the first iterator, other than s, are not localized and their values are taken from the global, system, or other contexts. Hence the AstronomicalData[p,"Satellites"] fails probably because p does not have a value. $\endgroup$ – Michael E2 Dec 17 '17 at 21:05
  • $\begingroup$ Any reason why you are not using EntityValue[PlanetData[], "Satellites", "EntityAssociation"] instead of Table? $\endgroup$ – Edmund Dec 18 '17 at 3:16
5
$\begingroup$

In the larger context, this is something you have to get used to. I too believe it is not intuitive. The reason for that is as follows:

Table[{x, y}, {x, 3}, {y, 4}]

This simple iteration scheme (works also with Sum, Integrate, Do, etc) implies for me that {x,3} is closer to the body {x,y} and therefore it is the inner iteration. But in fact, it is the other way around. This is even more disturbing when looking at a Do loop

Do[
 Print[{x, y}],
 {x, 3},
 {y, 3}
]

It feels like the x iteration is the inner loop, but it isn't. That is the one thing you have to remember and then everything comes naturally. If you know this, then you also see that this table

Table[{x, y}, {x, 3}, {y, x}]

can be rewritten in two nested tables

Table[
 Table[{x, y}, 
   {y, x}],
 {x, 3}
]

Here it also becomes clear, why this doesn't feel right. Now the iterators are in the order you would expect and {y,x} comes first and {x,3} comes seconds.

Additionally, please note that in version 10+ With the order is really from outer to inner and since the definition lists are the first arguments this makes sense. Everyone instantly knows what is meant by

With[{x = 3}, {y = x + 1}, x + y]
$\endgroup$
  • $\begingroup$ It make sense to me, if I think of the order of evaluation (left to right, not outer to inner). Somewhat confusing is that the first argument is held and, in a sense, evaluated last, that is, after each iterator variable has been given a value. If the body came last, then nesting tables would keep iterators in the same order, like With. $\endgroup$ – Michael E2 Dec 18 '17 at 2:43
  • 1
    $\begingroup$ @MichaelE2 I mean, I obviously got used to it, but I see it differently. When I do Table[body, {x,..}] I want to iterate x. Now, if I add another iterator, then the natural way of thinking is: I already have an iteration, please iterate now this iteration. Instead, the new iteration becomes the inner iteration. However, Haskell's list comprehension does it the same way. $\endgroup$ – halirutan Dec 18 '17 at 3:08

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.