Home > Enterprise >  Can we say function closure is saving a state to a function, and every time we assign a new state to
Can we say function closure is saving a state to a function, and every time we assign a new state to

Time:12-04

In following function called inc in Scala which does an increment operation.

def inc(more:Int) = {
  def helper(x:Int) = x more
  helper _
}

Whenever inc function is called, it returns another function which binds the argument passed to it. For example, inc(1) will return another function of type Int => Int where variable more is bind with 1.

inc(1) // This is of type Int => Int

So can we say that more is a state variable to the returned function and when we call inc(1) then 1 is assigned to more?

Here are some more elaborations,

Since I come from OO Programming paradigm, when I say state I was correlating it with Instance of a class, which at a given time has particular state. Lets first consider a class in Java call IncHelper as follows:

class IncHelper{
    private int more;
    public IncHelper(int more){
        this.more = more;
    }

    public int inc(int x){
        return x this.more;
    }
}

If I create different instance of above class as follows:

IncHelper inc1 = new IncHelper(1);  
// This instance will always increase a value by 1
inc1.inc(10);     // output will be 11

If I create different instance of above class as follows:

IncHelper inc2 = new IncHelper(2);  
// This instance will always increase a value by 2
inc2.inc(10);     // output will be 12

So in above two scenarios the two instances inc1 and inc2 contains two different values for state variables. And similar is true for the example I have given for Scala functional programming:

val inc1 = inc(1)
inc1(10)                   // Will return 11

If I create another value as follows:

val inc2 = inc(2)
inc2(10)                    // Will return 12

So in both cases i.e. OO Programming when I created 2 instances of IncHelper, it remembers the variable which is passed while constructing it. Same way, it is true for the two function literals we have created, where the two variables passed while creating the function literals inc1 and inc2 has stored the values.

CodePudding user response:

A function's closure stores information about context - whether this context consist of mutable and/or immutable data is another matter.

We would call function stateful only it there was some observably mutable state in it (making the function not referentially transparent; side effects like printing counts as mutable state). So, unless you have some data that could possible be mutated (having vars there that are never mutated makes them effective immutable), you function has no state according to usual terminology.

In your case:

def inc(more:Int) = {
  def helper(x:Int) = x more
  helper _
}

inc does NOT store mutable data. x more returns a new value without mutating neither x nor more values. If you do:

inc(1)
inc(1)
inc(1)
inc(1)

you'll get the same result (Int => Int function with the same behavior) every time with no side effects. So according to the usually accepted terminology, inc function is stateless and you cannot say that is has a state. The fact that is has some data stored inside... is irrelevant because every piece of code you ever wrote does this, so everything would be called stateful and distinction between stateful and stateless would be virtually useless.

Now, if you defined you function as:

var state = 0
def inc(more:Int) = {
  state = state   more
  val y = state // binds current value of state
  def helper(x:Int) = x   y
  helper _
}

every call to inc with the same value would result in a different value (here: function Int => Int with a different behavior), so there would be some state to talk about. (int function would have a state - stored in var state, while the returned functions would be stateless because they would capture only immutable values).

That state matter would be independent of the concept of closure - closure only "says" that function's definition uses some data provided at the moment it is created AND that function still can access this data after you no longer can from outside of it.

Summarizing, I would only say that (a particular) "function's closure saves a state to a function" if there was some mutable state in the environment that function was created which was captured (used) by that function. In other cases I would not say this as there would be no "state" to capture. However as this is quite imprecise statement (does function captured a snapshot of mutable state which is not mutable on it own? or does a function captured reference to some mutable data which can be mutated outside of it?) I would avoid it altogether.

  • Related