Programming Language for Old Timers


by David A. Moon
February 2006 .. September 2008

Comments and criticisms to dave underscore moon atsign alum dot mit dot edu.


Previous page   Table of Contents   Next page


Dynamic Binding

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