develooper Front page | perl.perl6.language | Postings from May 2005

Re: Declaration and definition of state() vars

Thread Previous
From:
Larry Wall
Date:
May 5, 2005 11:25
Subject:
Re: Declaration and definition of state() vars
Message ID:
20050505182448.GA19211@wall.org
On Thu, May 05, 2005 at 07:50:31PM +0200, Ingo Blechschmidt wrote:
: Hi,
: 
:   sub gen() {
:     state $svar = 42;
:     # Only initialized once, as it is (per S04) equivalent to
:     #   state $svar will first{ 42 };
:     return { $svar++ };
:   }
: 
:   my $a = gen();    # $svar == 42
:   $a(); $a();       # $svar == 44
:   my $b = gen();    # $svar == 44
:   say $b();         # 44
:                     # $svar == 45
: 
: I presume that's correct.

Yes.  Though I'm not quite sure if we've nailed down whether the "will"
form will auto-assign or would instead have to be written

    state $svar will first { $_ = 42 }

I think the latter is probably correct.  However, you should be able
to write the non-closure form to auto-assign in any event:

    state $svar is first(42)

: Is the following correct, too?
: 
:   sub gen() {
:     (state $svar) = 42;
:     # Initialized on each invocation of &gen, as it is equivalent to
:     #   (state $svar will first{ undef }) = 42;
:     # I.e. $svar is only set to undef once (as $svar is a state
:     # variable), but it is set to 42 each time &gen is called. Correct?
:     return { $svar++ };
:   }
: 
:   my $a = gen();    # $svar == 42
:   $a(); $a();       # $svar == 44
:   my $b = gen();    # $svar == 42
:   say $b();         # 42
:                     # $svar == 43

Depends on whether assignment to a state variable is recognized in
syntactic analysis (where parens count) or semantic analysis (where they
don't).  You're taking the syntactic approach.  It can be argued that
the semantic approach is more robust, insofar as it makes all of
these equivalent:

    state $a = 1; state $b = 2;
    state ($a,$b) = (1,2);
    (state $a, state $b) = (1,2);

just as

    my $a = 1; my $b = 2;
    my ($a,$b) = (1,2);
    (my $a, my $b) = (1,2);

should all be equivalent.  On the other hand, don't ask me when

    (my $a, state $b) = (1,2);

should evaluate its RHS.  The semantic analyzer should probably throw
up its hands in disgust if it sees conflicting requirements for =.

Or we could make assignment policy depend on the outside of the parens
as you're doing.  In that case

    my ($a, state $b) = (1,2);

might initialize $b every time, while

    state ($a, my $b) = (1,2);

would only initialize $b the first time.  Hmm, then you could write

    state (my $first) = 1;

and $first would be true only the first time though.  Not sure if that's
terribly useful.  On the other hand,

    state (our $x) = 1;

would have the same effect as

    our $x is first(1);

That isn't terribly useful, but I think, for simplicity of analysis,
let's go ahead with your approach and just make the assignment timing
depend only on the declarator outside the parens.

So, yes.

Larry

Thread Previous


nntp.perl.org: Perl Programming lists via nntp and http.
Comments to Ask Bjørn Hansen at ask@perl.org | Group listing | About