Take the 2-minute tour ×
Programmers Stack Exchange is a question and answer site for professional programmers interested in conceptual questions about software development. It's 100% free, no registration required.

With dynamic scoping, a callee can access the variables of its caller. Pseudo C code:

void foo()
{
    print(x);
}

void bar()
{
    int x = 42;
    foo();
}

Since I have never programmed in a language that supports dynamic scoping, I wonder what some real world use cases for dynamic scoping would be.

share|improve this question
    
maybe it's easier to implement when the interpreter is implemented in some particular other language? –  Alf P. Steinbach Aug 23 '11 at 18:19
1  
It's of sufficiently little use that most languages that once used it (e.g., Lisp) don't any more. Just for one obvious example, most early Lisp implementations used dynamic scoping, but now all the major variants (e.g., CL, Scheme) use lexical scoping. –  Jerry Coffin Aug 23 '11 at 19:20

4 Answers 4

(Disclaimer: I've never programmed in a dynamic scoping language)

The scoping is much easier to implement and potentially faster. With dynamic scoping, only the one symbol table is needed (the variables currently available). It just reads from this symbol table for everything.

Imagine in Python the same function.

def bar():
    x = 42;
    foo(42)

def foo(x):
    print x

When I call bar, I put x into the symbol table. When I call foo, I take the symbol table currently used for bar and push it onto the stack. I then call foo, which has x passed to it (likely having been put into the new symbol table on calling the function). After exiting the function, I have to destroy the new scope and restore the old one.

With dynamic scoping, this isn't needed. I only need to know the instruction I need to return to when the function ends since nothing has to be done to the symbol table.

share|improve this answer
    
"Potentially faster" only in a (naive) interpreter; compilers can do much better with lexical scoping than they can with dynamic scoping. Also, "With dynamic scoping, this isn't needed...." is wrong: with dynamic scoping, when a variable's scope ends (eg, the function returns), you need to update the symbol table to restore its previous value. Actually, I think the code would typically refer directly to a "symbol object" that would have a mutable field for the variable's current value, much faster than doing a table lookup each time. But still, the update work doesn't just vanish. –  Ryan Culpepper Aug 23 '11 at 20:21
    
Ah, I wasn't aware dynamic scoping would still restore the value from before the function was called. I thought they all referred to the same value. –  jsternberg Aug 23 '11 at 20:25
1  
yes, there is still nesting. Otherwise it would be equivalent to making every variable global and just doing a simple assignment to it. –  Ryan Culpepper Aug 23 '11 at 20:43

There pretty much aren't any. I sure hope that you, for example, never use the same variable twice.

void foo() {
    print_int(x);
}
void bar() {
    print_string(x);
}

Now how do you call both foo and bar from the same function?

This is effectively akin to simply using a global variable, and it's bad for all the same reasons.

share|improve this answer
    
x = 42; foo(); x = '42'; bar();? –  Luc Danton Aug 24 '11 at 0:38

Not 100% sure if this is an exact match, but I think it at least gets near enough in a general sense to show where it may can be of use to break or change scoping rules.

The Ruby language comes the templating class ERB, which for example in Rails is used to generate html files. If you use it looks like this:

require 'erb'

x = 42
template = ERB.new <<-EOF
  The value of x is: <%= x %>
EOF
puts template.result(binding)

The binding hands access to local variables to the ERB method call, so it can access them and use them to fill the template. (The code between the EOFs is a string, the part between <%= %> evaluated as Ruby code by ERB and would declare it's own scope like a function)

A Rails example even better demonstrates this. In an article controller, you would find something like this:

def index
  @articles = Article.all

  respond_to do |format|
    format.html
    format.xml  { render :xml => @posts }
  end
end

The index.html.erb file could then use the local variable @articles like this (in this case the creation of an ERB object and the binding are handled by the Rails framework, so you don't see it here):

<ul>
<% @articles.each do |article| %>
  <li><%= article.name</li>
<% end %>
</ul>

So by use of a binding variable, Ruby allows to run one and the same template code in different contexts.

The ERB class is only one example of usage. Ruby allows in general to get the actual state of execution with variable and method bindings by use of Kernel#binding, which is very useful in any context where you want to evaluate a method in different context or want to keep a context for later use.

share|improve this answer

A very useful application of dynamic scoping is for passing contextual parameters without having to add new parameters explicitly to every function in a call stack

For example, Clojure supports dynamic scoping via binding, which can be used to temporarily reassign the value of *out* for printing. If you re-bind *out* then every call to print within the dynamic scope of the binding will print to your new output stream. Very useful if, for example, you want to redirect all printed output to some kind of debugging log.

Example: in the code below, the do-stuff function will print to the debug output rather than standard out, but note that I didn't need to add an output parameter to do-stuff to enable this....

(defn do-stuff [] 
  (do-other-stuff)
  (print "stuff done!"))

(binding [*out* my-debug-output-writer]
  (do-stuff))

Note that Clojure's bindings are also thread-local, so you don't have an issue with concurrent usage of this capability. This makes bindings considerably safer than (ab)using global variables for the same purpose.

share|improve this answer

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.