<html><head></head><body style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space; "><br><div><div>On 2011-05-31, at 24:35 , Dan Stromberg wrote:</div><br class="Apple-interchange-newline"><blockquote type="cite"><br><div class="gmail_quote">On Mon, May 30, 2011 at 5:28 PM, Henry Olders <span dir="ltr"><<a href="mailto:henry.olders@mcgill.ca">henry.olders@mcgill.ca</a>></span> wrote:<br><div><br>Be careful not to conflate global scoping or global lifetime, with mutability or pure, side-effect-free functions (callables).  It sounds like what you want is immutability and/or freedom from side effects, which is found most often in (pure) functional languages - which is not what Python is, nor does it attempt to be so.<br></div></div></blockquote><div><br></div>I think you're right, I've been conflating scoping with side effects caused by passing mutable objects. <br><blockquote type="cite"><div class="gmail_quote"><div>
<br>In Python, and in many other languages, if you pass a scalar (or more generally, an object of an immutable type) to a function, and then change the scalar in that function, you only change the scalar within that function, not within the caller.<br>
<br>However, if you pass an aggregate type like a list (array) or dictionary (hash table), then the formal argument itself that you've passed is still only changeable within that function, however what it points off at _is_ changeable via that formal argument.  This is of course because otherwise passing a 1 gigabyte dictionary to a function would either have to copy the whole dictionary, or implement some sort of Copy-on-Write semantics, or make it somehow readonly.<br>
<br>If you need side effect-free functions in Python, you'd probably best copy your aggregates, EG:<br><br>import copy<br><br>def main():<br>      a = ['a list','with','three elements']<br>      print a<br>
      print fnc1(a)<br>      print a<br><br>def fnc1(b):<br>      b = copy.deepcopy(b)<br>      return fnc2(b)<br><br>def fnc2(c):<br>      c = copy.deepcopy(c)<br>      c[1] = 'having'<br>      return c<br></div></div></blockquote></div><br><div>Clearly, making a copy within the function eliminates the possibility of the side effects caused by passing in mutable objects. Would having the compiler/interpreter do this automatically make python so much different? What if it were optional, like nested scopes were in python 2.1 until they became standard in 2.2?</div><div><br></div><div>Henry</div></body></html>