tags:

views:

132

answers:

5

I am trying to make an executable out of my perl code and then I realized that there is no such option available with the perl compiler. After a bit of searching, I found perlcc, which is a frontend for the perl compiler and does the job (produce a binary).

Why does perl have separate compiler and frontend? Like for example, gcc for C/C++ is a complete tool in itself. Is this just the way it is, or are there some good reasons behind it?

A: 

Perl programs aren't compiled as C programs are, they are parsed at runtime. All perlcc does is try to bundle up the perl executable and any libraries your program needs into one binary. At runtime, the script will still be interpreted, not run from the binary data.

zigdon
Well, "runtime" meaning when you decide to run it. Perl compiles all the source then runs the bytecode it produces, unlike some things that read a line, run it, read another line, and so on. People tend to get this confused so I find you have to be really, really careful with "interpreted".
brian d foy
perlcc doesn't make a perl interpreter and I don't think it linked against libperl either, although I may be mistaken on the latter. Maybe you're thinking of PAR files and PAR::Packer?
Matt Kane
+1  A: 

Correction: It was a separate front-end. perl is not really a compiler to bytecode. The ultimate form of 'compiled' Perl is a set of abstract syntax trees that are then used by an interpreter. Perlcc support languished because the language changed fast enough that it never kept up. The problems it solved are mostly solvable in other ways that don't require constant maintenance of a separate source tree.

Matt Kane
What the E2 article totally neglects to mention, and what you seem not to be aware of, is that perlcc is now part of the [`B::C` distribution on CPAN](http://search.cpan.org/dist/B-C/) which is actively maintained. All those negative words "downfall" and "languished" give a false impression.
daxim
Well, don't also gloss over the docs that say "The code generated in this way is not guaranteed to work. The whole codegen suite (perlcc included) should be considered very experimental. Use for production purposes is strongly discouraged."
brian d foy
The test results for B::C don't look promising.
Matt Kane
(although I will add that to my E2 article)
Matt Kane
A: 

Perl is an interpreted language, C/C++ aren't.

Novikov
"Interpreted" in the sense that Java, Ruby, et al are interpreted, but not in the sense that shell scripts or BASIC is interpreted. It's a loaded term that people tend to take the wrong meaning from. :(
brian d foy
A: 

Because Perl 5 doesn't compile down to bytecode. Perl 6, on the other hand, can be compiled down to bytecode that runs on the Parrot virtual machine.

Chas. Owens
Well, Perl 5 doesn't compile down to a result that you can save and reuse in another run.
brian d foy
Yes, that is better way of saying it.
Chas. Owens
+5  A: 

First, perlcc is a dead tool (although it is in the B::C distro. Virtually no one uses (or used) it. It's not part of the normal Perl development process. It's own docs say:

The code generated in this way is not guaranteed to work. The whole codegen suite (perlcc included) should be considered very experimental. Use for production purposes is strongly discouraged.

Furthermore, it's not typical for people to compile Perl programs to a binary. Plenty of people would like to do that, but that's just not the way it works. What are you trying to accomplish? There might be another way to do what you want to do.

A Perl program really executes in two phases: a compile-time and a run-time.

Perl is more like Java or Ruby than C in this manner. When you run a Perl program, the perl interpreter loads all the source code and compiles it into a abstract syntax tree. It's that bytecode that perl executes (or interprets) during the runtime. This is the same sort of thing that Java, Ruby, and Python do.

One of Perl's warts is that it doesn't have a good way to save the result of that compilation, like those other languages can. That means you end up compiling the source every time. There are some ways around that with pperl and domain-specific tools such as mod_perl or fastcgi.

There are some fuzzy bits in there with BEGIN blocks, eval, and so on, but that's mostly the way it works. There are more details in perlmod.

This design wart wouldn't be there if we started all over with everything we know now, and indeed, in Perl 6 it isn't there. :)

brian d foy
Perl doesn't have the "two phases". What is also the main reason why no decent codegen ever materialized: one can't seperate compilation from interpretation. Perl compilation and running are overlapping and and there is no clear seperation: e.g. `BEGIN {}` are ran during syntax check already while `eval ""` or `s///ee` are compiled during run-time. Also many large module feature on-demand compilation where the real code is put past the `__END__` in the `.pm`. IOW Perl can save the results of the compilation - they just not useful since compiler still would be called during run-time.
Dummy00001
Perl basically has two phases. I mentioned the BEGIN and eval as "fuzzy bits". I don't know what you think saves the compilation, but if it's dump, that's the wrong answer too.
brian d foy
See [B::Concise](http://perldoc.perl.org/B/Concise.html) for example. Perl tree can be represented reliably. It just [makes no sense](http://www.perlmonks.org/index.pl?node_id=45235) since there is no clear separation between compilation and execution, and new stuff could be added to the tree during run-time (`eval "sub {}"`). And yes, that is actively used and deemed important language feature. That means generated executable would still have to contain (or access) the whole of the Perl distro. And that defies the purpose of code generation.
Dummy00001
B::Concise prints a text version of the syntax tree. It doesn't give you something that you can execute. I don't know why you're arguing about eval here. I mentioned that part was fuzzy in my post. I'm not denying that it exists. You can run code during the compile phase, and you can compile code during the run phase, but that doesn't negate that there are two phases. That's how the various blocks like BEGIN, INIT, CHECK, and so on know how to run.
brian d foy
@Dum: there are two phases, but each phase can recursively enter the other phase. There was a really good perlmonks article discussing this (and has come up before on previous SO posts) but alas my search-fu is inadequate for the time I currently have to find it.
Ether
@Ether: well, that [actually four](http://archu.wordpress.com/2006/10/02/perl-interpreted-or-compiled/). But as code generation goes, and why the subject's `perlcc` is useless, is precisely the recurrence. IOW, phases designation at large makes no sense, since in Perl script execution there is no point of time where one can say "from here on it is only interpretation." Compare to Python or Java or C: they have clearly demarcated global phases. Perl doesn't.
Dummy00001
I'm starting to understand your problem. You're reading random stuff on the internet instead of the documentation. It's easy to get confused doing that.
brian d foy
@Dummy Python has `eval`. We fully acknowledge that the compilation and runtime phases can call each other, but they are still distinct. I'm not sure what you're arguing. Anyhow, perlcc can handle `eval`. It only cuts out the first-pass compilation step. This is also why it was dropped, there's a small startup benefit but no runtime. Perl ops are already written in C, and a lot of what perlcc does is call ops. B::CC attempts to do optimizations, but it never got far. Its still being worked on as an independent project. http://search.cpan.org/dist/B-C
Schwern