Re: Compile-time undefined sub detection
On Sat, Mar 13, 2004 at 08:39:02PM +0100, James Mastros wrote: : Larry Wall wrote: : And how would it differ from END? You can't predict when the last : time a module is going to get used... : : Unless we support an explicit unload action on modules. This seems : highly useful for long-running processes. (I don't think making them : DODable is useful, since there's no way to tell if a future eval STRING : (or equiv) might be useful.) Then the explicit unload can call an explicit routine in the module for cleanup, I suspect. We don't really need a special name for it in the language, except perhaps to set something up by convention. We might not even need that if we require an unloadable module to register its unloadability, in which case the module can pass a closure to be called back at unload time. Larry
Re: Compile-time undefined sub detection
On Mon, Mar 15, 2004 at 12:30:51PM -0800, Larry Wall wrote: : On Sat, Mar 13, 2004 at 08:39:02PM +0100, James Mastros wrote: : : Larry Wall wrote: : : And how would it differ from END? You can't predict when the last : : time a module is going to get used... : : : : Unless we support an explicit unload action on modules. This seems : : highly useful for long-running processes. (I don't think making them : : DODable is useful, since there's no way to tell if a future eval STRING : : (or equiv) might be useful.) : : Then the explicit unload can call an explicit routine in the module : for cleanup, I suspect. We don't really need a special name for it : in the language, except perhaps to set something up by convention. : We might not even need that if we require an unloadable module to : register its unloadability, in which case the module can pass a closure : to be called back at unload time. Okay, to be perfectly fair, that registration might then look exactly like a funny block: UNLOAD {...} Larry
Re: Compile-time undefined sub detection
At 12:30 PM -0800 3/15/04, Larry Wall wrote: On Sat, Mar 13, 2004 at 08:39:02PM +0100, James Mastros wrote: : Larry Wall wrote: : And how would it differ from END? You can't predict when the last : time a module is going to get used... : : Unless we support an explicit unload action on modules. This seems : highly useful for long-running processes. (I don't think making them : DODable is useful, since there's no way to tell if a future eval STRING : (or equiv) might be useful.) Then the explicit unload can call an explicit routine in the module for cleanup, I suspect. That's going to be the only way to reasonably unload a module, and even then there'll be some interesting repercussions. Like... what happens when you unload a module with instantiated objects? How can you tell if there are secondary modules that need unloading? Does unloading actually unload, or just remove as many links to the module as we can and we then unload it when the last real reference to it goes away? Can we *re*load a module that's been unloaded? (The answer to that last one's no, for some modules that load in external libraries) It's an interesting problem. Modules leave debris around which can make it difficult to properly deal with, and allowing them to be unloaded requires a fair amount of thought. -- Dan --it's like this--- Dan Sugalski even samurai [EMAIL PROTECTED] have teddy bears and even teddy bears get drunk
Re: Compile-time undefined sub detection
On Mon, Mar 15, 2004 at 04:22:27PM -0500, Dan Sugalski wrote: : That's going to be the only way to reasonably unload a module, and : even then there'll be some interesting repercussions. Like... what : happens when you unload a module with instantiated objects? How can : you tell if there are secondary modules that need unloading? Does : unloading actually unload, or just remove as many links to the module : as we can and we then unload it when the last real reference to it : goes away? Can we *re*load a module that's been unloaded? (The answer : to that last one's no, for some modules that load in external : libraries) : : It's an interesting problem. Modules leave debris around which can : make it difficult to properly deal with, and allowing them to be : unloaded requires a fair amount of thought. Which is all good reason to assume a module is not unloadable unless it declares its intent to be unloadable--and then it's just on a best effort basis. Best effort is one of those phrases that doesn't mean what it means... Larry
Re: Compile-time undefined sub detection
Larry Wall wrote: And how would it differ from END? You can't predict when the last time a module is going to get used... Unless we support an explicit unload action on modules. This seems highly useful for long-running processes. (I don't think making them DODable is useful, since there's no way to tell if a future eval STRING (or equiv) might be useful.) -=- James Mastros
Re: Magic blocks (was: Compile-time undefined sub detection)
- Original Message - From: Larry Wall [EMAIL PROTECTED] To: [EMAIL PROTECTED] Sent: Saturday, March 06, 2004 10:39 PM Subject: Re: Magic blocks (was: Compile-time undefined sub detection) Oh, I accidentally left NEXT out of my canonical list. We do need to have the equivalent to Perl 5's continue. Will there be a corresponding 'will next' property on variables? If so, then this could be a very nice way to solve the problem of how to access the 'prior' element in a for loop: for @array - $current { state $prior will next {$prior := $current} will leave {$prior := undef}; ... } $prior is a state variable so that it retains its value between iterations of the loop. The 'will next' property binds $prior to $current just before the loop binds $current to the next element of @array; the result is that in every iteration of the loop after the first $prior is bound to the same element of @array that $current was bound to in the previous iteration. The 'will leave' property ensures that we don't keep a reference to an element of @array after we leave the loop; it also ensures that $prior has the correct value of undef() when we start the loop the next time. Joe Gottman
Re: Magic blocks (was: Compile-time undefined sub detection)
On Sat, Mar 06, 2004 at 06:39:44PM -0800, Larry Wall wrote: my @x will begin {...} # at BEGIN time my @x will check {...} # at CHECK time (redefined to unit check) my @x will init {...} # at INIT time my @x will end {...}# at END time Sorry, perhaps I wasn't paying close enough attention, but suddenly we've leaped from oddly named subs that get called at interesting times, to array variables with oddly-named properties (or attributes, or whatever). Je ne comprend pas :-(. Dave. -- A walk of a thousand miles begins with a single step... then continues for another 1,999,999 or so.
Re: Magic blocks (was: Compile-time undefined sub detection)
On Mon, Mar 08, 2004 at 11:57:04PM +, Dave Mitchell wrote: : On Sat, Mar 06, 2004 at 06:39:44PM -0800, Larry Wall wrote: : my @x will begin {...} # at BEGIN time : my @x will check {...} # at CHECK time (redefined to unit check) : my @x will init {...} # at INIT time : my @x will end {...}# at END time : : Sorry, perhaps I wasn't paying close enough attention, but suddenly we've : leaped from oddly named subs that get called at interesting times, to : array variables with oddly-named properties (or attributes, or whatever). : Je ne comprend pas :-(. Oddly named subs are cool as such, but there are times when you don't so much want an oddly named sub as an oddly named method. These are just oddly named methods on the container in question (which certainly doesn't have to be an array). Underneath they're still oddly named subs in terms of when they run. But they implicitly get (as their first argument/invocant/topic) the container in question, so they can do fancy things with $_ and .foo and Cwhen and such. The will first syntax is mentioned in A6. Plus we discussed it last April with respect to state variables--see message below. Larry From [EMAIL PROTECTED] Tue Apr 15 11:56:23 2003 Date: Tue, 15 Apr 2003 11:19:42 -0700 From: Larry Wall [EMAIL PROTECTED] Subject: Re: Initializations outside of control flow To: [EMAIL PROTECTED] On Tue, Apr 15, 2003 at 10:34:35AM -0400, Mark J. Reed wrote: : It just seems like there should be a way to accomplish that without : the visual clutter. Perhaps a trait: : : my $count is initially($INITIAL_VALUE); : : If there's already a defined way of doing that in Perl 6, please : point me at it and I'll go away chastened but happy. Otherwise, : does this seem a reasonable approach? Ideas for a better name for : the trait? The traits in question are already named corresponding to the various initialization closures, which at the moment are named BEGIN {...} CHECK {...} INIT {...} FIRST {...} ENTER {...} so, since the variable in question is the topic of the closure, we have my $count will begin { .set($INITIAL_VALUE) } my $count will check { .set($INITIAL_VALUE) } my $count will init { .set($INITIAL_VALUE) } my $count will first { .set($INITIAL_VALUE) } my $count will enter { .set($INITIAL_VALUE) } Perhaps those particular traits are smart enough to distinguish whether they have a closure or not, and build an appropriate closure if not, so we could also have my $count is begin($INITIAL_VALUE) my $count is check($INITIAL_VALUE) my $count is init($INITIAL_VALUE) my $count is first($INITIAL_VALUE) my $count is enter($INITIAL_VALUE) At the moment, I believe that = always happens at run-time. So my $count = BEGIN { calculation() } would do the calculation at compile time but assign the resulting value every time the statement is executed. This means that a declaration like: state $where = $x; is almost certainly incorrect. It should probably be one of state $where is begin($x); state $where is check($x); state $where is init($x); state $where is first($x); Could go so far as to lose the is, treating these as variants of is. state $where begin($x); state $where check($x); state $where init($x); state $where first($x); The other possible approach would be to allow blockless closures like BEGIN (state $where = $x); CHECK (state $where = $x); INIT (state $where = $x); FIRST (state $where = $x); Maybe the parens aren't necessary, if they just introduce a syntactic statement: BEGIN state $where = $x; CHECK state $where = $x; INIT state $where = $x; FIRST state $where = $x; But I think it would be a mistake to have = running at random times depending on either the foo and BAR in foo $x = BAR { ... } Larry
Re: Compile-time undefined sub detection
At 8:47 AM +1100 3/6/04, Damian Conway wrote: Larry wrote: Anybody got opinions on the naming of these beasts? Certainly *not* renaming CHECK is more compatible with Perl 5. I'd favour UNITCHECK and CHECK, mainly for the greater compatibility with Perl 5 and with software engineering jargon. How 'bout we make these properties on the subs instead of custom sub names? There are some times when its useful to have a sub callable by name as well as at a specified time in the startup sequence. (Which is what parrot'll be doing *anyway*--BEGIN blocks will be subs with bogus names with the :begin property on them, or something like that) -- Dan --it's like this--- Dan Sugalski even samurai [EMAIL PROTECTED] have teddy bears and even teddy bears get drunk
Re: Compile-time undefined sub detection
Austin Hastings writes: Perhaps this is one of those places where properties can help. Instead of having BEFORE, REALLY_BEFORE, NO_I_MEAN_REALLY_BEFORE, DONE, MOSTLY_DONE, PARTIALLY_DONE, WELL_DONE, DONE_AND_PROCESS_SPACE_ALMOST_RECLAIMED, etc., we could simply use some ordering properties: # Each broad class of upcased block is an execution group. The entries # in each execution group are not guaranteed to run in any particular order, # and in fact may run in parallel on a multithreaded perl. Would you guys cut that out! Nothing's running in parallel unless I tell it to! Or peraps, Nothing's running in parallel if I tell it not to! In either case, it could be an easy, global pragma overridable locally[1]. If I'm printing debug messages during compilation, say: BEGIN { print Before load\n; } use SomePackage; BEGIN { print After load\n; } I don't want to be getting: BefAfter load ore load Obviously this is a pathological case, due to the restriction immediately below, but you can extrapolate to more complex things. # However, blocks in the same source file are guaranteed to run in order of # occurrence. (Since they're catenated, basically.) # # Thus, all BEGIN blocks in a file are effectively catenated and added to # an overall BEGIN execution group. All the separate BEGIN entries have # the same initial priority(10), so they will run in whatever order suits # the P6 runtime. # # The Cgo property introduces changes to the execution group and/or # priority of the block in question. (Note that different priorities may # be attached to different blocks within the same file. Doing so creates # separate execution bundles, and breaks any guarantees about order of # execution.) # package OtherPackage; BEGIN will go first { print first!; } And what's with all the weird notation? Perl 6 naturally supports this without adding new syntax: BEGIN :first {...} BEGIN :priority(5) {...} I trust that these pairs will be somehow moved into their pair position after the block by Perl, since named args have to come after positional args. There are a lot of functions that take blocks, and writing: BEGIN { print I am here: [ ; print( @data == map { .join(',') } == join ';'); print ]\n; } :first; Seems to horribly violate end weight. package SomePackage; BEGIN will go after OtherPackage::BEGIN { print Second!; } END will go priority 5 { print End block with early priority; } package ThirdPackage; END will go group BEGIN before SomePackage::BEGIN { print I feel really out of place!; } Comment? As far as the execution groups, no, I don't think so. In particular, because I want: use SomePackage; BEGIN { SomePackage::foo(); } to work without doing some unnecessarily verbose encantation on that BEGIN. On the other hand, using a flag to indicate that you want a particular END to be [one of] the very last may be the right way to go. It's uncommon enough that the people who need it will be more than willing to look it up. Luke [1] And that's really just to make those happy who are efficiency-crazy. I have a strong aversion to automatic threading, and I don't care if it takes more than one line to put it in. In any case, I want control of my threads, otherwise my sweatshirt's going to come out raveled.
RE: Compile-time undefined sub detection
-Original Message- From: Luke Palmer [mailto:[EMAIL PROTECTED] Austin Hastings writes: # Each broad class of upcased block is an execution group. The entries # in each execution group are not guaranteed to run in any particular order, # and in fact may run in parallel on a multithreaded perl. Would you guys cut that out! Nothing's running in parallel unless I tell it to! Or peraps, Nothing's running in parallel if I tell it not to! In either case, it could be an easy, global pragma overridable locally[1]. True. But in a potentially-parallel environment, it's good to specify expected behavior. In this case, the expected behavior is such that if I say perl6 -P (or --parallel) myscript.p6 I know what the result will be, because the nice man on p6language specified it. And if that never happens, well, the spec didn't hurt anyone. # Thus, all BEGIN blocks in a file are effectively catenated and added to # an overall BEGIN execution group. All the separate BEGIN entries have # the same initial priority(10), so they will run in whatever order suits # the P6 runtime. # # The Cgo property introduces changes to the execution group and/or # priority of the block in question. (Note that different priorities may # be attached to different blocks within the same file. Doing so creates # separate execution bundles, and breaks any guarantees about order of # execution.) # package OtherPackage; BEGIN will go first { print first!; } And what's with all the weird notation? Perl 6 naturally supports this without adding new syntax: BEGIN :first {...} BEGIN :priority(5) {...} That's why we pay you, Luke -- to keep up with the syntax. :-) (Actually, Outlook seems to have transmogrified my guillemets into angle brackets. I find that quite frustrating -- I think I'd rather have them appear to everyone else as Korean spam than as incorrect ascii. So much for Office ServicePack 3...) I trust that these pairs will be somehow moved into their pair position after the block by Perl, since named args have to come after positional args. There are a lot of functions that take blocks, and writing: BEGIN { print I am here: [ ; print( @data == map { .join(',') } == join ';'); print ]\n; } :first; Seems to horribly violate end weight. Ayup. package SomePackage; BEGIN will go after OtherPackage::BEGIN { print Second!; } END will go priority 5 { print End block with early priority; } package ThirdPackage; END will go group BEGIN before SomePackage::BEGIN { print I feel really out of place!; } Comment? As far as the execution groups, no, I don't think so. In particular, because I want: use SomePackage; BEGIN { SomePackage::foo(); } to work without doing some unnecessarily verbose encantation on that BEGIN. Who says you need verbosity? The default behavior will dwym, natch. The execution grouping and prioritization and other stuff, which those-who-live-in-compiler-land understand better than I ever hope to, are where the verbosity goes. If you want after p6 reads the end of file but before the final reduction, well, there's an execution group for that. And if you want after the reduction but before peephole optimization, you're in luck. And if you want I'm not sure when, but it should be just before the BEGIN block from this other module, we can do that, too. And there's not an entire page of uppercase names that I have to thumbtack to my cubicle wall, since I can never remember this crap. Instead, we stay with BEGIN and END for compiler-phase stuff, and then immediately switch to better ways of thinking about this stuff, like at object instantiation, at destruction, which are actually data-related. On the other hand, using a flag to indicate that you want a particular END to be [one of] the very last may be the right way to go. It's uncommon enough that the people who need it will be more than willing to look it up. My thought, exactly. Luke =Austin
Magic blocks (was: Compile-time undefined sub detection)
Okay you guys, you're running away from one kind of madness and proposing various other kinds of madness in its place. Mostly you're confusing what should be easy and what should be possible. First a note about cleanup dependencies. In general, these should be driven by the structure of the data, not the structure of the program. If you want to make sure one piece of data is cleaned up before another, make sure there's a reference that enforces that. That's the principle on cleanup. It's also, more or less, the principle on initialization. What these various blocks are obscuring from your calculations is that there is a data structure for each of these sets of queued events, and as long as there's a way to name such a queue, it's not necessary to access it through the official block name. It would be nice if the property that stores a particular queue has a related name, of course. But for fancy things, we don't have to add options to the syntax of blocks in order to manipulate these queues. If you want to make sure you're last in the END queue, just manipulate that queue. We also don't need a new abstraction like execution group, unless by that you simply mean one of these callback queues. We particularly don't need to orthogonalize all the names and make them equally obfuscational. This is very much a place where easy things should be easy, and hard things should be difficult. So here's the ruling. We don't need any special names for hacking on the queue in another module. So CHECK means UNITCHECK, always. There's no MAINCHECK name. If you want to do something fancy to the main program's CHECK list or END list, then at export time, modify the queue contained in Main's CHECKLIST property or ENDLIST property. If you really, really, really, want something to run last, then install something into Main::ENDLIST that looks to see whether there's anything after it when it gets triggered, and if so, reinstalls itself at the end again. And then we can have the entertaining situation of two or more modules both playing leapfrog trying to be last. Perhaps something fancy with priorities can be worked out, but if so, that's the domain of direct queue manipulation routines. It has nothing to do with the easy-to-use block declarations, which have to remain simple interfaces, or there's no point to them. So we're back to the standard four phase oriented blocks: my @x will begin {...} # at BEGIN time my @x will check {...} # at CHECK time (redefined to unit check) my @x will init {...} # at INIT time my @x will end {...}# at END time plus these four block oriented blocks: my @x will pre {...}# at PRE time (return boolean for DBC) my @x will enter {...} # at ENTER time (block entry) my @x will leave {...} # at LEAVE time (block exit) my @x will post {...} # at POST time (return boolean for DBC) plus three specialty times for things with lifetimes not related to blocks: state @x will first {...} # at FIRST time (first time through) has @.x will build {...}# at BUILD time (object init time) has @.x will destroy {...} # at DESTROY time (object final time) There's no LAST corresponding to FIRST because you can't generally tell when you've called a block for the very last time. (If there is a LAST, it'd be loop related, but then FIRST and LAST aren't really opposites, and it'd duplicate LEAVE anyway.) Oh, and I guess we still have the two leave variants: my @x will keep {...} # at LEAVE time, if leaving successfully my @x will undo {...} # at LEAVE time, if leaving unsuccessfully There's also, in a sense, a catch time, but you can't have more than one of those, so there's no CATCHLIST property to modify. If you're trying to add semantics to your CATCH, you're probably wanting an undo instead. A good case can be made for all of those--unless you happen to be against transactional programming, or design by contract. Or state variables, or objects, or blocks, or modules... :-) Larry
Re: Magic blocks (was: Compile-time undefined sub detection)
Oh, I accidentally left NEXT out of my canonical list. We do need to have the equivalent to Perl 5's continue. Larry
Re: Compile-time undefined sub detection
On Thu, Mar 04, 2004 at 11:04:38PM +, Nigel Sandever wrote: : On the basis of what is known so far, will p6 be able to detect : undefined subs at compile time? In theory, yes, if you ask it to check in a CHECK block, and if you're willing for the check to assume that no eval or INIT block is going to supply the missing sub before it's actually called, and that no run-time code is going to alias the sub into one of your namespaces where it'll be visible to call, and that no AUTOLOAD in scope will be willing to emulate it. (But then, all that's true of Perl 5 right now as well...) Larry
Re: Compile-time undefined sub detection
Larry Wall wrote in perl.perl6.language : In theory, yes, if you ask it to check in a CHECK block, and if you're willing for the check to assume that no eval or INIT block is going to supply the missing sub before it's actually called, and that no run-time code is going to alias the sub into one of your namespaces where it'll be visible to call, and that no AUTOLOAD in scope will be willing to emulate it. (But then, all that's true of Perl 5 right now as well...) While we're at it. Is there some precise definition of the CHECK/INIT blocks for perl 6 right now ? In perl 5 those blocks are executed at the transition between the compilation and the execution phase *of the main program*. This is convenient for some purposes (the O and B::* modules) and inconvient for others (Attribute::Handlers, etc. etc.). It's not feasible to modify this for Backwards Compatibility Reasons; how will Perl 6 handle this ? is there going to be a CHECK-by-compilation-unit kind of block ?
Re: Compile-time undefined sub detection
On Fri, Mar 05, 2004 at 01:57:40PM -, Rafael Garcia-Suarez wrote: : While we're at it. Is there some precise definition of the CHECK/INIT : blocks for perl 6 right now ? Yes, the same precise definition as anything else we haven't defined yet: That works exactly the same as in Perl 5, until we change our minds. :-) : In perl 5 those blocks are executed at the : transition between the compilation and the execution phase *of the main : program*. This is convenient for some purposes (the O and B::* modules) : and inconvient for others (Attribute::Handlers, etc. etc.). Hmm, well, I think it's a problem with Attribute::Handlers only because that interface binds too late by default. Perl 6 traits will run at BEGIN time by default. (Though you can define actions at trait time that don't run till a later phase.) Can you elaborate on the etc. etc.? : It's not : feasible to modify this for Backwards Compatibility Reasons; how will : Perl 6 handle this ? is there going to be a CHECK-by-compilation-unit : kind of block ? The link phase is still controlled by the main compilation pulling in other modules, so CHECK still has the same semantics for the main program, at least. And for consistency (especially with Perl 5), a CHECK block from a separately compiled module probably should wait till end of link time to run. Particularly since we have modules that specifically create a CHECK knowing it runs at the end of the main compilation. So if we divide the CHECK notion up, you are correct that it's the end-of-the-compilation-unit check that needs a new name. That might be convenient, though redundant, since you can always run something at the end of the compilation by putting a BEGIN block down at the bottom. That BEGIN wouldn't know that it's the last thing, and can't guarantee that it's the last thing if someone inserts more code after it, but that doesn't stop you from putting stuff into the BEGIN block that knows it's the last thing, and putting a comment afterwards saying # Put no code here. Put it before the preceding BEGIN On the other hand, there are things that the compiler probably has to think about at the end of the compilation unit, and you might want to do something after that. For example, given the way that subs can forward-ref a declaration they haven't seen yet, we might want to figure out at that time what signature to apply to a mysterious call like: foo(@bar, @baz) So your final BEGIN would be ignorant of that decision unless it had some way to force it. But if we're going to provide an interface to let BEGIN tell the compiler to finish up, that's just as complicated as providing a different kind of block that lets the compiler finish up explicitly. So I guess the question boils down to, what shall we name it? UNBEGIN POSTCOMP PRELINK COMPCHECK UNITCHECK Actually, I could see an argument for REDUCE, which runs after the current block is reduced in the grammar. Which, if put at file-scope level, comes out to running after the file is reduced, kinda sorta, though to get the right semantics we'd have to consider not just the grammatical reduction, but all the action routines triggered as part of the reduction. So that might also give us a way to capture control after a sub is compiled, for instance. Or at least, its closure block... Hmm. BEGIN blocks work fine for that, probably better, since the reduction of the entire sub can happen, not just the block associated with the sub. So nevermind about REDUCE. It seems to be an ill-formed notion, since multiple reductions happen before your entire sub is defined. Which takes us back to something like UNITCHECK. Let's see: my @x will unitcheck { .stuff() }; I guess that works as a verb. So unless someone talks me out of it, we now have my @x will begin {...} # at BEGIN time my @x will unitcheck {...} # at UNITCHECK time my @x will check {...} # at CHECK time my @x will init {...} # at INIT time my @x will pre {...}# at PRE time (return boolean for DBC) my @x will enter {...} # at ENTER time (block entry) my @x will leave {...} # at LEAVE time (block exit) my @x will post {...} # at POST time (return boolean for DBC) my @x will end {...}# at END time state @x will first {...} # at FIRST time (first time through) has @.x will build {...}# at BUILD time (object init time) But most of you don't officially know about that last one yet. Few more days... :-) Larry
Re: Compile-time undefined sub detection
Larry Wall wrote in perl.perl6.language : : In perl 5 those blocks are executed at the : transition between the compilation and the execution phase *of the main : program*. This is convenient for some purposes (the O and B::* modules) : and inconvient for others (Attribute::Handlers, etc. etc.). Hmm, well, I think it's a problem with Attribute::Handlers only because that interface binds too late by default. Perl 6 traits will run at BEGIN time by default. (Though you can define actions at trait time that don't run till a later phase.) Can you elaborate on the etc. etc.? Of course :) the main problem is not that CHECK blocks are executed late (just at the end of the compilation phase); it's that they're executed too early, notably in some persistent environment, notably mod_perl (or mod_parrot in the future.) When you have a virtual machine, you'll end up including modules at run time, because the main compilation phase becomes less important. Thus CHECK blocks become worthless, code-reusability-wise. The link phase is still controlled by the main compilation pulling in other modules, so CHECK still has the same semantics for the main program, at least. And for consistency (especially with Perl 5), a CHECK block from a separately compiled module probably should wait till end of link time to run. Particularly since we have modules that specifically create a CHECK knowing it runs at the end of the main compilation. But, as I was saying, modules have no control on what the end of the compilation is; notably, they've no control on whether it's still finished. my @x will unitcheck {...}# at UNITCHECK time your next mission is now to put something like this in Perl 5...
Re: Compile-time undefined sub detection
On Fri, Mar 05, 2004 at 06:45:58PM -, Rafael Garcia-Suarez wrote: : Of course :) the main problem is not that CHECK blocks are executed : late (just at the end of the compilation phase); it's that they're : executed too early, notably in some persistent environment, notably : mod_perl (or mod_parrot in the future.) When you have a virtual machine, : you'll end up including modules at run time, because the main : compilation phase becomes less important. Thus CHECK blocks become : worthless, code-reusability-wise. Possibly a CHECK block that is compiled after end of main compilation should translate itself to a UNITCHECK. But maybe it should be an error. But it's also possible that CHECK should mean unit check, and there should be an explicit MAINCHECK for delegating checks to the main compilation. In that case, only in the main compilation would CHECK and MAINCHECK mean the same thing. (And since MAINCHECK is explicitly requesting a check at the end of main, a late MAINCHECK should probably be considered an error. (But by that argument, a late CHECK should probably fail under the current naming scheme.)) Anybody got opinions on the naming of these beasts? Certainly *not* renaming CHECK is more compatible with Perl 5. And I kinda got fond of UNITCHECK in the last hour or so. :-) Larry
Re: Compile-time undefined sub detection
Larry Wall wrote in perl.perl6.language : Possibly a CHECK block that is compiled after end of main compilation should translate itself to a UNITCHECK. But maybe it should be an error. But it's also possible that CHECK should mean unit check, and there should be an explicit MAINCHECK for delegating checks to the main compilation. In that case, only in the main compilation would CHECK and MAINCHECK mean the same thing. (And since MAINCHECK is explicitly requesting a check at the end of main, a late MAINCHECK should probably be considered an error. (But by that argument, a late CHECK should probably fail under the current naming scheme.)) Anybody got opinions on the naming of these beasts? Certainly *not* renaming CHECK is more compatible with Perl 5. And I kinda got fond of UNITCHECK in the last hour or so. :-) I think I like CHECK and MAINCHECK. (and MAINCHECK being an error after the main compilation phase.) Lots of people who use CHECK (for some value of lots -- let's say, Damian and a few others) actually mean UNITCHECK. MAINCHECK is mainly useful for the O compiler backend, which is part of the perl core anyway, thus without any backward-compatility constraint. (I'd like to have opinions about PAR as well.) So I think changing the meaning of CHECK in Perl 5 is feasible. (and I know it would be welcomed by the mod_perl crowd.)
Re: Compile-time undefined sub detection
Larry wrote: Anybody got opinions on the naming of these beasts? Certainly *not* renaming CHECK is more compatible with Perl 5. I'd favour UNITCHECK and CHECK, mainly for the greater compatibility with Perl 5 and with software engineering jargon. And because MAINCHECK is *ugly*. ;-) So ugly that, if we go the other way and do change CHECK's behaviour, then the new postlinkage phase should be something else: like POSTLINK or PREINIT or INTEGRATE. And I kinda got fond of UNITCHECK in the last hour or so. :-) Well, that counts in its favour too. ;-) Does that imply a UNITEND as well? Damian
Re: Compile-time undefined sub detection
On Sat, Mar 06, 2004 at 08:47:25AM +1100, Damian Conway wrote: : Does that imply a UNITEND as well? Why would you want to unite North Dakota? And how would it differ from END? You can't predict when the last time a module is going to get used... Larry
Re: Compile-time undefined sub detection
Damian Conway wrote in perl.perl6.language : I'd favour UNITCHECK and CHECK, mainly for the greater compatibility with Perl 5 and with software engineering jargon. As far as Perl 5 is concerned, it appears that most people who write CHECK mean UNITCHECK. Including you :) And because MAINCHECK is *ugly*. ;-) I can't disagree. So ugly that, if we go the other way and do change CHECK's behaviour, then the new postlinkage phase should be something else: like POSTLINK or PREINIT or INTEGRATE. But INTEGRATE is even more ugly.
Re: Compile-time undefined sub detection
Larry asked: And how would it differ from END? Like CHECKs, ENDs execute in reverse order. Which generally means that main END executes before module ENDs (unless we're careful to put our main END before our module loads -- which is subtle and counterintuitive). Sometimes it would be handy to be able to mark some cleanup code so that it executes before main's END, regardless of how early main's END is declared. You can't predict when the last time a module is going to get used... I'm not suggesting you need to. I'm saying that, just as all UNITCHECKs are guaranteed to run before any main CHECK, we might want a UNITEND that's guaranteed to execute before any main END. Damian
Re: Compile-time undefined sub detection
On Fri, Mar 05, 2004 at 04:17:12PM -0600, Rod Adams wrote: Given the fact that use of these blocks are overall quite rare, and potentially very confusing to the casual perl hacker who encounters one of them, I propose a rather different tact: BEGIN = EXECUTE_ON_PARSE CHECK = EXECUTE_AFTER_COMPILE and EXECUTE_AFTER_UNIT_COMPILE INIT = EXECUTE_INITIALIZATION END = EXECUTE_ON_EXIT This also has the advantage of being able to reserve all subs with name EXECUTE_.* for compiler/interpreter special sub like these, so we could add more of them come perl 6.8 w/o much issue. I'm not sure I agree with your actual proposal, but I certainly agree with the spirit of it. When I first saw UNITEND I had to double take to make sure I read it correctly. I propose that if we use multi-word block names, that they have an underscore between the words to be slightly more readable. (I hate underscores, but I hate LONGCAPSWORDS more) -Scott -- Jonathan Scott Duff Division of Nearshore Research [EMAIL PROTECTED] Senior Systems Analyst II
RE: Compile-time undefined sub detection
You can't predict when the last time a module is going to get used... I'm not suggesting you need to. I'm saying that, just as all UNITCHECKs are guaranteed to run before any main CHECK, we might want a UNITEND that's guaranteed to execute before any main END. Perhaps this is one of those places where properties can help. Instead of having BEFORE, REALLY_BEFORE, NO_I_MEAN_REALLY_BEFORE, DONE, MOSTLY_DONE, PARTIALLY_DONE, WELL_DONE, DONE_AND_PROCESS_SPACE_ALMOST_RECLAIMED, etc., we could simply use some ordering properties: # Each broad class of upcased block is an execution group. The entries # in each execution group are not guaranteed to run in any particular order, # and in fact may run in parallel on a multithreaded perl. # # However, blocks in the same source file are guaranteed to run in order of # occurrence. (Since they're catenated, basically.) # # Thus, all BEGIN blocks in a file are effectively catenated and added to # an overall BEGIN execution group. All the separate BEGIN entries have # the same initial priority(10), so they will run in whatever order suits # the P6 runtime. # # The Cgo property introduces changes to the execution group and/or # priority of the block in question. (Note that different priorities may # be attached to different blocks within the same file. Doing so creates # separate execution bundles, and breaks any guarantees about order of # execution.) # package OtherPackage; BEGIN will go first { print first!; } package SomePackage; BEGIN will go after OtherPackage::BEGIN { print Second!; } END will go priority 5 { print End block with early priority; } package ThirdPackage; END will go group BEGIN before SomePackage::BEGIN { print I feel really out of place!; } Comment? =Austin