I've been wondering if something like Java's ThreadLocal (which I use a 
massively in (Java) server-side code), could be defined in Nim.

I tried those two approaches, but neither is valid code. It seems to me it 
isn't possible.

Attempt #1: 
    
    
    type
      ThreadLocal*[T] = object
        ## Represents a thread-local, similar to ThreadLocals in Java.
        initialised*: bool
          ## Is this thread local already initialised?
        value*: T
          ## The thread local value.
      
      InitThreadLocalProc*[T] = proc(): T {.nimcall, gcsafe.}
        ## Type of a proc that lazy initialises a ThreadLocal.
    
    proc getValue*[T](init: InitThreadLocalProc[T]): var T =
      ## Returns the value of a thread-local.
      var myThreadVar {.threadvar.}: ThreadLocal[T]
      if not myThreadVar.initialised:
        myThreadVar.value = init()
        myThreadVar.initialised = true
      return myThreadVar.value
    
    proc Returns42(): int =
      42
    
    echo("TL: ",getValue(Returns42))
    

Attempt #2 (would be preferable to #1, because you are not limited to 1 
ThreadLocal per type): 
    
    
    type
      InitThreadLocalProc*[T] = proc(): T {.nimcall, gcsafe.}
        ## Type of a proc that lazy initialises a ThreadLocal.
      
      ThreadLocal*[T] = object
        ## Represents a thread-local, similar to ThreadLocals in Java.
        lazyInit: InitThreadLocalProc[T]
          ## The lazy initialisation proc.
        initialised {.threadvar.}: bool
          ## Is this thread local already initialised?
        value {.threadvar.}: T
          ## The thread local value.
    
    
    proc initThreadLocal*[T](init: InitThreadLocalProc[T]): ThreadLocal[T] =
      ## Initialises a ThreadLocal.
      result.lazyInit = init
    
    proc getValue*[T](tl: ThreadLocal[T]): var T =
      ## Returns the value of a thread-local.
      if not tl.initialised:
        tl.value = tl.lazyInit()
        tl.initialised = true
      return tl.value
    
    
    proc Returns42(): int =
      42
    
    var testThreadLocal = initThreadLocal[int](Returns42)
    
    echo("TL: ",getValue(testThreadLocal))
    

Reply via email to