Dynamic scope. Not really very strange but very unusual; not supported by many languages. AFAIK Perl and Lisp(ish) languages are the only ones. For example:
sub foo {my $x='fish'; local $y='chips'; &bar;}
sub bar {print "\$x is >$x< and \$y is >$y<\n";}
This will output
$x is >< and $y is >chips<
It's quite handy - saves passing around a "context" object, for example. The remarkable thing is how few languages implement some form of it.
Dynamic scope is supported in older Lisps (eLisp is the only widely used variant with it), and a variety of scripting languages including PHP, Perl, TCL and vimsh (that's vim's internal scripting language). It is rarish because it has been recognized as a bad design, but it still turns up because it is easy to implement.
It is often recognized as bad design - though I don't think that's always fair. I thought of this because I was just reading some Java code that passed around a context object with all kinds of random things stuffed into it. It was, in effect, a way of simulating dynamic scope. There's a time and a place for everything. I'm sure dynamic scope can be horribly abused, but it's also nice to have in the toolbox for when you actually need to do what it does.
import Control.Monad.Reader
type Action = ReaderT String IO ()
foo :: Action
foo = do
bar
local (const "new state") bar
bar
bar :: Action
bar = liftIO . putStrLn =<< ask
> runReaderT foo "foo"
foo
new state
foo
If you ever tried implementing a language, you'll see that dynamic scope is actually much easier. So it's not that language x doesn't implement dynamic scope. It's that language x doesn't actually implement lexical scope so it's left with dynamic scope :)
I'm not sure I understand your sentence (did you mean language x does implement dynamic scope?), but I feel obliged to mention Perl offers lexical scoping as well--within each file and each block.
If you're a lazy language designer dynamic scope sort of emerges from the design proces while one really has to do extra work to support lexical scoping in a language.
Perl 5 has dynamic scoping for backward compatibility with Perl 4, which had only dynamic scoping, and not only that, it botched it so that this code didn't work right:
sub greet {
local ($who) = @_;
print "hello, $who\n";
}
$who = "world";
&greet($who);
This would print, "hello, " with a newline, due to a design bug called "variable suicide", which has been fixed in newer Perls.
Needless to say, this made the extract-subroutine refactoring quite a bit more trouble in Perl 4.
Perl 6 also has dynamic scoping. But I don't think they kept it just for backward compatibility with Perl 4 & 5 :)
Here is another example where dynamic scoping can indeed be very useful:
sub bar { 'bar' }
sub baz { bar() }
sub foo {
no warnings 'redefine';
local *bar = sub { 'My Bar' };
baz();
}
say foo(); # => 'My Bar'
say baz(); # => 'bar'