Previous page Table of Contents Next page
Dynamic binding of variables is a very useful feature, but it is not included in the PLOT language. However, it can easily be implemented as a user-defined library, based on macros, cleanups, and a mechanism for thread-local storage.
---TBD dynamic binding is so useful that maybe I should build it into the language after all?
Here is an example implementation. Define dynamically bindable variables using defdynamic. Use dynamic-bind to create a new dynamic binding of such a variable. These bindings are scoped according to dynamic control state and are per-thread. Accessing a dynamically bindable variable is slower than accessing an ordinary variable. This assumes the existence of a class thread-local-storage whose value slot has a distinct value in each thread. Most operating systems provide a feature like that.
def *no-local-value* = list(1) ; a unique object
defmacro defdynamic ?:typed-variable := ?init =>
def var = typed-variable.name
def local-var = name(spelling(var) + "-local", var)
def global-var = name(spelling(var) + "-global", var)
def type-spec = typed-variable.type
`do
def ?global-var is ?type-spec := ?init
def ?local-var = thread-local-storage(*no-local-value*)
defmacro ?var => \`dynamic-binding(?local-var, ?global-var)\` `
defmacro dynamic-bind ?var is name := ?new-value ?:body =>
def local-var = name(spelling(var) + "-local", var)
`block
def old-value = ?local-var.value
cleanup ?local-var.value := old-value
?local-var.value := ?new-value
?body`
;; Read a dynamically bound variable
defun dynamic-binding(local-var is thread-local-storage, global-var)
def local-value = local-var.value
if local-value eq *no-local-value*
global-var
else
local-value
;; Write a dynamically bound variable
defmacro dynamic-binding:= (?local-var is name, ?global-var is name, ?new-value) =>
`if ?local-var.value eq *no-local-value*
?global-var := ?new-value
else
?local-var.value := ?new-value`
A minor problem with this implementation is that reading the dynamically bound variable does not have the specific declared compile-time type. The result type of the runtime function dynamic-binding is anything. This could be fixed by adding a run-time type check after calling dynamic-binding, or if the PLOT type system becomes enhanced to support parameterized types and thread-local-storage and dynamic-binding are parameterized.
Previous page Table of Contents Next page