Hacker Newsnew | past | comments | ask | show | jobs | submitlogin

With RAII, it is not terribly hard to build dynamic scoping on top of thread_local variables in C++.

   template<class T>
   struct scoped_replace {
       scoped_replace(T& ref, T new_val) 
          : ref(ref), old_val(ref) { 
         ref =  std::move(new_val); 
       }
       ~scoped_replace() { ref = std::move(old_val); }
       T& ref;
       T old_val;
   };

   thread_local int val = 0;
   int foo() {
      return val;
   }
  
   int bar() {
      scoped_replace _(val, 42);
      return foo();
   }
   int main() {
      foo(); // returns 0
      bar(); // returns 42;
      foo(); // still returns 0
   }


That's a "shallow binding" implementation of dynamic scope which works fine enough; but if you have coroutines and continuations and such, it might not play along. Whichever thread invokes a continuation will see its own current value of the variable.

Under "deep binding", where we have a dynamic environment stack, we can save that stack as part of the context of the coroutine, continuation or whatever else. It requires only one word: a pointer to the top of the dynamic environment. Whenever we restore that pointer value, we have the original environment.




Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: