Why I Don’t Like Perl State Variables

State variables work something like C static vars. It’s a forgivable feature in C, because C doesn’t have lexical scoping.

Here’s an example of Perl’s state variables, taken from Learning Perl, 6th Ed.:

This could be implemented with lexical scoping like this:

Is this uglier? Yes, absolutely it is. That extra indent level is not pretty at all. So what’s the advantage?

With lexical variables, you learn a general feature that’s applicable to a wide range of situations. It is something you ought to know in order to program in anything like Modern Perl. State variables, on the other hand, are applicable to a specific case. While I’m sure someone who encounters them regularly would be able to intuitively reason about them, it’s not obvious to the rest of us without sitting down and working it out for a while.

(And if you’re in the position of being able to intuitively reason about complex functions involving state variables, I wonder about the Bus Factor of your code.)

Website Pin Facebook Twitter Myspace Friendfeed Technorati del.icio.us Digg Google StumbleUpon Premium Responsive

Bookmark the permalink.

11 Responses to Why I Don’t Like Perl State Variables

  1. Felix says:

    One important think about your lexical variables. In a simple script you have to write first your function, then the function call … with state the order is not important. Ofc in .pm-Files it is not relevant.



    sub my_cool_funct {
    state = $sum = 0;


  2. png says:


    I think you’re right about preferring lexicals over state variables as a more general tool; however, I find state vars useful when I need to initialize a variable just once. State vars save me from writing some boilerplate code (check if $costly_variable is initialized, initialize if not, etc…) and that makes the function using them a bit shorter/simpler.

  3. Joe says:

    In studying Javascript, one of their claims is that having
    their first-class functions maintain state of variables, is useful. I’m glad the Perl people put that option in, you can always leave it out, no one is forcing anyone to “use State;” in their routines

  4. Quantum Mechanic says:

    You haven’t stated why you don’t like state variables, other than there’s an obscure alternative.

    One can also use state variables in the second example, as a way to limit sharing to nested blocks only. In fact, I can’t think of a difference between these, except if something starts poking under the hood into variable spaces. Replacing “my” with “state” in the second example seems to be equivalent. Both are lexical, and implicitly only executed once.


    I like the state version, as this allows the variable declaration to be closer to the first use. (Obviously, if some variable is shared across several blocks or subs, it can’t be declared close to every “first” use.)

    • Timm Murray says:

      Think about it from the standpoint of someone coming fresh into the language. Maybe they don’t even know about C static vars or similar concepts in other languages.

      You teach them about lexicals, and you’ve given them a powerful tool. You teach them about state vars, and you’ve given them a niche and sometimes confusing tool that could be implemented by other means.

      • Matthew King says:

        > you’ve given them a niche and sometimes confusing tool that could be implemented by other means.

        Like … perl?

  5. Joel Berger says:

    Using your same reasoning, I come to the opposite conclusion. I love ‘state’. Yes you need to know and love lexicals but state gives you one further benefit, privacy. state says “give me a lexical, defined in the outer scope, but not accessible in that scope”.

    The pattern you show in your example will work as long as you are sure to include those outer braces. This pattern is useful but state makes your meaning explicit.

  6. cfedde says:

    Sure all proramming constructs can be reduced to simpler forms. higher level constructs can be reduced to more general lower level ones. A decent CS course will show you how to do this all the way down to, machine instructions, Turing machines or lambda calculus. This would be absurd to do manually.

    Personally I like to use the highest level abstractions I’m comfortable with, and I strive to become comfortable with ever higher levels of abstraction that let me express my program in a clear and concise way.

    I use the static key word. I like that it lifts the level of abstraction just that little bit higher. It is through the levels of shared abstraction that I don’t have to implement my that a programming language gains utility.

  7. gh0stwizard says:


    In old times (few years ago) someone use this hack:


    use 5.010;

    sub oldstate_sum {
    if (0) {
    $sum = 0;

    foreach my $number ( @_ ) {
    push @numbers, $number;
    $sum += $number;

    say “The sum of (@numbers) is $sum”;

    oldstate_sum( 5, 6 ); # “The sum of (5 6) is 11”
    oldstate_sum( 1..3 ); # “The sum of (5 6 1 2 3) is 17”
    oldstate_sum( 4 ); # “The sum of (5 6 1 2 3 4) is 21”

  8. brian d foy says:

    You’ve made a serious mistake in your alternative. You have to ensure that the initialize code runs before you call the subroutine. That means that with your alternative, there can be no call to the subroutine until your block executes during the run phase.

    You could fix that with a BEGIN before the block so all of that code runs as it is parsed that the variables get the intended initial values.

Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.