Author: larry
Date: Mon Aug 14 17:53:44 2006
New Revision: 10942
Modified:
doc/trunk/design/syn/S04.pod
doc/trunk/design/syn/S06.pod
Log:
FIRST renamed to START. (FIRST now does loop initialization only.)
Minor cleanup of MAIN verbiage.
Modified: doc/trunk/design/syn/S04.pod
==
--- doc/trunk/design/syn/S04.pod(original)
+++ doc/trunk/design/syn/S04.podMon Aug 14 17:53:44 2006
@@ -615,26 +615,32 @@
called at various times, and some of them respond to various control
exceptions and exit values:
- BEGIN {...}* at compile time, ASAP
- CHECK {...}* at compile time, ALAP
- INIT {...}* at run time, ASAP
-END {...} at run time, ALAP
- FIRST {...}* at first block entry time
- ENTER {...}* at every block entry time
+ BEGIN {...}* at compile time, ASAP, only ever runs once
+ CHECK {...}* at compile time, ALAP, only ever runs once
+ INIT {...}* at run time, ASAP, only ever runs once
+END {...} at run time, ALAP, only ever runs once
+
+ START {...}* on first ever execution, once per closure clone
+
+ ENTER {...}* at every block entry time, repeats on loop blocks.
LEAVE {...} at every block exit time
- KEEP {...} at every successful block exit
- UNDO {...} at every unsuccessful block exit
- NEXT {...} at loop continuation time
- LAST {...} at loop termination time
-PRE {...} assert precondition at every block entry
- POST {...} assert postcondition at every block exit
- CATCH {...} catch exceptions
-CONTROL {...} catch control exceptions
+ KEEP {...} at every successful block exit, part of LEAVE queue
+ UNDO {...} at every unsuccessful block exit, part of LEAVE queue
+
+ FIRST {...}* at loop initialization time, before any ENTER
+ NEXT {...} at loop continuation time, after any LEAVE
+ LAST {...} at loop termination time, after any LEAVE
+
+PRE {...} assert precondition at every block entry, before any
+ POST {...} assert postcondition at every block exit, after any
+
+ CATCH {...} catch exceptions, before LEAVE
+CONTROL {...} catch control exceptions, before LEAVE
Those marked with a C* can also be used within an expression:
my $compiletime = BEGIN { localtime };
-our $temphandle = FIRST { maketemp() };
+our $temphandle = START { maketemp() };
Code that is generated at run time can still fire off CCHECK
and CINIT blocks, though of course those blocks can't do things that
@@ -644,25 +650,26 @@
These have the advantage of passing the variable in question into
the closure as its topic:
-my $r will first { .set_random_seed() };
+my $r will start { .set_random_seed() };
our $h will enter { .rememberit() } will undo { .forgetit() };
-Apart from CCATCH and CCONTROL, which can only occur once, most of
-these can occur multiple times within the block. So they aren't really
-traits, exactly--they add themselves onto a list stored in the
-actual trait. So if you examine the CENTER trait of a block, you'll
-find that it's really a list of closures rather than a single closure.
+Apart from CCATCH and CCONTROL, which can only occur once, most
+of these can occur multiple times within the block. So they aren't
+really traits, exactly--they add themselves onto a list stored in the
+actual trait (except for CSTART, which executes inline). So if you
+examine the CENTER trait of a block, you'll find that it's really
+a list of closures rather than a single closure.
-The semantics of CINIT and CFIRST are not equivalent to each
+The semantics of CINIT and CSTART are not equivalent to each
other in the case of cloned closures. An CINIT only runs once for
-all copies of a cloned closure. A CFIRST runs separately for each
+all copies of a cloned closure. A CSTART runs separately for each
clone, so separate clones can keep separate state variables:
our $i = 0;
...
-$func = { state $x will first{$i++}; dostuff($i) };
+$func = { state $x will start { $x = $i++ }; dostuff($i) };
-But Cstate automatically applies first semantics to any initializer,
+But Cstate automatically applies start semantics to any initializer,
so this also works:
$func = { state $x = $i++; dostuff($i) }
@@ -671,6 +678,12 @@
previous, and each clone maintains its own state of C$x, because that's
what Cstate variables do.
+Even in the absence of closure cloning, CINIT runs before the
+mainline code, while CSTART puts off the initialization till the
+last possible moment, then runs exactly once, and caches its value
+for all subsequent calls (assuming it wasn't called in void context,
+in which case the CSTART is evaluated once only for its side effects).
+
All of these trait