Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

E6 (sort of): All levels of complex data structs marked ro?

8 views
Skip to first unread message

Rick Delaney

unread,
Aug 2, 2003, 5:09:00 PM8/2/03
to perl6-l...@perl.org
As I understand it, the comments in the following two subs are correct.

sub foo (@array) {
my $x = @array[0]; # ok, allowed to read
@array[0] = "something"; # compile fails because '@array is ro'
}

sub bar (@array_2d) {
my $x = @array[0]; # ok, allowed to read
$x[0] = "something"; # ok, said nothing about contents
}

That is, you can't STORE into a read-only variable, but if the thing
you FETCH has its own STORE method then that method will work fine.

What I would like is something like the following to prevent corruption
of complex data structures passed to subroutines.

sub baz (@array_2d is very_read_only) {
my $x = @array[0]; # ok
$x[0] = "something"; # would croak at runtime but ...
@array[0][0] = "something"; # ... this already failed to compile
}

Are there any plans for such a trait or would it be easy for a user to
implement? I have no idea how to implement it; presumably the
variable's FETCH method would return an alias with the same
very_read_only trait attached. I'm sure this ain't even close:

method FETCH ($var, $index) {
my $val = $var[$index];
return $val unless $val.can("STORE");
my $x is very_read_only := $val;
return $x;
}

And how the trait connects to the FETCH-replacing I don't even know
where to begin.

--
Rick Delaney
rick.d...@rogers.com

Luke Palmer

unread,
Aug 2, 2003, 9:10:46 PM8/2/03
to rick.d...@rogers.com, perl6-l...@perl.org
> As I understand it, the comments in the following two subs are correct.
>
> sub foo (@array) {
> my $x = @array[0]; # ok, allowed to read
> @array[0] = "something"; # compile fails because '@array is ro'
> }
>
> sub bar (@array_2d) {
> my $x = @array[0]; # ok, allowed to read
> $x[0] = "something"; # ok, said nothing about contents
> }
>
> That is, you can't STORE into a read-only variable, but if the thing
> you FETCH has its own STORE method then that method will work fine.

Yeah, I think so. It might be that the first C<@array[0] =
"something"> is actually valid, and the only things that would be
invalid would be calling mutating methods on the array itself (like
C<pop>). These are details that will probably be worked out in the
next Apocalypse, "references".

And as far as compile time stuff, this would (unfortunately) be legal
(but croak at runtime):

sub foo (@array) {
my @myarr := @array;
pop @myarr;
}

Getting that to complain at compile time is equivalent to the halting
problem.

> What I would like is something like the following to prevent corruption
> of complex data structures passed to subroutines.
>
> sub baz (@array_2d is very_read_only) {
> my $x = @array[0]; # ok
> $x[0] = "something"; # would croak at runtime but ...
> @array[0][0] = "something"; # ... this already failed to compile
> }

Hmm, I can think of a very C++-esque oververbose declaration:

sub baz (@array_2d of (Array is constant)) { ... }

That seems okay, but it gets ugly really really fast.

sub baz (@array_3d of (Array of (Array is constant) is constant))
{ ... }

It's especially worrysome because the word C<constant> is so far away
from what it saying is constant. It might be that you can say:

sub baz (@array_2d of (Array is constant of (Array is constant)))
{ ... }

But I wonder whether that second C<of> is actually going with
C<constant>. It'd be nice to see the grammar for these sorts of
things.


> Are there any plans for such a trait or would it be easy for a user to
> implement? I have no idea how to implement it;

Yeah, nobody's quite sure how to implement traits yet ;-)

> presumably the variable's FETCH method would return an alias with
> the same very_read_only trait attached. I'm sure this ain't even
> close:
>
> method FETCH ($var, $index) {
> my $val = $var[$index];
> return $val unless $val.can("STORE");
> my $x is very_read_only := $val;
> return $x;
> }

It might need to be a bit more declarative to get things to work at
compile time.

Luke

Larry Wall

unread,
Aug 2, 2003, 11:35:22 PM8/2/03
to perl6-l...@perl.org
On Sat, Aug 02, 2003 at 07:10:46PM -0600, Luke Palmer wrote:
: Yeah, I think so. It might be that the first C<@array[0] =

: "something"> is actually valid, and the only things that would be
: invalid would be calling mutating methods on the array itself (like
: C<pop>).

Maybe not even that restrictive. To the first approximation, I mostly
care about whether I have to autovivify on the caller end. I don't
if parameter passing is by copy. I also don't if the parameter is a
reference but it doesn't have to function as an lvalue within the sub.
If we can get more mileage out of the implicit constant declaration,
that's fine, but it wasn't my primary motivation. I'm certainly
not going to clutter up the language with constant declarations like
C++.

: These are details that will probably be worked out in the
: next Apocalypse, "references".

Except the next Apocalypse won't be the next Apocalypse.

Larry

0 new messages