title: Atomic compareAndSet parameters are evaluated even if it's not used
body: <p>I have the following code that set the Atomic variable (both <code>java.util.concurrent.atomic</code> and <code>monix.execution.atomic</code> behaves the same:</p>
  
  <pre><code>class Foo {
    val s = AtomicAny(null: String)
  
    def foo() = {
      println("called")
      /* Side Effects */ 
      "foo" 
    }
  
    def get(): String = {
      s.compareAndSet(null, foo())
      s.get
    }
  }
  
  
  val f = new Foo
  f.get //Foo.s set from null to foo, print called
  f.get //Foo.s not updated, but still print called
  </code></pre>
  
  <p>The second time it compareAndSet, it did not update the value, but still foo is called. This is causing problem because <code>foo</code> is having side effects (in my real code, it creates an Akka actor and give me error because it tries to create duplicate actors). </p>
  
  <p>How can I make sure the second parameter is not evaluated unless it is actually used? (Preferably not using synchronized)</p>
  
  <p>I need to pass implicit parameter to foo so lazy val would not work. E.g.</p>
  
  <pre><code>  lazy val s = get() //Error cannot provide implicit parameter
  
    def foo()(implicit context: Context) = {
      println("called")
      /* Side Effects */ 
      "foo" 
    }
  
    def get()(implicit context: Context): String = {
      s.compareAndSet(null, foo())
      s.get
    }
  </code></pre>