This and other RFCs are available on the web at
  http://dev.perl.org/rfc/

=head1 TITLE 

Better constants and constant folding

=head1 VERSION 

    Maintainer: John Siracusa <[EMAIL PROTECTED]>
    Date: Aug 15 2000
    Version: 1 
    Mailing List: [EMAIL PROTECTED]
    Number:  113

=head1 ABSTRACT 

There are many ways to use named "constants" in Perl, but they all have
drawbacks: runtime initialization costs, the extra overhead of loading
another module, the inability to use the constants in certain situations,
and so on.

Constants should be first-class citizens in Perl, and should be constant
folded with a vengeance by a clever compiler.

=head1 DESCRIPTION 

An ideal Perl constant can be used anywhere that a Perl variable of the
same type can be used: a constant scalar can be used in place of any
scalar, a constant array can be used in place of any array, and so on.
These constants should not incur runtime inefficiencies or undue
compile-time overhead.  Performance should be should be exactly as if the
data was hard-coded in place.

=head1 IMPLEMENTATION

The simplest solution is something like:

    constant $PI = 3.14159265;

This looks shockingly similar to the current, much maligned (by me, anyway)
constant module:

    use constant PI => 3.14159265;

but the former has many syntactic advantages.  First, there's no "use"
directive to reveal the constant's second-class citizenship.  Second, it
uses the assignment operator instead of the "fancy comma."  Third, context
is determined by the left-hand-side of the assignment operator instead of
always being forced into list context.

Using these constants is simple.  They behave just like variables of the
same type.

    print "Would you like some apple $PI?"; # A constant string

That whole string is converted to a single constant at compile time.
Collections behave in a similar manner:

    constant @FISH = (1, 2, 'red', 'blue');
    
    print @FISH;   # prints "12redblue"
    print "@FISH"; # prints "1 2 red blue"

    print "$FISH[2] head"; # prints "red head"

Again, each argument to C<print> is converted to a constant string at
compile time.

Modification of a constant is a compile-time error:

    $PI = 5;           # Bzzt!
    $PI =~ s/\.\d+$//; # Sorry
    $#FISH = 15;       # Nice try

The C<constant> keyword should work when combined with C<my> and C<our>:

    package Foo;
    
    our constant $GOO = 5;
    
    if(...)
    {
      my constant $GOO = 10;
      
      print $GOO; # Prints 10
    }

As an added implementation bonus, "constant methods" should be supported
in the same way that "constant subroutines are now.

    package MyConstants;
    constant $PI = 3.14159265;

    package MyClass;
    ...
    sub method { $MyConstants::PI }
    
    package MyLib;
    ...
    sub func { $MyConstants::PI } # Shouldn't have to be sub func() ...

Both C<method()> and C<func()> should know that they return constants,
and the compiler should optimize them away whenever possible, even without
explicit hints like an empty "()" prototype after C<func>.  Yes, there
are issues with turning a method call into a constant at compile time, but
it's possible if Perl can determine with certainty that C<MyClass::method>
is the actual code that will be executed by an object or class method call.
Example:

    my $obj = MyClass->new;
    
    print $obj->method();    # Converted to the constant 3.14159265
    print MyClass->method(); # Ditto

Again, this magic is accomplished by a clever compiler that does not need
this type of help:

    my MyClass $obj = MyClass->new; # Not necessary, ideally

As should be clear by now, I'm not too familiar with the perl internals
that are required to support this stuff.  It just "seems possible" to me.
And hey, there are no "perl internals" to speak of yet in a "clean-sheet"
implementation, right?

=head1 REFERENCES 

Perl's C<constant> pragma documentation.


Reply via email to