in reply to Why does Perl use dynamic scoping?

Perl cannot get rid of dynamic scoping because it is needed for backwards compatibility.

Other than that it is generally a bad idea. I have only needed it to track levels of function calls, or detect deep recursion.

Not sure what else you would choose to use it for if you could choose lexical scoping instead.

Replies are listed 'Best First'.
Re: Re: Why does Perl use dynamic scoping?
by demerphq (Chancellor) on Feb 07, 2003 at 13:06 UTC
    Not sure what else you would choose to use it for if you could choose lexical scoping instead.

    Dunno. I like dynamic scoping. It has some interesting uses. How would do the same as below without it? (Im not saying it cant be done, just that it would be harder)

    our $Debug=0; # lots of subs that work sub doesnt_work_quite_right { local $Debug=1; # code that we are trying to debug }
    In order to do the same thing we would have to do that as
    my $Debug; sub doesnt_work_quite_right { my $olddebug=$Debug; $Debug=1; # code that we are trying to debug $Debug=$olddebug; }
    Which is both a PITA and far too reminiscent of debugging VBA for my taste.

    --- demerphq
    my friends call me, usually because I'm late....

      I have to agree with dmerphq here. I can't understand why something so useful gives so many people fits. It's like anything else, you use it where appropriate. dmerphq's code above might as well be mine. I have a global Debug package that provides a $Debug package variable. When I want localized debugging I use a local $Debug = N type declaration. The alternative, as pointed out, is to get/set/replace. I hated doing that with signal handlers in C. When coming to Perl I found it so much cleaner.

      How about temporarily overriding STDOUT, or one of the built-ins? For example, I routinely override line delimiters to process files from other systems. What would be the advantage of not being able to dynamically scope these sorts of overrides?

      I see that as a variation on levels of function calls. You want to know whether you are in the function call in question.

      But there are several ways to do the above. One crazy approach is to write a function set_debugging that replaces a function with a wrapped version that sets and unsets debugging as above. Take a look at the implementation of Memoize if you need hints on how to do that. Or for methods you can use Class::Contract and set pre and post conditions. Once written, using it is easy.

      Still this is a case where dynamic scope makes it simple and handles hard cases like unexpected interior exits - possibly from a die/eval pair.

        You want to know whether you are in the function call in question.

        Yeah I can see your point. But as you said most of the other ways are inconvient and inefficient, not to mention less flexible. For instance perlfunc:caller provides a way to determine if you have been called below a given sub, just walk the stack and see, but it would be slow and clumsy. Also in addition to your last point localization provides the benefit of applying to blocks and not just subs.

        As adrianh said, I dont want globals or dynamic scoping often, but when I want them I want them there. :-)

        Minor typographical changes were made to this node after it was posted.

        --- demerphq
        my friends call me, usually because I'm late....

      demerphq~

      If I recall correctly from my programming language class, what you are doing there is actually called fluid scoping.

      In a language without side effects, fluid and dynamic scoping are the same. However in a language with side effects, dynamic scope has the effect of treating all variables as globals. Thus fluid scoping with side effects into what is more commonly thought of as dynamic scoping in a language without them.

      Boots
      ---
      Computer science is merely the post-Turing decline of formal systems theory.
      --???
        I am at loss here. A google for "fluid scoping" finds only two matches, neither of which are on line right now. Can you explain what you mean?

        However in a language with side effects, dynamic scope has the effect of treating all variables as globals.

        First off, I dont grok "a language with side effects". I understand a "function with side effects" or "a function with no side effects" but I dont quite see how that can be applied to a language. And when I do, it seems logical to me to posit that "a language without side effects" doesn't do anything. Can you explain this idea to me?

        Why should dynamic scoping mandate only global variables? Presumably Perl is a language with side effects so how does that square with the observation that we have dynamic scoping of elements of lexical composite variables like hashes and arrays? Or is that still fluid scoping?

        Im interested to hear more about this.

        :-)

        Incidentally my understanding is that dynamic scoping was introduced to perl to aleviate the problems of only having globals. Not that some variables had to be global so that they could be dynamically scoped.

        --- demerphq
        my friends call me, usually because I'm late....

        I've only ever come across "fluid scoping" as a synonym for "dynamic scoping". Can you provide some refs and a bit more detail? My poor brain not understanding the distinction you are trying to draw:-)