Why pass by reference?

2009-06-14 Thread John M. Dlugosz
In Perl 6, the default parameter passing is to make a read-only alias 
for the caller's lvalue.  This means that the function may not change 
the caller's variable, but must track changes to it made by other means.


What is the point?

It is a contrivance to illustrate how the variable can be changed by 
other means, and requires a global variable, the same variable passed as 
two different parameters, or the variable and a closure that affects the 
variable be passed.


In fact, this effect seems like something that should be warned against, 
not something that is touted as a feature.


It complicates the passing, requiring a read-only proxy or equivalent be 
introduced, making the readonly parameter more complex than the rw 
parameter.  It makes the actual access more complex, having to go 
through this extra layer.  It prevents optimizations, since you have 
more plumbing to go through and you have to watch for aliasing (that's 
the feature!) instead of assuming the value doesn't change between accesses.


In Perl 5, the @_ is a normal alias (read/write), and most parameters 
are copied to local variables, making it essentially pass-by-value.  The 
local variable is pass-by-value, and looking back at the @_ is pass by 
reference.  There is no feature like Perl 6's default readonly passing 
(read-only reference).  So it's not for historical use.  At least not as 
the default method!


So, I ask:  is there any reason to want this read-only reference as a 
passing method?  And if so, why does that preclude having the simple 
pass-by-value method available also?


From the typical Perl 5 usage, I would think that pass-by-value should 
be the default.


--John



Re: Why pass by reference?

2009-06-14 Thread Daniel Ruoso
Em Dom, 2009-06-14 às 15:53 -0500, John M. Dlugosz escreveu:
 In Perl 6, the default parameter passing is to make a read-only alias 
 for the caller's lvalue.  This means that the function may not change 
 the caller's variable, but must track changes to it made by other means.
 What is the point?
 It is a contrivance to illustrate how the variable can be changed by 
 other means, and requires a global variable, the same variable passed as 
 two different parameters, or the variable and a closure that affects the 
 variable be passed.

Actually, it only looks complicated while you think only on the callee
side. Because when you take the caller side, you'll note that it builds
a capture to send to the call, and the capture is always a reference, so
the signature just makes sure that references becomes read-only. To
illustrate:

 my $a = 1;
 foo($a);

In this case, the capture sent must contain a direct reference to the
scalar held in '$a', so both signatures with is ref or signatures with
is copy can work.

So, if foo has the signature

 sub foo($a is ref) {...}

it will be able to change the scalar outside foo. If it is

 sub foo($a) {...}

It will be a read-only access to that scalar

 sub foo($a is rw) {...}

Works almost like is ref, but encloses immutables into a container in
order to always provide rw semantics.

 sub foo($a is copy) {...}

Is the completely opposite to is ref, copying the actual value to a
new container.

So, it is not at all complicated, it's just oriented to the Capture, and
the capture provides semantics to the call that are not present in any
other language I'm aware of.

daniel



Re: Why pass by reference?

2009-06-14 Thread John M. Dlugosz

Daniel Ruoso daniel-at-ruoso.com |Perl 6| wrote:

Actually, it only looks complicated while you think only on the callee
side. 
No, in general it requires introducing a read-only proxy in front of the 
container.  This may be optimized away when it can be tracked at 
compile-time, but that's certainly not simple as compared to not 
having it nor the aliased item container at all.




Because when you take the caller side, you'll note that it builds
a capture to send to the call, and the capture is always a reference, so
the signature just makes sure that references becomes read-only. To
illustrate:

 my $a = 1;
 foo($a);

In this case, the capture sent must contain a direct reference to the
scalar held in '$a', so both signatures with is ref or signatures with
is copy can work.

So, if foo has the signature

 sub foo($a is ref) {...}

it will be able to change the scalar outside foo. If it is

 sub foo($a) {...}

It will be a read-only access to that scalar

 sub foo($a is rw) {...}

Works almost like is ref, but encloses immutables into a container in
order to always provide rw semantics.
  
No, is rw does not like immutables.  It will cause autovivification to 
take place, but will not accept something that is not an lvalue such as 
1 or Hello literals.  This was just doubled-checked with S06, S09, and 
discussion with Larry in #perl6.  If Ra


   ruosorakudo: sub foo($a is rw) { $a += 1; say $a }; foo(1);
   p6eval   rakudo 77f9d7: OUTPUT«2␤»

that directly contradicts S06, which states Otherwise the signature 
fails to bind, and this candidate routine cannot be considered for 
servicing this particular call.  Doing otherwise affects the semantics 
of MMD for allowing overloading based on whether the parameter is an 
lvalue or not.


Somebody who works with rakudo could submit a bug, if it's not in there 
already?






 sub foo($a is copy) {...}

Is the completely opposite to is ref, copying the actual value to a
new container.
  

Agreed.

So, it is not at all complicated, it's just oriented to the Capture, and
the capture provides semantics to the call that are not present in any
other language I'm aware of.

  


Complex or not in that sense, it complicates things in allowing the 
value to be changed by another path.  I think that is something we want 
to avoid doing, not present as a feature.  Much of my original post 
concerns the actual meaning, not whether it is considered simple.


Since then, I see that it is useful for plural containers.  We don't 
want to copy them!  But for items, why do we not even _have_ pass by 
value?  The compiler must assume the worst and can't optimize as well.


--John