Beefy Boxes and Bandwidth Generously Provided by pair Networks
There's more than one way to do things
 
PerlMonks  

Re^2: Shouldn't references be readonly?

by LanX (Saint)
on Aug 05, 2020 at 02:01 UTC ( [id://11120305]=note: print w/replies, xml ) Need Help??


in reply to Re: Shouldn't references be readonly?
in thread Shouldn't LITERAL references be readonly? (updated)

I'm wondering how you are defining "literal"?

Cheers Rolf
(addicted to the Perl Programming Language :)
Wikisyntax for the Monastery

Replies are listed 'Best First'.
Re^3: Shouldn't references be readonly?
by Fletch (Bishop) on Aug 05, 2020 at 02:27 UTC

    Unlike a numeric literal value, [] is compiled into an opcode which calls . . . something (this is where I'm hoping someone more familiar with guts steps in) which returns a new reference value.

    $ perl -MO=Concise,-exec, -E '$a = []; $b = 5' 1 <0> enter v 2 <;> nextstate(main 2 -e:1) v:%,us,{,fea=7 3 <0> pushmark s 4 <@> anonlist sK* 5 <#> gvsv[*a] s 6 <2> sassign vKS/2 7 <;> nextstate(main 2 -e:1) v:%,us,{,fea=7 8 <$> const[IV 5] s 9 <#> gvsv[*b] s a <2> sassign vKS/2 b <@> leave[1 ref] vKP/REFC

    Opcode 4 here is doing something to allocate a new AV* and pushing the SVrv referencing that new arrayref onto the stack which then is assigned into $a. Opcode 8 is pushing the immediate literal value SViv (which is readonly) onto the stack and assigning that into $b.

    Edit: I'm mixing up the layers and perl and C and everything but . . .

    When you have map { $_ = 1 } [] in the underlying runtime what's kind of happening is that something's going:

    my @args; $args[0] = anonlist();

    then when your map EXPR, @args runs, because $_ is aliased to each item in @args something like this happens

    $args[0] = 1;

    The anonymous arrayref went into the temporary array's slot zero when it was initialized; in the map EXPR you're replacing the value in that slot in the array but you're not doing anything to the arrayref which was referenced by the previous value in that same slot. I admit that it's kind of weird that the temporary arglist slots aren't readonly but if they were made readonly then I don't think aliasing like $a = 1;for($a){ $_ = 'foo' } would work so that $a would have 'foo' afterwards (i.e. aliasing of $_ in for to a transient list of arbitrary values).

    Edit 2: while [] is a literal token it doesn't stand for a constant value.

    The cake is a lie.
    The cake is a lie.
    The cake is a lie.

      Im asking about logic and you are arguing with implementation.

      I haven't seen a logical reason why Perl shouldn't throw an error if the alias to a ref is overwritten.

      My suspicion is that the ugly truth is that the readonly flag is (mis)used for indicating if the referenced data structure is "constant" not the reference itself.

      Cheers Rolf
      (addicted to the Perl Programming Language :)
      Wikisyntax for the Monastery

Re^3: Shouldn't references be readonly?
by chromatic (Archbishop) on Aug 05, 2020 at 17:28 UTC

    They're constructors for containers, not values. I'm not sure what the value would be to make [] and {} create singleton immutable containers.

      I'm talking about the container not the content.

      I can't see a reason why one would want to change the alias of the container, hence this should throw an error.

      Cheers Rolf
      (addicted to the Perl Programming Language :)
      Wikisyntax for the Monastery

Re^3: Shouldn't references be readonly?
by jcb (Parson) on Aug 05, 2020 at 21:43 UTC

    I am considering "literals" as more like constants embedded in the program, using a constant pool, where changing a value would have bizarre effects, like changing the value of "123456" everywhere in the program. Literal strings in C programs are often combined in this way.

    The {} and [] operators are defined to produce distinct mutable aggregates every time they are evaluated. In this sense, they are not literals.

    I am unsure how this behavior of replacing the reference itself is actually useful, but nor do I see any harm here.

      > I am considering "literals" as more like constants embedded in the program,

      I understand your POV ...

      ... BUT literals with the exception of undef are not constant!

      Re^2: Shouldn't references be readonly?

      It's always a new ref, hence constructed.

      The semantics in JS are 100% the same, and they refer to [] and {} as "literal (object) constructors"

      And I can't find any definition claiming literals to be constants, I think that was made up in this thread.

      Cheers Rolf
      (addicted to the Perl Programming Language :)
      Wikisyntax for the Monastery

        Perl is not JS. Does JS even have references as first-class values like Perl does?

        I just tested it and was surprised that overwriting a reference to a literal number or string through $_ in map raises an error, even if multiple layers of references are involved, but overwriting a reference (even through metareferences) to an array is fine.

        Devel::Peek reveals that the READONLY flag is apparently copied by the \ operator. If you start with a literal value, such as 1 or "abc" (which has the READONLY flag) the references are similarly seen to be read-only values, but if you start with an anonymous aggregate, which is mutable, the references are mutable. I would argue that, if there is a bug here, it is that references to constants, which should themselves (the references) be mutable, are incorrectly marked read-only.

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: note [id://11120305]
help
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others studying the Monastery: (4)
As of 2024-03-29 04:41 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found