Name any protocol for which the question "does this mutate?" has no answer.
Heh -- you must not use Zope much <0.6 wink>. I'm hard pressed to think of a protocol where that does have a reliable answer. Here:
x1 = y.z x2 = y.z
Are x1 and x2 the same object after that? At least equal? Did either line mutate y? You simply can't know without knowing how y's type implements __getattr__, and with the introduction of computed attributes (properties) it's just going to get muddier.
(I ask you to accept that __call__ is a special case.)
It's not to me -- if a protocol invokes user-defined Python code, there's nothing you can say about mutability "in general", and people do both use and abuse that.
What's so special about "for" that it should pretend to deliver purely functional behavior in a highly non-functional language?
Who said anything about functional behaviour? I'm not requiring that looping *never* mutate. I just want to be able to tell *whether* it will.
I don't blame you, and sometimes I'd like to know whether y.z (or "y += z", etc) mutates y too. It cuts deeper than loops, so a loop-focused gimmick seems inadequate to me (provided "something needs to be done about it" at all -- I'm not sure, but doubt it).