develooper Front page | perl.perl5.porters | Postings from July 2013

[perl #109744] referenced constant loses readonlyness

Thread Next
From:
Father Chrysostomos via RT
Date:
July 31, 2013 03:07
Subject:
[perl #109744] referenced constant loses readonlyness
Message ID:
rt-3.6.HEAD-2552-1375240060-1096.109744-15-0@perl.org
On Fri Jul 26 09:17:22 2013, zefram@fysh.org wrote:
> Father Chrysostomos via RT wrote:
> >I'm afraid the second one sounds stupid because I am biased against it
> >and know not how to express it convincingly.
> 
> The position to which you refer comes from a conceptual distinction
> between variables and values.  A value is (conceptually) inherently
> immutable.  A variable is a storage location that contains a value, and
> is mutable in that it can contain different values at different times.
> Two variables that presently contain the same value are functionally
> distinguishable because one can write a new value to one of them and
> observe that they now contain different values.
> 
> The position, then, is an instance of Occam's razor: one should not
> gratuitously generate variables.  A non-lvalue expression, such as $a+1,
> conceptually yields a value, not a variable.  As the Perl language
> allows the refgen operator to be applied to this expression, inevitably
> we can get this value into an lvalue situation and try assigning to it.
> Applying Occam's razor, this process should not have generated a variable,
> and so assignment must fail.  If assignment is not to fail, then we have
> created a variable somewhere, and whichever operator did that ought to
> be documented as having that effect.  In the case of \($a+1), apparently
> either the addition or the refgen operator is creating variables, either
> of which is somewhat surprising.

Considering that \ and foreach can autovivify, I do not find that
surprising at all.  In fact, you haven given me a clear way to express
something that I understood intuitively but had difficulty explaining. 
I thank you for that.

If $a+$b returns a value, not a variable, then we could say that \ and
for(...) and func(...) impose ‘variable context’.

This makes it similar to the way @a and %h work on the lhs of
assignment.  The thing the expression evaluates to is an array or hash,
but bare arrays or hashes cannot be passed around in perl, so there is
no way to inspect that list as-is.  Everything in perl is looked at
through scalar variables.  If you write \(@a, %h), you get scalar
variables reference the two aggregates.  If you write func(@a,%h), you
see the scalar elements (and keys).  If you write scalar(@a) you get a
brand new scalar variable with information about the array.

Likewise, \ imposes a context that requires that a scalar variable be
returned.  The same for for(...) and func(...).

(Note that the term ‘variable’ does not necessarily exclude read-only
scalars.  $^S is certainly a variable, but it is read-only.  And in the
end distinguishing between &PL_sv_undef and $^S and considering them to
be of different types is not all that useful, even though one is
constant and the other is not--they are both read-only scalars.)

Under that model, there is no reason why something called a constant
cannot return a mutable scalar.  In that case it is the context that is
reifying the constant value into a mutable scalar.

Whether we should follow that model is hard to say.  The other model,
where ‘constant’ means ‘read-only scalar’ breaks CPAN modules.  See
tickets #119043 and #119045.

-- 

Father Chrysostomos


---
via perlbug:  queue: perl5 status: open
https://rt.perl.org:443/rt3/Ticket/Display.html?id=109744

Thread Next


nntp.perl.org: Perl Programming lists via nntp and http.
Comments to Ask Bjørn Hansen at ask@perl.org | Group listing | About