1

In my function, can I have a variable that

  • Retains its value between function calls.
  • Is only visible inside that function
  • Is unique for each thread i.e. if I'm calling the function from two threads then there are two variables that are static with regard to each thread.

Why I want that:

I have a function in which I fill in a list and return that list. The problem is that if I declare a variable normally, then I will have to allocate memory for it every time I call the function. I want to avoid that and allocate only once then every time I call the function it would fill in that variable with the proper values then return it.

I can do the following inside a class:

class MyClass {
 val __readLineTemp = mutable.IndexedSeq.fill[Int](5)(-1)
 def readLine() = {
     var i = 0
     while (i < __readLineTemp.length) 
     {
         __readLineTemp(i) = Random.nextInt()
         i += 1
     }
     __readLineTemp
 }
}

My problems with this approach is that it doesn't satisfy the points 2 and 3 namely visibility only inside the method and being unique for each thread. However, for point 3 I can simply make each thread initialise its own object of MyClass.

I understand there is probably no way of achieving exactly what I want, but sometimes people come up with clever ideas to overcome this, specially that Scala seems quite deep and there is a lot of tricks you can do

1 Answer 1

4

You can use a closure to satisfy 1 and 2:

def foo = {
    var a = 5
    () => {
        a = a + 1
        a
    }
}

i.e. create a closure that will contain the static variable (in your case, this is __readLineTemp) and return a function that's the only thing with access to the variable.

Then use it like this to satisfy the thread requirement:

val t1 = new Thread(new Runnable {
    def run = {
        val f = new DynamicVariable(foo)
        println(f.value())
        println(f.value())
    }
})
Sign up to request clarification or add additional context in comments.

6 Comments

perfect ! That's really clever and exactly what I hoped to get. I was just reading about closures today and I was wondering when I would need that feature !
Yep, closures can be pretty useful, especially in languages like JavaScript where a closure is the only thing that creates a scope (although this changes with ECMAScript 6 and let).
hmmm... Are you sure that variable gets created once? My understanding of your answer is that "var a = 5" is executed when "foo" is defined and not every time it is called. However, benchmarking it shows that it is very slow compared to my example i.e. it must be allocating memory for it every time it is called
yup, I have just debugged it. It creates the variable every time you call the function
You have to do either the val f = new DynamicVariable(foo) or val f = foo and then call f. This is so f gets the result from initializing the closure and becomes the returned function. If you call foo directly, it will indeed create it every time.
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.