Re: Compiled programs to keep BEGIN blocks? (was Re: [RFC] Switch to make Test::Builder output even if $^C ( for B::C ))

2002-01-16 Thread Michael G Schwern

On Wed, Jan 16, 2002 at 11:39:05AM +0100, Mattia Barbon wrote:
> >It seems that's wrong.  That what perlcc/B::C does is 'freeze' the
> >current state of the interpreter after compilation, including the
> >values of variables, and then spit out appropriate C code for only 
> >the post-compile opcode tree.  Is this right?
> 
> Yes. That's what makes startup time faster ( but not run time,
> as you surely know )

I always thought that was recouped because you didn't have to load the
interpreter and wait for Perl to compile the program and libraries to
bytecode.


PS  I got a huge number of these warnings from compiling 'use CGI'
pccF6qox.c:14873: warning: decimal constant is so large that it is unsigned
pccF6qox.c:14875: warning: decimal constant is so large that it is unsigned



-- 

Michael G. Schwern   <[EMAIL PROTECTED]>http://www.pobox.com/~schwern/
Perl Quality Assurance  <[EMAIL PROTECTED]> Kwalitee Is Job One
This is my sig file.  Is it not nify?  Worship the sig file.
http://www.sluggy.com



Re: Compiled programs to keep BEGIN blocks? (was Re: [RFC] Switch to make Test::Builder output even if $^C ( for B::C ))

2002-01-16 Thread Paul Johnson

On Tue, Jan 15, 2002 at 05:30:09PM -0500, [EMAIL PROTECTED] wrote:
> On Tue, Jan 15, 2002 at 08:51:06AM +, Piers Cawley wrote:
> > > I don't understand.  Why do we have to deal with them?  Just translate
> > > the Perl code in the BEGIN block to C , dump it and make
> > > sure it gets run first.  Right?
> > >
> > > I think I'm missing something very vital here.

Yeah, I think so ;-)

[snip]

> Guess?  Its a BEGIN block, it gets run once!

Oh good, because you seemed to be suggesting otherwise.

> Ok, there's some really fundemental breakdown of understanding here,
> and I think its me.  Let's step back a second.  Why is anything
> guessing when and how many times BEGIN blocks are run?

Well, you seemed to be suggesting that some BEGIN blocks would be run at
runtime.  Some BEGIN blocks have to run at compile time.  If they're
only to be run once then you have to decide when that will be.


My boss recently gave me a fairly tricky problem to solve.  The Java
boys weren't making much headway, so he asked if I could do it in PERL.
After (a) little thought I came up with an elegant modular solution.

Since the program contains proprietary intellectual property and also
because it has to run as fast as C, I decided to run perlcc on it.

Here's my program.  Please don't break it.

ONE.pm
==

package ONE;

# I might obfuscate this eval statement later in case any of our
# competitors ever see this code.

sub import { eval '$main::ONE--' }

1

one.plx
===

#!/usr/bin/perl

# Copyright Paul Johnson, 2002
# This program is mine.  You can't have it.

# Program to print 1

BEGIN { $ONE = 2 }  # Initialisation.

use ONE;# Abstracted away main logic.

print $ONE  # Output.

__END__


The fundamental problem here is that BEGIN blocks have to run when they
are compiled.  This is documented.  You can try to work out whether the
BEGIN blocks can be rearranged and run at different times, but as Piers
has pointed out, this is impossible in the general case.  So if the
BEGIN blocks are run at compile time, there's no point having them
around at run time.  This is the raison d'ĂȘtre of INIT blocks.

This problem cannot be solved.  But if you do solve it millions will
rejoice.  Well, thousands anyway.  Still, I wonder whether you shouldn't
work up to it by perhaps finding a polynomial time solution to the
travelling salesman problem for example.

PS.  Parts of this message are moderated by :-) where required by law.

-- 
Paul Johnson - [EMAIL PROTECTED]



Re: Compiled programs to keep BEGIN blocks? (was Re: [RFC] Switch to make Test::Builder output even if $^C ( for B::C ))

2002-01-16 Thread Michael G Schwern

On Wed, Jan 16, 2002 at 08:45:26AM +0100, Paul Johnson wrote:
> The fundamental problem here is that BEGIN blocks have to run when they
> are compiled.  This is documented.  You can try to work out whether the
> BEGIN blocks can be rearranged and run at different times, but as Piers
> has pointed out, this is impossible in the general case.  So if the
> BEGIN blocks are run at compile time, there's no point having them
> around at run time.  This is the raison d'?tre of INIT blocks.

Ok, lemme run this by you.

Here's my conception of how perlcc/B::C works.  The program is
compiled, the opcode tree is scanned and the appropriate C code is
written for each op in the program.  Just like B::Deparse scans the
opcode tree and writes out Perl code.

Which is why I'm having so much conceptual trouble with why BEGIN
blocks would be a problem.

It seems that's wrong.  That what perlcc/B::C does is 'freeze' the
current state of the interpreter after compilation, including the
values of variables, and then spit out appropriate C code for only 
the post-compile opcode tree.  Is this right?

In which case, yes, I can see how BEGIN blocks would be
troublesome. :(


-- 

Michael G. Schwern   <[EMAIL PROTECTED]>http://www.pobox.com/~schwern/
Perl Quality Assurance  <[EMAIL PROTECTED]> Kwalitee Is Job One
Nature is pissed.
http://www.unamerican.com/



Re: Compiled programs to keep BEGIN blocks? (was Re: [RFC] Switch to make Test::Builder output even if $^C ( for B::C ))

2002-01-15 Thread Michael G Schwern

On Tue, Jan 15, 2002 at 08:51:06AM +, Piers Cawley wrote:
> > I don't understand.  Why do we have to deal with them?  Just translate
> > the Perl code in the BEGIN block to C , dump it and make
> > sure it gets run first.  Right?
> >
> > I think I'm missing something very vital here.
> 
> Let's see if I can come up with a simple counterexample that will show
> up the problem.
> 
> #!perl
> my($compile_time, $start_time);
> BEGIN {$compile_time .= localtime(time)}
> 
> # Later:
> 
> print "Compiled at $compile_time\n";
> print "Started at $start_time\n";
>
> ...
> 
> BEGIN {$start_time .= localtime(time)}
> __END__
> 
> How do you intend to distinguish between those two BEGIN blocks, one
> of which must be run at script compile time, the other of which must
> be run at (for want of a better description) INIT time? And neither of
> which can be run twice (hence the .=).

Wouldn't both of those BEGIN blocks be run at compile-time?  The only
ordering I'd see is that the first one declared (ie. $compile_time) is
run before the second (ie. $start_time).


> The only thing that can make that distinction is a human being. The
> compiler can probably guess that the two blocks should only be run
> once

Guess?  Its a BEGIN block, it gets run once!

Ok, there's some really fundemental breakdown of understanding here,
and I think its me.  Let's step back a second.  Why is anything
guessing when and how many times BEGIN blocks are run?

Is B::C literally dumping out the total state of the interpreter after
compile-time, variables and everything?!


-- 

Michael G. Schwern   <[EMAIL PROTECTED]>http://www.pobox.com/~schwern/
Perl Quality Assurance  <[EMAIL PROTECTED]> Kwalitee Is Job One
Paste is a waste if you're chaste,
but in this case dump a load
of goo and poo by the case in your face,
and place in your jawls like a juicy chaw,
but don't spit that shit and enjoy it all.
-- Ubergirl's beau



Re: Compiled programs to keep BEGIN blocks? (was Re: [RFC] Switch to make Test::Builder output even if $^C ( for B::C ))

2002-01-14 Thread Michael G Schwern

On Mon, Jan 14, 2002 at 11:43:24PM +, Piers Cawley wrote:
> > What's left?
> 
> What about begin blocks with side effects. How do you propose
> detecting the side effects. How do you deal with things that may
> dispatch to different subroutines depending on when they are
> evaluated? How do you deal with arrays getting initialised (and
> possible extended) twice? How, in short do you solve the halting
> problem? 

A scene from Perl: The Gathering.

Piers has played the Halting Problem card your thread!

Schwern counters by taping Hitler and playing two Befuddled 
Innocence cards!

;)

I don't understand.  Why do we have to deal with them?  Just translate
the Perl code in the BEGIN block to C , dump it and make
sure it gets run first.  Right?

I think I'm missing something very vital here.


> The point is that even B::Deparse, which tries very hard to get BEGIN
> blocks right, can't do this and, according to the above extract, is
> highly unlikely to do so in the forseeable future.

Like I said, I don't expect perlcc to run perfectly Right Now, but I
do expect this to be considered a bug, not a feature.  The upshot of
this is: don't prop up the perlcc tests to shield against this.

That was the original point of this thread.  Somebody will come along
and fix it someday.  That day might be tommorrow, dunno.  Three weeks
ago perlcc was declared indefinitely dead in the water, now its alive
and kicking again.  We do impossible things all the time.


-- 

Michael G. Schwern   <[EMAIL PROTECTED]>http://www.pobox.com/~schwern/
Perl Quality Assurance  <[EMAIL PROTECTED]> Kwalitee Is Job One
grep { ref and ref !~ /^[A-Z]+$/ } kill 9, @ARGV;



Re: Compiled programs to keep BEGIN blocks? (was Re: [RFC] Switch to make Test::Builder output even if $^C ( for B::C ))

2002-01-14 Thread Michael G Schwern

On Mon, Jan 14, 2002 at 11:11:57PM +, Nicholas Clark wrote:
> On Mon, Jan 14, 2002 at 10:38:36PM +, Piers Cawley wrote:
> > Michael G Schwern <[EMAIL PROTECTED]> writes:
> > 
> > > On Mon, Jan 14, 2002 at 04:16:49PM +, Piers Cawley wrote:
> > >> Michael G Schwern <[EMAIL PROTECTED]> writes:
> 
> > >> > Like it or not, people put lots of init code into BEGIN blocks, if
> > >> > nothing else for backwards compatiblity with 5.005.  perlcc has to
> > >> > compile real world programs.
> 
> > Meanwhile we *do* have INIT blocks will do what you want without doing
> > the impossible. (Well, admittedly, educating programmers might well be
> > nearly impossible too, but dammit the behaviour of BEGIN blocks has
> > been *documented* since before there was a Perl compiler. And the
> > behaviour of INIT and CHECK blocks have also been clearly documented
> > since they were interested.
> > 
> > This really is a case of 'READ THE FSCKING MANUAL'.
> 
> I can't see that anything is going to solve what Schwern wants, becuse what
> he wants is a solution backwards compatible to 5.00503 and preferably 5.004

I want 5.004_05 compatible code (or any syntacticly correct piece of
Perl code) to be able to be compiled correctly (eventually) with the
latest version of perlcc.

If there's Perl->C translation issue as to why that's not possible,
ok.  But I know from a B standpoint all the information is there to
handle BEGIN blocks.


-- 

Michael G. Schwern   <[EMAIL PROTECTED]>http://www.pobox.com/~schwern/
Perl Quality Assurance  <[EMAIL PROTECTED]> Kwalitee Is Job One
Now I fight for wisdom.
http://sluggy.com/d/010204.html



Re: Compiled programs to keep BEGIN blocks? (was Re: [RFC] Switch to make Test::Builder output even if $^C ( for B::C ))

2002-01-14 Thread Michael G Schwern

On Mon, Jan 14, 2002 at 10:38:36PM +, Piers Cawley wrote:
> >> Deferring BEGIN blocks 'til runtime will break rather more realworld
> >> program than it fixes I think.
> >
> > Where is deferring involved?
> 
> Err... it goes like this:
> 
>  by the main program>
> 
> 
> 
> 
> 
> The compiled file gets dumped out at CHECK time as I think we said
> before. What you propose is to defer BEGIN processing to after the
> CHECK phase. So, how do you decide whether 
> 
> BEGIN {
> push @INC, 'bibble';
> }
> 
> gets evaluated at compile time (which it should because it has far
> reaching effects about where stuff gets included from during
> compilation), or if it gets evaluated at runtime. Admittedly, this one
> is rather straightforward.

Oh, I think you misunderstand.  Everything gets evaluated like normal.
BEGIN blocks run, checks, whatever.  Then its all compiled and dumped.
The only difference I'm proposing is that any code in the BEGIN blocks
(mod use statements and whatnot) is also dumped.  So the resulting
C code mirrors what the original was doing.

You can get at the BEGIN code via B::save_BEGINs.  You can figure out
what's code and what's just a use statement.  You can squelch any
output with O.pm's -qq.

What's left?


> Meanwhile we *do* have INIT blocks will do what you want without doing
> the impossible. (Well, admittedly, educating programmers might well be
> nearly impossible too, but dammit the behaviour of BEGIN blocks has
> been *documented* since before there was a Perl compiler. And the
> behaviour of INIT and CHECK blocks have also been clearly documented
> since they were interested.
> 
> This really is a case of 'READ THE FSCKING MANUAL'.

Its also a case of "I'd rather not break backwards compatibility [1]
just to feed perlcc's neurosises".  

There's also the factor that for all intents and purposes, Joe Average
Programmer really shouldn't have to care about the difference between
BEGIN, INIT and CHECK.  In fact, they should be able to get along just
fine without ever knowing INIT and CHECK even exist.  Sort of like
*foo{HASH} and the finer points of the -D switch.


Its perlcc's job to reproduce the actions of the original code to the
best of its abilities.  It might turn out that its not possible.  This
is, after all, an experiment.


[1] I think they were in 5.005_XX, just not documented well until 5.6.

-- 

Michael G. Schwern   <[EMAIL PROTECTED]>http://www.pobox.com/~schwern/
Perl Quality Assurance  <[EMAIL PROTECTED]> Kwalitee Is Job One
Maybe they hooked you up with one of those ass-making magazines.
-- brian d. foy as misheard by Michael G Schwern



Re: Compiled programs to keep BEGIN blocks? (was Re: [RFC] Switch to make Test::Builder output even if $^C ( for B::C ))

2002-01-14 Thread Michael G Schwern

On Mon, Jan 14, 2002 at 11:20:43PM +0100, Rafael Garcia-Suarez wrote:
> On 2002.01.14 22:27 Michael G Schwern wrote:
> > B::Deparse has slowly gotten very good at figuring out BEGIN blocks
> > from 'use' statements and putting them in the right places.  Hard
> > fought knowledge.  Steal from it.
> 
> There are still problems with pragmas. (As I was working on B::Deparse
> the last few weeks, if you find new solutions, let me know.)

I don't know if B::C has to worry about the same style of pragma
problems as B::Deparse.  ie. it doesn't have to worrying about
reconstructing 'use strict' from a bunch of magic $^H twiddling
opcodes.


-- 

Michael G. Schwern   <[EMAIL PROTECTED]>http://www.pobox.com/~schwern/
Perl Quality Assurance  <[EMAIL PROTECTED]> Kwalitee Is Job One
You can't control the universe with a jar of red pepper.
http://www.goats.com/archive/981004.html



Re: Compiled programs to keep BEGIN blocks? (was Re: [RFC] Switch to make Test::Builder output even if $^C ( for B::C ))

2002-01-14 Thread Rafael Garcia-Suarez

On 2002.01.14 22:27 Michael G Schwern wrote:
> B::Deparse has slowly gotten very good at figuring out BEGIN blocks
> from 'use' statements and putting them in the right places.  Hard
> fought knowledge.  Steal from it.

There are still problems with pragmas. (As I was working on B::Deparse
the last few weeks, if you find new solutions, let me know.)

> I don't expect perlcc to magically become perfect overnight.  What I
> do expect is that the 'compiled programs won't run code in BEGIN
> blocks' be treated as a bug and not a feature and to look around at
> other bits of B which are taking a stab at solving these problems.



Re: Compiled programs to keep BEGIN blocks? (was Re: [RFC] Switch to make Test::Builder output even if $^C ( for B::C ))

2002-01-14 Thread Michael G Schwern

On Mon, Jan 14, 2002 at 04:16:49PM +, Piers Cawley wrote:
> Michael G Schwern <[EMAIL PROTECTED]> writes:
> 
> > On Mon, Jan 14, 2002 at 10:23:46AM +, Piers Cawley wrote:
> >> Um... You're wrong. If you do need 'startup time' initialization then
> >> you should do it in an INIT block. If I may quote from the
> >> documentation:
> >
> > Like it or not, people put lots of init code into BEGIN blocks, if
> > nothing else for backwards compatiblity with 5.005.  perlcc has to
> > compile real world programs.
> 
> Deferring BEGIN blocks 'til runtime will break rather more realworld
> program than it fixes I think.

Where is deferring involved?


-- 

Michael G. Schwern   <[EMAIL PROTECTED]>http://www.pobox.com/~schwern/
Perl Quality Assurance  <[EMAIL PROTECTED]> Kwalitee Is Job One
Lord of Kwalitee!  Wearer of the CPANTS and Slayer of Pseudo-hashes!



Re: Compiled programs to keep BEGIN blocks? (was Re: [RFC] Switch to make Test::Builder output even if $^C ( for B::C ))

2002-01-14 Thread Michael G Schwern

On Mon, Jan 14, 2002 at 04:16:49PM +, Piers Cawley wrote:
> > Like I said, if B::Deparse can do it, B::C can.
> 
> But it shouldn't. How do you distinguish between:
> 
>use Foo;
> 
> (needs to use 'Foo' before generating the compiled script, otherwise
> what's the bloody point?)
> 
> and 
> 
>BEGIN { ... }

Using Deep Magic as demonstrated inside B::Deparse by begin_is_use().
Module::Info uses a rather simplified version for it's
modules_used() method.

Not easy, but definately a (mostly) solved problem.


> Also, as the docs for B::Deparse points out:
> 
> we can't guarantee to produce BEGIN blocks or "use" declarations
> in exactly the right place.
> 
> Which can become a big problem when you find that your compiled script
> doesn't work and there's no easy way of debugging the program that it
> thinks it's evaluating.

So is the answer to just exclude them entirely?  That's the wrong way
out.

B::Deparse has slowly gotten very good at figuring out BEGIN blocks
from 'use' statements and putting them in the right places.  Hard
fought knowledge.  Steal from it.


I don't expect perlcc to magically become perfect overnight.  What I
do expect is that the 'compiled programs won't run code in BEGIN
blocks' be treated as a bug and not a feature and to look around at
other bits of B which are taking a stab at solving these problems.


-- 

Michael G. Schwern   <[EMAIL PROTECTED]>http://www.pobox.com/~schwern/
Perl Quality Assurance  <[EMAIL PROTECTED]> Kwalitee Is Job One
Well, my work here is done.  If you need me again, just admit that you're
screwed and die.



Re: Compiled programs to keep BEGIN blocks? (was Re: [RFC] Switch to make Test::Builder output even if $^C ( for B::C ))

2002-01-14 Thread Mattia Barbon

> On Sun, Jan 13, 2002 at 10:04:58PM +0100, Mattia Barbon wrote:
> > > $ bleadperl -MO=-qq,Deparse foo.plx
> > > sub BEGIN {
> > > print "foo\n";
> > > }
> > > print "bar\n";
> > > 
> > > If B::Deparse can save BEGIN blocks, B::C can.
> >
> > I didn't mean that I can't write code to make B::C save BEGIN blocks
> > ( it'd require <10 lines, probably ), I did mean that doing so would
> > not be a god idea: _I am
> > saving the state of the program after those blocks were ran_ and
> > they will be run _another time_ at runtime, and this is not correct:
> > ( for example use lib 'a'; would put 'a' into @INC twice, once
> > ( correctly ) at compile time, and another time ( incorrectly ) at 
> > runtime ). In this 
> > case this is not harmful, but you get the idea.
> 
> I don't understand.  The compiled program should do exactly what the
> original program did.  Anything else, as difficult as it may be, is a
> bug.  Lots of programs and modules do important load-time checks and
> logic inside BEGIN blocks.
> 
> Why would this:
> 
> BEGIN {
> push @INC, 'foo';
> }
> 
> put 'foo' into @INC twice if it were compiled?  The compiled program
> should not be storing the post-BEGIN value of @INC, it should store
> the original value at startup.
This isn't the way B::C ( I suspect B::Bytecode and B::CC work
the same way ) works. It _by design_ saves the state _after_ the
BEGIB blocks are run; the idea is to skip compilation time.
Now, I know this is not going to always work, and the only ( always ) working 
solution I see ( and I'd like to be proved wrong here ), is something like B::Script 
( which stores the source code of the program+modules in a single executable ). And 
yes, I realized that
[ B::C is not always going to work ] just a coule days ago.

Regards
Mattia



Compiled programs to keep BEGIN blocks? (was Re: [RFC] Switch to make Test::Builder output even if $^C ( for B::C ))

2002-01-13 Thread Michael G Schwern

On Sun, Jan 13, 2002 at 10:04:58PM +0100, Mattia Barbon wrote:
> > $ bleadperl -MO=-qq,Deparse foo.plx
> > sub BEGIN {
> > print "foo\n";
> > }
> > print "bar\n";
> > 
> > If B::Deparse can save BEGIN blocks, B::C can.
>
> I didn't mean that I can't write code to make B::C save BEGIN blocks
> ( it'd require <10 lines, probably ), I did mean that doing so would
> not be a god idea: _I am
> saving the state of the program after those blocks were ran_ and
> they will be run _another time_ at runtime, and this is not correct:
> ( for example use lib 'a'; would put 'a' into @INC twice, once
> ( correctly ) at compile time, and another time ( incorrectly ) at 
> runtime ). In this 
> case this is not harmful, but you get the idea.

I don't understand.  The compiled program should do exactly what the
original program did.  Anything else, as difficult as it may be, is a
bug.  Lots of programs and modules do important load-time checks and
logic inside BEGIN blocks.

Why would this:

BEGIN {
push @INC, 'foo';
}

put 'foo' into @INC twice if it were compiled?  The compiled program
should not be storing the post-BEGIN value of @INC, it should store
the original value at startup.


-- 

Michael G. Schwern   <[EMAIL PROTECTED]>http://www.pobox.com/~schwern/
Perl Quality Assurance  <[EMAIL PROTECTED]> Kwalitee Is Job One
Me? A robot? That's rediculous! For one thing, that doesn't compute at all!