Take the 2-minute tour ×
Programmers Stack Exchange is a question and answer site for professional programmers interested in conceptual questions about software development. It's 100% free, no registration required.

I feel that side effects are a natural phenomenon. But it is something like taboo in functional languages. What are the reasons?

Edit: My question is specific to functional programming style. Not all programming languages/paradigms.

share|improve this question
add comment

10 Answers

up vote 42 down vote accepted

Writing your functions/methods without side effects - so they're pure functions - makes it easier to reason about the correctness of your program.

It also makes it easy to compose those functions to create new behaviour.

It also makes certain optimisations possible, where the compiler can for instance memoise the results of functions, or use Common Subexpression Elimination.

Edit: at Benjol's request: Because a lot of your state's stored in the stack (data flow, not control flow, as Jonas has called it here), you can parallelise or otherwise reorder the execution of those parts of your computation that are independent of each other. You can easily find those independent parts because one part doesn't provide inputs to the other.

In environments with debuggers that let you roll back the stack and resume computing (like Smalltalk), having pure functions means that you can very easily see how a value changes, because the previous states are available for inspection. In a mutation-heavy calculation, unless you explicitly add do/undo actions to your structure or algorithm, you cannot see the history of the computation. (This ties back to the first paragraph: writing pure functions makes it easier to inspect the correctness of your program.)

share|improve this answer
2  
Maybe consider adding something about concurrency in your answer? –  Benjol Oct 28 '10 at 8:48
1  
Side-effect free functions are easier to test and to reuse. –  LennyProgrammers Oct 28 '10 at 10:56
    
@Lenny222: reuse was what I was hinting at by talking about function composition. –  Frank Shearar Oct 28 '10 at 11:22
    
@Frank: Ah, ok, too shallow browsing. :) –  LennyProgrammers Oct 28 '10 at 11:38
    
@Lenny222: It's ok; it's probably a good thing to spell it out. –  Frank Shearar Oct 28 '10 at 11:56
add comment

You've got it wrong, functional programming promotes limiting side effects to make programs easy to understand and optimize. Even Haskell allows you to write to files.

Essentially what I am saying is that functional programmers don't think side effects are evil, they simply think limiting the use of side effects is good. I know it may seem like such a simple distinction but it makes all the difference.

share|improve this answer
    
Which is why they're "something like taboo" - FPLs encourage you to limit side effects. –  Frank Shearar Oct 28 '10 at 6:30
    
+1 for the approach. side effects still exist. indeed, they are limited –  Belun Oct 28 '10 at 9:22
    
For clarification, I haven't said 'why side effect is not allowed in functional programming' or 'why side effect is not needed'. I know It IS allowed in functional languages and sometimes is a must. But it is very much discouraged in functional programming. Why? That was my question. –  Gulshan Oct 28 '10 at 9:25
    
@Gulshan - Because side effects make programs harder to understand and optimize. –  ChaosPandion Oct 28 '10 at 14:00
add comment

Few to no languages make it impossible to cause side-effects. Languages that were completely side-effect free would be prohibitively difficult (near to impossible) to use, except in a very limited capacity.

Why side-effects are considered evil?

Because they make it much more difficult to reason about exactly what a program does, and to prove that it does what you expect it to do.

At a very high level, imagine testing an entire 3-tier web site with only black-box testing. Sure, it's doable, depending on the scale. But there is certainly a lot of duplication going on. And if there is a bug (that is related to a side-effect), then you could potentially break the entire system for further testing, until the bug is diagnosed and fixed, and the fix is deployed to the test environment.

Benefits

Now, scale that down. If you were fairly good at writing side-effect free code, how much faster would you be at reasoning at what some existing code did? How much faster could you write unit tests? How confident would you feel that the code with no side-effects was guaranteed bug-free, and that users could limit their exposure to any bugs it did have?

If code has no side-effects, the compiler also may have additional optimizations that it could perform. It may be much easier to implement those optimizations. It may be much easier to even conceptualize an optimization for side-effect free code, which means that your compiler vendor might implement optimizations that are difficult-to-impossible in code with side effects.

Concurrency is also drastically simpler to implement, to automatically generate, and to optimize when code has no side-effects. This is because all the pieces can be safely evaluated in any order. Allowing programmers to write highly concurrent code is widely considered the next big challenge that Computer Science needs to tackle, and one of the few remaining hedges against Moore's Law.

share|improve this answer
    
Ada makes it very difficult to cause side-effects. It is not impossible though, but you clearly know what you do then. –  mouviciel Oct 28 '10 at 9:22
    
@mouviciel: I think there are at least a few useful languages out there that make side-effects very difficult, and try to relegate them to Monads. –  Merlyn Morgan-Graham Oct 28 '10 at 9:27
add comment

Side effects are like "leaks" in your code that will need to be handled later, either by you or some unsuspecting coworker.

Functional languages avoid state variables and mutable data as a way of making code less context dependent and more modular. Modularity insures that the work of one developer won't affect/undermine the work of another.

Scaling rate-of-development with team size, is a "holy grail" of software development today. When working with other programmers, few things are as important as modularity. Even the most simple of logical side effects make collaboration extremely difficult.

share|improve this answer
    
+1 - "or some unsuspecting coworker" –  Merlyn Morgan-Graham Oct 28 '10 at 9:35
1  
-1 for side effects being "leaks that need to be handled." Creating "side effects" (non-pure-functional code) is the entire purpose of writing any non-trivial computer program. –  Mason Wheeler Jan 19 '11 at 18:33
add comment

In my experience good design in Object Orientated programing mandates the use of functions that have side effects.

For example, take a basic UI desktop application. I may have a running program that has on its heap an object graph representing the current state of domain model of my program. Messages arrive to the objects in that graph (for instance, via methods calls invoked from the UI layer controller). The object graph (domain model) on the heap is modified in response to the messages. Observers of the model are informed of any changes, the UI and maybe other resources are modified.

Far from being evil the correct arrangement of these heap-modifying and screen-modifying side effects are at the core of OO design (in this case the MVC pattern).

Of course, that does not mean that your methods should have arbitary side-effects. And side effect free functions do have a place in improving the readbility and sometimes performance, of your code.

share|improve this answer
1  
Observers (including the UI) should find out about modifications via subscribing to the messages/events that your object send out. This is not a side effect unless the object directly modifies the observer - which would be bad design. –  ChrisF Oct 28 '10 at 10:42
1  
@ChrisF Most defintely it is a side effect. The message passed to the observer (in an OO langauge most likely a method call on an interface) will lead to the state of the UI component on the heap changing (and these heap objects are visible to other parts of the program). The UI component is neither a parameter of the method or the return value. In a formal sense, for a function to be side effect free it must be idempotent. Notification in the MVC pattern is not, for example the UI may display a list of messages it has received - console - calling it twice results in a different program state. –  flamingpenguin Oct 28 '10 at 15:17
add comment

A few notes:

  • Functions without side effects can trivialy be executed in parallel, while functions with side effects typically require some sort of synchronisation.

  • Functions without side effects allow for a more aggressive optimization (e.g. by transparentely using an result cache), because as long as we get the right result, it doesn't even matter whether or not the function was really executed

share|improve this answer
add comment

Well, IMHO, this is quite hypocritical. Nobody likes side effects, but everybody needs them.

What is so dangerous about side effects is that if you call a function, then this possibly has an effect not only on the way the function behaves when it is called next time, but possibly it has this effect on other functions. Thus side effects introduce unpredictable behavior and nontrivial dependencies.

Programming paradigms such as OO and functional both address this problem. OO reduces the problem by imposing a separation of concerns. This means the application state, which consists of a lot of mutable data, is encapsulated into objects, each of which is responsible for maintaining its own state only. This way the risk of dependencies is reduced and problems are far more isolated and easier to track.

Functional programming takes a far more radical approach, where the application state is simply immutable from the perspective of the programmer. This is a nice idea, but renders the language useless on its own. Why? Because ANY I/O-operation has side effects. As soon as you read from any input stream, you application state is likely to change, because the next time you invoke the same function, the result is likely to be different. You may be reading different data, or - also a possibility - the operation might fail. The same is true for output. Even output is an operation with side effects. This is nothing you realize often nowadays, but imagine you have only 20K for your output and if you output any more, your app crashes because you're out of disk space or whatever.

So yes, side effects are nasty and dangerous from the perspective of a programmer. Most bugs come from the way certain parts of the application state are interlocked in a nearly obscure way, through unconsidered and oftentimes unnecessary side effects. From the perspective of a user, side effects are the point of using a computer. They don't care for what happens inside or how it is organized. They do something and expect the computer to CHANGE accordingly.

share|improve this answer
    
interestingly logic programming not only does not have functional side effects; but you can't even change the value of a variable once assigned. –  Ilan Oct 28 '10 at 10:31
    
@Ilan: This is also true for some functional languages and it is a style easy to adopt. –  back2dos Oct 28 '10 at 14:17
    
"Functional programming takes a far more radical approach, where the application state is simply immutable from the perspective of the programmer. This is a nice idea, but renders the language useless on its own. Why? Because ANY I/O-operation has side effects": FP does not forbid side-effects, it rather restricts them when not necessary. E.g. (1) I/O -> side effects are necessary; (2) computing an aggregate function from a sequence of values -> side effect (e.g. for loop with accumulator variable) not necessary. –  Giorgio Nov 18 '12 at 19:31
add comment

From an article about Functional programming:

In practice, applications need to have some side effects. Simon Peyton-Jones, a major contributor to the functional programming language Haskell, said the following: "In the end, any program must manipulate state. A program that has no side effects whatsoever is a kind of black box. All you can tell is that the box gets hotter." (http://oscon.blip.tv/file/324976) The key is to limit side effects, clearly identify them, and avoid scattering them throughout the code.

share|improve this answer
add comment

Evil is a bit over the top.. it all depends on the context of the usage of the language.

Another consideration to those already mentioned is that it makes proofs of correctness of a program much simpler if there are no functional side effects.

share|improve this answer
add comment

Any side-effect introduces extra input/output parameters which must be taken in account when testing.

This make code validation much more complex as the environment cannot be limited to just the code being validated, but must bring in some or all of the surrounding environment (the global that is updated lives in that code over there, which in turn depends on that code, which in turn depends on living inside a full Java EE server....)

By trying to avoid side-effects you limit the amount of externalism needed to run the code.

share|improve this answer
add comment

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

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