Inside a quantifier (such as foreach), the expression on the RHS is a boolean condition that is evaluated for every possible value of 'i' (or whatever you name the variable). So the def() function is useful here as it returns a bool and specifically returns True for any value that is 'defined' (think 'not null'). Thus for arrays, the def() effectively allows us to just iterate over every value in the array without filtering any out.
To some degree, this is a mis-use of the intention of the def() function. def() should be used anywhere one wishes to test if an expression contains a value that is defined.
you see many attributes marked with a '?' - these are attributes that may or may not be defined. Here is where you would want to use def() - to test if the attribute exists first before trying to read it.
Hope that helps clarify things!
- Robert