RFC 337 (v1) Common attribute system to allow user-defined, extensible attributes

[email protected] (Perl6 RFC Librarian) 29 Sep 2000 00:45:56 -0000
Newsgroups perl.perl6.announce.rfc,perl.perl6.language
Message-ID <[email protected]>
This and other RFCs are available on the web at
  http://dev.perl.org/rfc/

=head1 TITLE

Common attribute system to allow user-defined, extensible attributes

=head1 VERSION

  Maintainer: Nathan Wiger <[email protected]>
  Date: 28 Sep 2000
  Mailing List: [email protected]
  Number: 337
  Version: 1
  Status: Developing

=head1 ABSTRACT

Camel-3 and others have proposed a syntax for declaring variables like
so:

   my type $var :attr1 :attr2 = $val;

However, nobody has really nailed down what C<:attr1> and C<:attr2> are
supposed to do. This takes a shot at it, since this could simplify the
implementation of B<RFC 188>, B<RFC 336>, B<RFC 163>, and others.

=head1 DESCRIPTION

Attributes should be able to access some type of core hooks so that they
can be defined by the user and extended arbitrarily. For example, in
pseudocode, a user should be able to say something like this:

   package Dog;

   attr fluffy {
        causes numeric contexts to fail;
        results in stringification appending "--and fluffy";
   }

Then, if a user does the following:

   my Dog $spot :fluffy = "happy";
   print "$spot";                   # "happy--and fluffy";
   $spot++;                         # fails 

This would allow B<RFC 188>, which proposes new C<private> and C<public>
keywords, to instead be implemented as attributes. This is perhaps more
appropriate since these do not alter lexical scope (unlike C<my> and
C<our>), but rather change properties of the variables themselves:

   package __ALL__;   # some type of builtin global declaration
    
   attr private {
        attachable to hashes and hash keys only;
        marks entire hash as non-autovivifying;
        marks specific entry as private to the package;
        allows duplication of keys in different packages;
        leaves any other entries public;
   }

   attr public {
        attachable to hashes and hash keys only;
        marks specific entry as accessible by all packages;
        would take the entry out of the package symbol table;
   }

In your code, then, you could use the C<:private> and C<:public>
attributes to modify your variables:

   sub new {
         my ($class, %self) = @_;
         bless \%self :private, $class;
         $self{seed} = rand;             # dies, can't autovivify
         $self{seed} :private = rand;    # okay
         $self{seed} = rand;             # now okay
   }

In addition, perhaps we have a BigInt class that we need to be able to
modify:

   package BigInt;

   attr 128bit {
        attachable to any variable;
        causes exception if 128 bits not supported;
        results in huge memory preallocation;
        does other neato stuff too; 
   }

Again, in your code:

   my BigInt $x :128bit;

This would invoke the attribute to modify the variable's properties
internally. By having some type of C<attr> declaration method, the
attribute system could be modifiable at will, allowing for native access
to variable manipulation without the need for to compile a new version
of Perl.

Such a common system would allow those to warp Perl OO into Java or
Python without these features having to be either widely used or
embedded in core. A base class could simply define C<attr>s which other
classes could then inherit from. Attributes would be inherited just like
subs.

Attributes are not necessarily tied to C<my> or C<our> declarations; see
B<RFC 279> for details.

=head1 IMPLEMENTATION

Catch me on a day when I don't have 40+ RFC's to update. :-{

=head1 MIGRATION

None. New functionality.

=head1 REFERENCES

RFC 279: my() syntax extensions and attribute declarations

RFC 218: C<my Dog $spot> is just an assertion

RFC 270: Replace XS with the C<Inline> module as the standard way
         to extend Perl.

RFC 188: Objects: Private keys and methods

RFC 163: Objects: Autoaccessors for object data structures

RFC 336: use strict 'objects': a new pragma for using Java-like
         objects in Perl