package edu.umbc.cmsc331.matuszek;

import java.util.concurrent.atomic.AtomicInteger;

public class SideEffects
{
	public static void main(String[] args)
	{
		//  What will this code print?
		int x = 12;
		int y = increment(x);
		System.out.println("Primitive ints: x is " + x + ", y is " + y);
		
		//  What will this code print?
		AtomicInteger i = new AtomicInteger(12);
		AtomicInteger j = increment(i);
		System.out.println("AtomicIntegers: i is " + i + ", j is " + j);
	}

	static AtomicInteger increment(AtomicInteger i)
	{
		i.incrementAndGet();
		return i;
	}
	
	static int increment(int x) 
	{
		x = x + 1;
		return x;
	}
}

/*
Here is what will be printed:
Primitive ints: x is 12, y is 13
AtomicIntegers: i is 13, j is 13
Despite the fact that both increment methods appear to modify the variables that are passed in to them, the primitive int x remains unchanged in main, while the AtomicInteger i has its value modified in main.

The small moral of the story is that variables of primitive types have their actual values passed to method calls, and therefore can be modified within those methods without modifying the original variable -- essentially, the int x in increment has nothing to do with int x in main.

The larger moral of the story is that you should be aware of whether or not the methods you are calling have side effects. These two increment methods look similar from the outside, but they work differently.

But the moral of the story that is why I brought it up in class in the first place, even though we're done with Java, is that side effects are a pain, and one of the advantages of functional programming is that it avoids side effects altogether.

Even if you are not writing in a functional-programming-specific language, you can write functional-style code, such as this version of increment:

	static AtomicInteger increment(AtomicInteger i)
	{
		int value = i.get();
		return new AtomicInteger(value + 1);
	}
There are no side effects here; the method takes a value and returns a value.
*/