Why I Don't Like Perl State Variables
2013-12-16
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.:
use 5.010;
sub running_sum
{
state $sum = 0;
state @numbers;
foreach my $number ( @_ ) {
push @numbers, $number;
$sum += $number;
}
say "The sum of (@numbers) is $sum";
}
running_sum( 5, 6 ); # "The sum of (5 6) is 11"
running_sum( 1..3 ); # "The sum of (5 6 1 2 3) is 17"
running_sum( 4 ); # "The sum of (5 6 1 2 3 4) is 21"
This could be implemented with lexical scoping like this:
use strict;
{
my $sum = 0;
my @numbers;
sub running_sum
{
foreach my $number ( @_ ) {
push @numbers, $number;
$sum += $number;
}
print "The sum of (@numbers) is $sum\n";
}
}
running_sum( 5, 6 ); # "The sum of (5 6) is 11"
running_sum( 1..3 ); # "The sum of (5 6 1 2 3) is 17"
running_sum( 4 ); # "The sum of (5 6 1 2 3 4) is 21"
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.)