Perl6 RFC Librarian <[EMAIL PROTECTED]> writes:

> This and other RFCs are available on the web at
>   http://dev.perl.org/rfc/
> 
> =head1 TITLE
> 
> Transparently integrate C<tie>

On the whole I think I'm liking this. But it needs work.

>    my packed $a;       # just an assertion, RFC 218
>    $a = get_binary;    # packed->TIESCALAR($a); $a->STORE(..);

I'm not sure there's any reason to delay the tie; It kind of depends
on what happens to stuff like 'defined($a)'. RFC 218 was brought
forward because I didn't want magic to be happening in cases where
C<my Foo $bar> was using a Foo that was a superclass, and there was no
mechanism for knowing that at the time. 

I'm kind of curious to know what you think would happen with the
following. I've commented where I'm confident...

    interface Number;
    sub TIESCALAR;
    sub STORE;
    sub FETCH;
    
    package integer implements Number; # I really like this notation
    sub TIESCALAR {...};
    sub STORE {...};
    sub FETCH {...};

    my Number $i;       # Number is an interface, so just an assertion
    my integer $n;      # integer->TIESCALAR($n);
    my non_tied $object;# Just an assertion
    defined($n);        # Should be false

    $n = 5;
    $i = $n;            
    $n = 10;
    print $i;           
    $i = $object;       # Assertion fails

>    $a = more_data;     # $a->STORE(...);
>    $a++;               # $a->STORE($a->PLUS(1));
>    undef $a;           # $a->DESTROY;
> 
>    my int @b :64bit;   # again, just an assertion

Asserting what? That's not valid syntax at the moment.

>    @c = @b;            # empty list passed still
>    @b = (1,2);         # int->TIEARRAY(@a, '64bit'); @b->CLEAR(...);
>    ...

Hmm... I think this is somewhat ugly. Assuming that you want
C<my int @b> to imply C<UNIVERSAL::isa(all(@a), 'int')> then tying the
entire array seems a bit weird.

> Note that the C<TIE*> methods will only be called if they exist, just
> like currently. If a given C<TIE*> method does not exist, then the
> appropriate error should be spit out:
> 
>    my Pet @spot = ("fluffy");
>    Can't locate method "TIEARRAY" via package "Pet"
> 
> In this case, the package C<Pet> has declared that it can't handle
> arrays, which is just fine.

Er... You seem to be implying here that *all* classes should have TIE
methods. Which is not good. It's especially not good in cases where
the class is actually an interface. Hmm... maybe we should have the tie
behaviour only happen if the package is declared as implementing an
appropriate 'Tie::Foo' interface:

    package integer implements Tie::Scalar;

Note that this would imply that the Tie::Foo modules in the standard
library become interfaces, but I'm not sure that that would be any
great loss...

> =head2 Optimization and Inheritance
> 
> One of the main goals behind doing something like this is being able to
> create custom variable types that can take advantage of optimizations,
> and having these variables walk and talk like builtins.
> 
> For this reason, it is further proposed that all variable types be
> handled through basic method inheritance in Perl 6. Essentially,
> everything becomes an object and is fully overrideable and redefineable.
> So, for example:

Whoa, now you're stretching.

> [...]

> =head2 Type checking
> 
> Nat's upcoming RFC on type checking will propose a C<use strict 'types'>
> pragma. Type checking would be trivial to implement by combining aspects
> of this RFC with the C<use optimize> concept:
> 
>    package Pet : interface;   # RFC 265
>    use optimize types => ['Dog', 'Cat'];
> 
> With this declaration, Perl is now told that anything of type C<Pet> can
> be either a C<Dog> or a C<Cat>. 

Err... Specifying which classes implement an interface in the
interface specification is Wrong Wrong Wrong.

> This means that in your main code:
> 
>    use strict 'types';
>    my Pet $spot = new Camel;   # oops!
> 
> The second line would raise a syntax error.

If your client code wants to insist that the only pets it's interested
in are Dogs or Cats then you should make that assertion somewhere.
You certainly shouldn't assert it in the interface declaration.
Check out the 

    my Pet $spot : isa(any(qw/Dog Cat/)) = new Camel; # oops!

style that I proposed elsewhere.

> =head2 The C<:tie> attribute
> 
> Making C<tie> this seamless may scare some people. In this case, we may
> wish to add an C<:tie> attribute that can be specified on the
> C<package>:
> 
>    package Pet : tie;     # will be auto-tied

Can I just point out that nobody has yet proposed that you can attach
attributes to a package?

> 
> Placing this on the package, and not individual subs, makes more sense
> because it dictates how all the package's methods interact.
> 
> The idea here is that by fully integrating these concepts, a separate
> C<tie> function will no longer be necessary and will instead be replaced
> by a simple C<:tie> package attribute (or no attribute at all).

I'm not entirely sure what you're driving at here. I thought you were
arguing that *all* packages that created objects would use tie magic,
in which case the new attribute becomes unnecessary. And if you're not
proposing that then :tie is too general in the cases where the module
can only tie to specific variable types. I think you get better
granularity with interfaces, which are way more general than a special
new attribute.

As far as I can see there's the germ of a good idea in this RFC, but
you seem to be way too ambitious in terms of its scope.

-- 
Piers

Reply via email to