Side-effects [was Re: I am out of trial and error again Lists]
Chris Angelico wrote: On Sat, Oct 25, 2014 at 4:40 PM, Rustom Mody rustompm...@gmail.com wrote: Its generally accepted that side-effecting functions are not a good idea -- typically a function that returns something and changes global state. Only in certain circles. Not in Python. There are large numbers of functions with side effects (mutator methods like list.append, anything that needs lots of state like random.random, everything with external effect like I/O, heaps of stuff), and it is most definitely not frowned upon. Hmmm. You might be overstating it a tad. You are absolutely correct that Python is not a strict functional language with no side-effects. However, mutator methods on a class don't change global state, they change the state of an instance. Even random.random and friends don't change global state, they change a (hidden) instance, and you can create your own instances when needed. That gives you the convenience of pseudo-global state while still allowing the flexibility of having separate instances. Even global variables in Python are global to the module, not global to the entire application. So although Python code isn't entirely side-effect free, the general advice to avoid writing code that relies on global state and operates via side-effect still applies. To take an extreme example, we do this: print(len(something)) not this: LEN_ARGUMENT = something len() print(LEN_RESULT) We *could* write code like that in Python, but as a general rule we don't. If we did, it would be frowned upon. I would say that Python is a pragmatic language which uses whatever idiom seems best at the time, but over all it prefers mutable state for compound objects, prefers immutable state for scalar objects (like numbers), and discourages the unnecessary use of global mutable state. -- Steven -- https://mail.python.org/mailman/listinfo/python-list
Re: Side-effects [was Re: I am out of trial and error again Lists]
On Sun, Oct 26, 2014 at 5:12 PM, Steven D'Aprano steve+comp.lang.pyt...@pearwood.info wrote: However, mutator methods on a class don't change global state, they change the state of an instance. Even random.random and friends don't change global state, they change a (hidden) instance, and you can create your own instances when needed. That gives you the convenience of pseudo-global state while still allowing the flexibility of having separate instances. Even global variables in Python are global to the module, not global to the entire application. True, but they do still change state; I oversimplified a bit, but certainly there are plenty of functions that change state in some way, and are not frowned upon. Module level variables really are global, though. You can't easily and conveniently reinstantiate a module in Python; if you import random; random.seed(1234), you can confidently expect that some other module that uses random.random will be affected. Sure, there are ways around that, but that's true of any form of global state - for a start, it's usually process level state, in that spawning a new process will isolate one from another. The only thing that isn't truly global is the namespace; I can write x = {} and you can write x = [] and they don't collide. They're still global (process-level), it's just that they're foo.x and bar.x and are thus distinct. I would say that Python is a pragmatic language which uses whatever idiom seems best at the time, but over all it prefers mutable state for compound objects, prefers immutable state for scalar objects (like numbers), and discourages the unnecessary use of global mutable state. It's not really compound vs scalar, but yes, I agree. Practicality beats purity, on so many levels. Functions with side effects aren't considered some sort of weird beast that we have to permit for the sake of I/O; they're a fundamental part of the language. ChrisA -- https://mail.python.org/mailman/listinfo/python-list