Re: Compile-time undefined sub detection

2004-03-15 Thread Larry Wall
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

2004-03-15 Thread Larry Wall
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

2004-03-15 Thread Dan Sugalski
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

2004-03-15 Thread Larry Wall
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: Magic blocks (was: Compile-time undefined sub detection)

2004-03-08 Thread Dave Mitchell
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)

2004-03-08 Thread Larry Wall
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

2004-03-07 Thread Dan Sugalski
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

2004-03-06 Thread Luke Palmer
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

2004-03-06 Thread Austin Hastings


 -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)

2004-03-06 Thread Larry Wall
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)

2004-03-06 Thread Larry Wall
Oh, I accidentally left NEXT out of my canonical list.  We do need to
have the equivalent to Perl 5's continue.

Larry


Compile-time undefined sub detection

2004-03-05 Thread Nigel Sandever
On the basis of what is known so far, will p6 be able to detect undefined subs 
at compile time?

Regards, Nigel.




Re: Compile-time undefined sub detection

2004-03-05 Thread Larry Wall
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

2004-03-05 Thread Rafael Garcia-Suarez
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

2004-03-05 Thread Larry Wall
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

2004-03-05 Thread Rafael Garcia-Suarez
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

2004-03-05 Thread Larry Wall
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

2004-03-05 Thread Rafael Garcia-Suarez
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

2004-03-05 Thread Damian Conway
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

2004-03-05 Thread Larry Wall
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

2004-03-05 Thread Rod Adams
Larry Wall wrote:

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
 

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.

-- Rod




Re: Compile-time undefined sub detection

2004-03-05 Thread Rafael Garcia-Suarez
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

2004-03-05 Thread Damian Conway
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

2004-03-05 Thread Jonathan Scott Duff
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

2004-03-05 Thread Austin Hastings
  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