http://www.perlmonks.org?node_id=344952

Recently in the pub I was talking about forward compatibility between perl5 and perl6 with Nicholas Clark, the current perl 5.8 pumpking. We have been promised that perl6 will also run older perl5 programs, despite quite a lot of incompatible feature changes between the two versions of the language. So how will perl6 be able to tell whether code is written in perl5 or perl6? Or whether it's buggy perl5, correct perl5, buggy perl6, or correct perl6? Heuristics can only get you part of the way, so some kind of explicit marker which definitively says "this is perl5" would be a Good Thing. And it would also be a Good Thing if that mechanism could be used right now in perl5 programs, so that we can start our migration to perl6 by at least ensuring that existing code is forward-compatible.

So I took this to the perl6-language list, suggesting a perl5 pragma "use perl5;" which would be that marker for the perl6 interpreter, but in perl5 would be a null pragma.

However, it turns out that there is already such a mechanism. perl6 will not use the "package" keyword, and will take its presence to mean "this is perl5 code". So existing modules should work already.

But what about scripts and programs? They don't generally say "package" anywhere. But, if you don't specify a package, that just means use the default package, which is called "main". The solution therefore is to insert, at the top of all your scripts and programs, this line:

package main;

Go and do it today. Tell your friends. Get yourself ready for the shiny new perl6 world.

Replies are listed 'Best First'.
Re: Ensuring forward compatibility
by Abigail-II (Bishop) on Apr 14, 2004 at 10:54 UTC
    But what about scripts and programs? They don't generally say "package" anywhere. But, if you don't specify a package, that just means use the default package, which is called "main". The solution therefore is to insert, at the top of all your scripts and programs, this line:
    package main;
    Go and do it today. Tell your friends. Get yourself ready for the shiny new perl6 world.

    This problem has already been addressed by Larry in Apocalyse 1, three years ago. I quote:

    A closely related question is how Perl is going to recognize when it has accidentally been fed Perl 5 code rather than Perl 6 code. It would be rather bad to suddenly give working code a brand new set of semantics. The answer, I believe, is that it has to be impossible by definition to accidentally feed Perl 5 code to Perl 6. That is, Perl 6 must assume it is being fed Perl 5 code until it knows otherwise. And that implies that we must have some declaration that unambiguously declares the code to be Perl 6.

    Now, there are right ways to do this, and wrong ways. I was peeved by the approach taken by DEC when they upgraded BASIC/PLUS to handle long variable names. Their solution was to require every program using long variable names to use the command EXTEND at the top. So henceforth and forevermore, every BASIC/PLUS program had EXTEND at the top of it. I don't know whether to call it Bad or Ugly, but it certainly wasn't Good.

    A better approach is to modify something that would have to be there anyway. If you go out to CPAN and look at every single module out there, what do you see at the top? Answer: a ``package'' declaration. So we break that.

    I hereby declare that a package declaration at the front of a file unambiguously indicates you are parsing Perl 5 code. If you want to write a Perl 6 module or class, it'll start with the keyword module or class. I don't know yet what the exact syntax of a module or a class declaration will be, but one thing I do know is that it'll set the current global namespace much like a package declaration does.

    Now with one fell swoop, much of the problem of programming in the large can be dealt with simply by making modules and classes default to strict, with warnings. But note that the default in the main program (and in one liners) is Perl 5, which is non-strict by definition. We still have to figure out how Perl 6 main programs should distinguish themselves from Perl 5 (with a ``use 6.0'' maybe?), and whether Perl 6 main programs should default to strict or not (I think not), but you can already see that a course instructor could threaten to flunk anyone who doesn't put ``module Main'' at the front each program, and never actually tell their pupils that they want that because it turns on strictures and warnings.

    Abigail

      I would be dismayed if the solution reached meant that Perl 5 barfed with an odd error - if any Perl 6 program needs to be Perl 5 before Perl 6 is 'switched on', then I would think that the switch should be something that causes an obvious error in Perl 5 when run, so that the user knows that it is Perl 6 code. For example:

      $ perl use 6.0; Perl v6.0.0 required (did you mean v6.000?)--this is only v5.8.1, stopped at - line 1.

      To me, that looks fine. To have some kind of 'module Main;' requirement (as per Larry's last sentance) you get:

      $ perl module Main; Can't locate object method "module" via package "Main" (perhaps you forgot to load "Main"?) at - line 1.

      That just looks like something has broken. But, although 'use 6.0;' looks okay, it kinda fails the EXTEND test he sets out - it's not naturally there. In fact, I don't think there is anything naturally there in a Perl 5 program that you can use to do this. But, maybe Larry only raised that point in relation to modules.

      Most people haven't read the apocalypses, or have read them but forgot the details. This was my humble attempt to bring one of the more important issues for perl5 programmers to a wider audience.
        Maybe I should have been more explicit. My point wasn't that you should have read the apocalypse. My point was that you shouldn't spread FUD, suggesting that people should modify their perl5 programs. Putting a package main; on top of your programs is not necessary.

        Abigail

Re: Ensuring forward compatibility
by eserte (Deacon) on Apr 14, 2004 at 09:14 UTC
    Of course there are exceptions. For instance do not put "package main" in a script which is used with Apache::Registry.
      Please tell a perl novice why this is so.

      -Theo-
      (so many nodes and so little time ... )

        Apache::Registry automatically puts every script in its own namespace, something like Apache::ROOT$script_name. This is so to avoid name clashes in global variables and subroutines, because every Apache::Registry script is running in the same perl interpreter. Putting a "package main" on top of such a script would make the special namespace void and thus name clashes would be possible.

        As a workaround, one could use "package my_distinct_script_name" instead of "package main".

Re: Ensuring forward compatibility
by Jouke (Curate) on Apr 14, 2004 at 08:15 UTC
    Reading the first part of your posting I was thinking you wanted suggestions...I was almost starting to post a node were I suggested to use 'package main' (which is already in quite a few of my scripts)...but then you provided the answer yourself DrHyde++


    Jouke Visser, Perl 'Adept'
    Using Perl to help the disabled: pVoice and pStory
Re: Ensuring forward compatibility
by rinceWind (Monsignor) on Apr 14, 2004 at 09:17 UTC
    I see the following as a new perl5 script boilerplate:
    #!** perl ** (replace with $^X on target machine) package main; use strict; use warnings;

    --
    I'm Not Just Another Perl Hacker

Re: Ensuring forward compatibility
by kal (Hermit) on Apr 14, 2004 at 10:04 UTC

    Much as I like the intent, package main; looks ugly as sin to my fair eyes! We must be able to do better than that, surely?

    To me, something like require v5; should trigger the "uh, this isn't Perl6" switch - and is much more obvious to my mind. "I require version 5" is better than "I live in the main namespace" (or whatever package does :). I'm aware that require doesn't put a ceiling on the version, but I doubt adding one now will really make any practical difference.

Re: Ensuring forward compatibility
by dragonchild (Archbishop) on Apr 14, 2004 at 12:22 UTC
    I think the important feature here is that Perl6 scripts will be able to use Perl5 modules and classes, among other languages. The parser will have to disambiguate when it is handling a Perl6 module, a Perl5 module, a PHP module, etc. Hence, the difference between package and module/class/whatever other scopers Perl6 will have.

    As for scripts ... I think that this is a straw man. If you pass a PHP script or HTML file to Perl5, what would you think is going to happen? Perl6 is not the same language as Perl5. It is a different language that just happens to have a common subset. This is not a C to C++ upgrade. Very few Perl5 scripts will actually compile under Perl6 syntax, and this is a good thing.

    Let me put it this way - what happens if you mix your Perl binaries right now, in the 5.x series? You might get lucky ... you might get spewed. Script authors will just have to be careful. (Or anal, with 'package main;' and 'module Main;'. I plan on being careful.)

    ------
    We are the carpenters and bricklayers of the Information Age.

    Then there are Damian modules.... *sigh* ... that's not about being less-lazy -- that's about being on some really good drugs -- you know, there is no spoon. - flyingmoose

      The problem is that the same binary (eg, /usr/bin/perl) will be able to load both Perl 5 and 6, so we need some way to tell it which we're feeding it.

        On a Linux, Unix, BSD, or Unix like system it is possible to install perl 6 as /usr/bin/perl6, right alongside perl5. As a matter of fact, for most of my programs, as I upgrade, I keep versions separate. i.e. I have /usr/local/apache2/ linked to /usr/local/apache2.49 while I also have /usr/local/apache2.48 installed on my system


        Want to support the EFF and FSF by buying cool stuff? Click here.

      I'm not so sure about your straw man. Yes, we know that Perl 6 is very different to Perl 5. But, to many people (dare I suggest most), it's likely that Perl is Perl is Perl. They will understand things like "not a new enough version", but not the arcane messages (like I posted above).

      Look at it the other way around: if there is a way to make Perl 6 scripts fail under Perl 5 with an error saying "This is Perl 6 code, but you're running Perl 5", surely that is the best way to have it? After all, if you mix your Perl binaries in 5.x, judicious use of 'require' means that you're not going to get "spewed" as often as you could do, and when it happens you know why.

Re: Ensuring forward compatibility
by ambrus (Abbot) on Apr 14, 2004 at 13:27 UTC

    Wouldn't it be a good solution if the perl6 had a different name?

    I mean, suppose that when you install perl6, it owuld install its binary as /usr/local/bin/perl6, and a link to it as /usr/local/bin/perl. Then, it could decide on what kind of code something is from the name it is started, and the shebang line (which would have higher privilege then the actual executable name). As most scripts already have a shebang line (even if not used by the os, just the switches are read by perl), this would work with great reliability. There might still be a mechanism to override this, such as package in one way, and for example module or I don't know what in the other way.

    (Maybe Larry is affraid to do this as this would admit that perl6 and perl are a different language.)

    Update 2010-04-15: python3 does this now.

      I suggest we use newbie convention and call it Perl (watch the case!), so we could say "you need to use Perl not perl to parse Perl 6 Perl, because you use perl to parse Perl 5 Perl, PERL is reserved for Perl 7". That would be funny, especially for Windows users.

      Nah, seriously, I like your idea best. This is what python does between 2.2 and 2.3 and it seems to work for them. Unambigious, and dead-on straight forward. Plus, it means the interpreter/VM can be a little cleaner for not understanding compatibility. This doesn't mean the perl6 executable couldn't detect the lack of a module/class and option out to perl5 via exec...

      This is similar to why you see some Perl code around that has a shebang line of /usr/local/bin/perl5. During the transition from Perl4 -> Perl5, there needed to be seperate intepreters. Of course, by now everyone who is going to convert their code to Perl5 has probably already done so, but we're still stuck with some silly shebang lines. IMHO, it's better not to force the seperation if it's not needed, espcially if the underlieing runtime (Parrot) will handle both.

      ----
      : () { :|:& };:

      Note: All code is untested, unless otherwise stated

Re: Ensuring forward compatibility
by flyingmoose (Priest) on Apr 14, 2004 at 13:54 UTC
    Of course the joke response here is that you will not need "package main" inserted into your perl5 scripts for another 3 to 5 years :)
Re: Ensuring forward compatibility
by Theo (Priest) on Apr 14, 2004 at 14:51 UTC
    A lot of this discussion is just passed my level of understanding, so forgive me if this is inappropriate. It almost sounds like we're approaching a "Y2K" kind of issue. Even if Perl 6 won't be released for a few years yet (I don't know *what* the real schedule is) when it is released, unprepared perl 5 code will manage to find itself submitted to a Perl 6 interpreter. You can count on it! In the above discussion, it doesn’t sound like Perl 6 will magically know when it is getting perl 5. Don't programmers have an obligation to "do the right thing" now to avoid problems in the future?

    Perhaps, though, only trivial code will be affected because all serious code uses packages. Is that's the case, the problems of transition will be trivial.

    -Theo-
    (so many nodes and so little time ... )

      ... unprepared perl 5 code will manage to find itself submitted to a Perl 6 interpreter. You can count on it! In the above discussion, it doesn’t sound like Perl 6 will magically know when it is getting perl 5. Don't programmers have an obligation to "do the right thing" now to avoid problems in the future?

      The problem is that the Perl 6 team knows about this issue and is working to address it, but hasn't decided exactly how to do so. Given that we don't yet know what "the right thing" is, calls to start doing something about it seem premature.

        Thank you. I think that sums up the situation very well.

        - tye        

Re: Ensuring forward compatibility
by Happy-the-monk (Canon) on Apr 16, 2004 at 10:57 UTC

    we don't need to worry about Perl 6 not recognising Perl 5, so there isn't actually much to be said.

    There's a well known programming language that forces you to put everything into a class.
    Many here are known to shun it for this rigidness.

    Then there's Perl where, think about it, you may actually chose to put everything into a package.
    It can be executed if you want it to, you put a

    unless ( caller ) {
        package main;
        do what needs to be done here
    }

    block somewhere and there you go.
    TIMTOWTDI again and no worries about scripts that don't have a package declaration.

    Cheers, Sören (who learned this bit from Johan Vromans)