HaloO, Nicholas Clark wrote:
No, I think not, because the closure on the last line closes over a read/write variable. It happens that read only reference to the same variable is passed into the subroutine, but that's fine, because the subroutine never writes to *its* reference.
So, you argue that Luke's example should print 42?
Thinking about it in C terms, where pointers and values are explicit, it's as if function arguments are always passed as const pointers to a value in a outer scope. This seems fine and consistent to me, but you can never be sure whether anyone else has another pointer to that same value, which they can modify at any time.
Sure. But I consider this a semantic nightmare. And the optimizer thinks the same. Basically every variable then becomes volatile in C terms :( Note that lazy evaluation does *not* imply permanent refetching. Actually the opposite is true, lazy evaluation implies some capturing of former state as far as the lazied part needs it to produce its content. And item parameters aren't even lazy by default!
If nearly all function parameters are PMCs (internally) I don't think that this is an efficiency problem, as PMCs are always reference semantics, even when loaded into Parrot's registers.
The point I'm argueing about is how exposed subs like Luke's foo should be to this. Essentially I want the invocation of foo to create a COW branchpoint in the outer $bar such that when, from where ever, this value is changed, the former $bar that foo's $x was bound to remains unharmed. And is garbage collected when foo is done with it. -- $TSa.greeting := "HaloO"; # mind the echo!