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

Re: lvalues and "is rw" parameter passing

1 view
Skip to first unread message

Patrick R. Michaud

unread,
May 16, 2006, 4:24:20 PM5/16/06
to Chip Salzenberg, Leo Toetsch, Audrey Tang, perl6-i...@perl.org
On Tue, May 16, 2006 at 09:00:17AM -0700, Chip Salzenberg wrote:
> On Fri, Apr 14, 2006 at 06:17:01PM -0500, Patrick R. Michaud wrote:
> > How would you envision doing something like the following
> > Perl 6 in PIR?
> >
> > sub foo($x is rw) {
> > $x = new SomeClass
> > }
> >
> > @z = 0..2;
> > foo( @z[1] );
>
> I suspect that this problem is quite deep and may require significant
> changes to Parrot. But I don't want to jump to conclusions, because my Perl
> 6 is not as good as yours.

It's entirely possible my Perl 6 isn't accurate here, either.

My intent is that after the call to 'foo', @z[1] should be an
instance of SomeClass because $x was a rw parameter in foo.
(For clarity I probably should've written @z = (0, 1, 2);
instead of @z = 0..2; above, I forgot that ranges are lazy in Perl 6.
Let's treat it as written that way for the remainder of this thread.)

I don't think the naive PIR translation (complete copy at bottom of message)
expresses the intent, at least not within current Parrot capabilities. In
particular, AFAIK "foo"(z[1]) isn't a valid call in Parrot.
I suppose it could be made to be valid. But even then, I wonder
about:

.sub foo
.param pmc x
$P0 = new .SomeClass
x = $P0
.return ()
.end

IIUC, the x = $P0 line translates into a "set" opcode -- i.e.,
it causes the local x pmc register to rebind to the SomeClass object,
but doesn't affect the object x was previously bound to. So that
doesn't seem to do it.

Assuming that "assign" was meant here, as in

.sub foo
.param pmc x
$P0 = new .SomeClass
assign x, $P0
.return ()
.end

this would seem to imply that pmc x is something that knows to
morph its type into a .SomeClass object, regardless of what x (@z[1])
was when sub foo was invoked.

> I've made a naive translation of the above code
> into PIR below. Does it correctly express the intent of the above code? If
> not, is it possible to express this problem in Perl 5?

Yes, somewhat, since parameters are already passed rw in Perl 5:

#!/usr/bin/perl

use Digest;

sub foo { $_[0] = Digest->new('MD5'); }

@z = (0, 1, 2);
foo($z[1]);

print "@z\n"; # outputs "0 Digest::MD5=Scalar(...) 2\n"

The key question revolves around foo changing the second element of
@z to no longer be an Int.

Going back to the original Perl 6 code, I'll note that the problem
exists for scalars as well -- i.e., after

sub foo($x is rw) { $x = new SomeClass; }

my $y = 3;
foo($y);

the $y lexical is a SomeClass object and not an Int. So, how
does .sub foo make that happen? (I posed the array version simply
because it seems to cover more of the issues involved.)

> While you're at it, could you explain how the above code is problematic
> while, presumably,
> $x = 1
> is OK? (... or is it?)

I think it's OK only if we change the naive PIR to use 'assign'
instead of 'set', and then only because $x happens to already be
an Int when foo is called. To bring it down to base types,
what about:

sub foo($x is rw) { $x = 'hello'; }

my $y = 3;
foo($y);

Can Parrot make this work if the Int type (.Integer) isn't
automatically morphing into a Str (.String)?

Thanks,

Pm


Full Naive PIR translation from Chip:
>
> .sub main :main
> .local pmc z i
> z = new .ResizablePMCArray
>
> # assignment of z[0] and z[2] omitted for brevity
> i = new .Integer
> i = 1
> z[1] = i
>
> "foo"(z[1])
> .end
>
> .sub foo
> .param pmc x
> $P0 = new .SomeClass
> x = $P0
> .return ()
> .end

Chip Salzenberg

unread,
May 16, 2006, 4:54:08 PM5/16/06
to Patrick R. Michaud, Leo Toetsch, Audrey Tang, perl6-i...@perl.org
On Tue, May 16, 2006 at 03:24:20PM -0500, Patrick R. Michaud wrote:
> On Tue, May 16, 2006 at 09:00:17AM -0700, Chip Salzenberg wrote:
> > On Fri, Apr 14, 2006 at 06:17:01PM -0500, Patrick R. Michaud wrote:
> > > How would you envision doing something like the following
> > > Perl 6 in PIR?
> > >
> > > sub foo($x is rw) {
> > > $x = new SomeClass
> > > }
> > >
> > > @z = 0..2;
> > > foo( @z[1] );
> >
> > I suspect that this problem is quite deep and may require significant
> > changes to Parrot. But I don't want to jump to conclusions, because my Perl
> > 6 is not as good as yours.
>
> It's entirely possible my Perl 6 isn't accurate here, either.
> My intent is that after the call to 'foo', @z[1] should be an
> instance of SomeClass because $x was a rw parameter in foo.

I sympathize with your desire for an answer, but it's probably a good idea
for you to get the sample code and desired behavior right in all its Perl 6
details before we go further. As for me, I'm not sure what the "=" in &foo
is *supposed* to do in Perl 6. I think it does what you suggest, but I'm
not entirely sure. And I'm even less sure whether ":=" in the same place
would be legal, and if it were, what it would mean.

Furthermore, I think you'll need to ask Audrey or Larry about the
implications of the Perl 6 container/value dichotomy on your example. Now
that Perl 6 scalars consist of containers that hold values, every Perl 6
scalar is made up of two distinct PMCs[*], so it seems to me that you're
likely to be able to do what you want with current Parrot.

[*] except for the containers that can't hold PMCs, e.g. C<my int $i>.

The reason I think you need to do this first is that "is rw" with "=" is a
common case, while supporting ":=" probably isn't. As an extreme
possibility, if "is rw" makes a deep enough alias to amount to call-by-name,
Perl 6 may need to pass all "is rw" parameters as implicit references, and
dereference them automatically and invisibly at each use.

Look before I leap.


> AFAIK "foo"(z[1]) isn't a valid call in Parrot.

I meant that to be the equivalent of

$P0 = z[1]
"foo"($P0)


> I suppose it could be made to be valid. But even then, I wonder
> about:
>
> .sub foo
> .param pmc x
> $P0 = new .SomeClass
> x = $P0
> .return ()
> .end
>

> [... ] Assuming that "assign" was meant here [...]

It was, mea culpa.


> I think [changing '= new SomeClass' to '= 1' is] OK only if we change the


> naive PIR to use 'assign' instead of 'set', and then only because $x
> happens to already be an Int when foo is called. To bring it down to base
> types, what about:
>
> sub foo($x is rw) { $x = 'hello'; }
>
> my $y = 3;
> foo($y);
>
> Can Parrot make this work if the Int type (.Integer) isn't automatically
> morphing into a Str (.String)?

I infer that in Perl 6, assigning '1' is at root the same problem as
assigning 'new SomeClass', because morphing is *not* assumed to be an
ability of most types, so it may be necessary to store a new value of a
completely new type in the given target container.
--
Chip Salzenberg <ch...@pobox.com>

Audrey Tang

unread,
May 16, 2006, 9:14:40 PM5/16/06
to Chip Salzenberg, perl6-i...@perl.org
Chip Salzenberg wrote:
> <speculation>
> All that's needed is for the Perl 6 implementors to create a perl6;Scalar
> container that's more or less a translucent reference: It will handle
> assignment by switching to a new value, but it will handle most other
> operations by delegating to the value it currently holds.
> </speculation>
>
> Audrey, is this basically your plan for (scalar) containers? If not, what is?

Yes, that is basically my plan.

Thanks,
Audrey

signature.asc
0 new messages