It seems to me that the majority of recommended programming practices here on PM involve avoiding dynamic scoping as much as possible. Examples: I've tried to think of situations when dynamic scoping turns out to be convenient. Here's what I've come up with: It dawned on me that the problems addressed well by dynamic scoping involve only subroutines (including method calls). I don't see any other big problems addressed that can't be dealt with lexically. I don't pretend to know a lot about language design, so I may be missing something obvious here. Anyway, after thinking about this for a while I concluded, why not just make subroutine/method calls dynamically scoped and force everything else lexical?

Perhaps the answer is just as simple as "Perl shouldn't force anything, even our scoping preferences." But I want to know what you all think. Also, is dynamic scoping still hanging around just for posterity? Is Perl moving away from dynamic scoping?

Thanks,
blokhead

Replies are listed 'Best First'.
Re: Why does Perl use dynamic scoping?
by rob_au (Abbot) on Feb 07, 2003 at 10:27 UTC
    Perhaps the answer is just as simple as "Perl shouldn't force anything, even our scoping preferences."

    Quoting Larry (and Randal) from Programming Perl - "In accordance with UNIX philosophy, Perl gives you enough rope to hang yourself".

    I think that explains it nicely :-)

     

    perl -le 'print+unpack("N",pack("B32","00000000000000000000001000101100"))'

Re: Why does Perl use dynamic scoping?
by Juerd (Abbot) on Feb 07, 2003 at 06:47 UTC
Re: Why does Perl use dynamic scoping?
by bsb (Priest) on Feb 07, 2003 at 07:39 UTC
    Lexical scoping generally needs declarations to work.

    Just taking the first use of a variable may not be what the coder intends and Larry (in an Apocalpse, if I recall correctly) couldn't find a good heuristic to intuit the intended lexical scope. So you'll end up having to declare your lexicals even in Perl 6.

    So for quick and nasty scripts, one-liners and the like, we are left with symbol tabled, dynamically scoped variables. There's no safety but you're less likely to need it.

Re: Why does Perl use dynamic scoping?
by Anonymous Monk on Feb 07, 2003 at 03:00 UTC
    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.

      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.

        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.
        --???
Re: Why does Perl use dynamic scoping?
by adrianh (Chancellor) on Feb 07, 2003 at 22:28 UTC
    Also, is dynamic scoping still hanging around just for posterity? Is Perl moving away from dynamic scoping?

    "No" and "No" in my opinion :-)

    I don't need dynamic scoping often, but when I do I want it there ready and waiting.

    I think many of the perceived problems with dynamic scope and perl are due to the fact that it was around before lexical variables - so people had to be re-educated to use lexicals where appropriate.

    Removing dynamic scope because some people misuse it where lexicals would be more appropriate would be like removing map because some people misuse it in a void context instead of foreach :-)

    Other languages allow you to do even more with dynamic scoping. For example Pop-11's dlocal statement allows you to dynamically scope arbritary expressions as well as variables. For example (taken from Pop-11 docs):

    ;;; make a three element list vars list =[1 2 3]; define test(); ;;; dynamically scope the second element dlocal %hd(tl(list))%; [original list ^list]=> ;;; update second element 5 -> hd(tl(list)); [updated list ^list] => enddefine; test(); ** [original list [1 2 3]] ** [updated list [1 5 3]] ;;; But the value of hd(tl(list)) has been restored on exit: list => ** [1 2 3]

    (Yes, I know you can use tie in perl to bind functionality to dynamic scoping - but it's not simple).

    In Pop-11 you can even dynamically scope lexicals if you want.

    Personally I hope that perl6 will take dynamic scoping to new levels rather than taking it away.

    Anyway - the point I'm trying to make is that dynamic scope can be a useful and powerful feature. Just because some people misuse it isn't a reason for it to be removed.

Re: Why does Perl use dynamic scoping?
by dmitri (Priest) on Feb 07, 2003 at 23:48 UTC
    The view that dynamic scoping is a bad idea (™) is similar to the view that goto is bad in C programming. However, there are situations when goto is a natural way to solve a coding problem (just recently I have used one).

    Dynamic variables are there to be used. In my opinion is, all language features should be used when appropriate. After all, we adapt language syntax to our coding preferences, and not the other way around. People who disagree with this assumption use Python :).