Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

function parameters aren't readonly *aliases* #2877

Closed
p6rt opened this issue Sep 17, 2012 · 6 comments
Closed

function parameters aren't readonly *aliases* #2877

p6rt opened this issue Sep 17, 2012 · 6 comments
Labels

Comments

@p6rt
Copy link

p6rt commented Sep 17, 2012

Migrated from rt.perl.org#114946 (status was 'resolved')

Searchable as RT114946$

@p6rt
Copy link
Author

p6rt commented Sep 17, 2012

From @nwc10

Well, I don't think that I'm doing anything stupid here, but it's always
a possibility.

Surely if function parameters are readonly *aliases* to the argument
passed to the function, then they should see modifications made to that
argument by other parts of the code. eg

$ cat ../test/aliases.pl
use v6;

my $global = "Perl Rules";

sub baz {
  $global ~~ s/Perl /Perl 6/;
}

sub foo ($bar) {
  say $bar;
  baz;
  say $bar;
  try {
  ++$bar;
  }
  say $!;
}

foo($global);

say "But at the end​: $global";
$ ./perl6 ../test/aliases.pl
Perl Rules
Perl Rules
Cannot assign to a readonly variable or a value
  in sub prefix​:<++> at src/gen/CORE.setting​:1350
  in sub foo at ../test/aliases.pl​:14
  in block at ../test/aliases.pl​:19

But at the end​: Perl 6 Rules

I would have expected the second line to be "Perl 6 Rules", because the
aliased value has been changed by the call to &baz().

$ ./perl6 -v
This is perl6 version 2012.07-270-g5e1b9a8 built on parrot 4.4.0 revision RELEASE_4_4_0

Yes, there is an ulterior motive to this bug report. I'm not confident that
read only aliases are actually an optimiser win. You mustn't assume that the
aliased value remains unchanged by any opaque action, such as a function
call, else you break correctness.

Nicholas Clark

@p6rt
Copy link
Author

p6rt commented Sep 17, 2012

From @jnthn

On Mon Sep 17 09​:34​:45 2012, nicholas wrote​:

Yes, there is an ulterior motive to this bug report. I'm not confident
that
read only aliases are actually an optimiser win. You mustn't assume
that the
aliased value remains unchanged by any opaque action, such as a
function
call, else you break correctness.

I'm not sure the point is optimisability so much as it is stopping
people changing the arguments and accidentally updating things in the
caller, unless that's specifically declared as being the intent (using
'is rw' or the backslash parcel syntax).

As for Rakudo's current semantics, it works by taking the argument from
its container - if it has one - and placing it into a readonly
container. That's why it has the snapshot semantics. It's been that way
for a long time, and it's curious the first ticket that notices is one
trying to prove a point. :-)

/jnthn

@p6rt
Copy link
Author

p6rt commented Sep 17, 2012

The RT System itself - Status changed from 'new' to 'open'

@p6rt
Copy link
Author

p6rt commented Sep 17, 2012

From @nwc10

On Mon, Sep 17, 2012 at 10​:14​:28AM -0700, jnthn@​jnthn.net via RT wrote​:

On Mon Sep 17 09​:34​:45 2012, nicholas wrote​:

Yes, there is an ulterior motive to this bug report. I'm not confident
that
read only aliases are actually an optimiser win. You mustn't assume
that the
aliased value remains unchanged by any opaque action, such as a
function
call, else you break correctness.

I'm not sure the point is optimisability so much as it is stopping
people changing the arguments and accidentally updating things in the
caller, unless that's specifically declared as being the intent (using
'is rw' or the backslash parcel syntax).

Yes, this was what I was wondering. In which case, it would mean that a
read-only copy would be just as effective (from the user point of view) at
achieving this. From the implementation side, if efficient copy-on-write
exists, then it doesn't make much difference, does it?

As for Rakudo's current semantics, it works by taking the argument from
its container - if it has one - and placing it into a readonly
container. That's why it has the snapshot semantics. It's been that way
for a long time, and it's curious the first ticket that notices is one
trying to prove a point. :-)

But I'm not sure what point I'm trying to prove.

I think the initial problem is "Rakudo and the spec disagree. That means that
at least one is wrong."

The backstory​:

It (obviously, or maybe not so obviously) started with the discussions
about function signatures for Perl 5. To my mind (I may not be
representative here), it seems best to stay the same as Perl 5, if there
isn't good reason to do otherwise. So, "read only aliases" seem a sensible
default, on the assumption that they're actually cheap.

But in Perl 5 they don't look to be. (There are no vtables to swap out to
make proxy objects, or something, so you have to do the test for "is this an
alias" everywhere you look at something. This gets expensive.) So it's a
false economy in Perl 5. Getting copy-on-write seems a better plan. Aliases
cost everywhere because you have to chase a pointer to the original.

But it got me thinking - surely Perl 6 has to do this too? With gradual
typing, Perl 6 has a fighting chance of do optimisations that static
languages take for granted. But static languages can't assume too much.
(and related to enthusiastic discussion about LLVM, and what it might be
able to do) in particular, C can't assume that a function call isn't going
to change the value of memory at the end of a pointer. So it can't merge
dereferences from before and after a function call. So a true alias, even if
it's read only, can be treated to all sorts of sensible desirable
optimisations. Whereas a read-only (copy) can.

So it comes back to "Rakudo and the spec disagree". Rakudo seems to actually
be implementing read only copies, on the basis that this is more performant.

But if this is a much better strategy, who is right long term? The spec?
In which case, is Rakudo going to have to be fixed to match the spec? And
pessimise 99% or more of programs for a pathological few? That doesn't
feel right.

But it also feels very wrong that the spec says one thing, and the
implementation does something else.

So I guess my question is really a request to step back, and answer
"what is the spec trying to achieve here?" Because I'm not comfortable
that the design it describes aligns with its underlying goals.

Nicholas Clark

@p6rt
Copy link
Author

p6rt commented Dec 18, 2015

From @jnthn

On Mon Sep 17 09​:34​:45 2012, nicholas wrote​:

Well, I don't think that I'm doing anything stupid here, but it's
always
a possibility.

Surely if function parameters are readonly *aliases* to the argument
passed to the function, then they should see modifications made to
that
argument by other parts of the code. eg

$ cat ../test/aliases.pl
use v6;

my $global = "Perl Rules";

sub baz {
$global ~~ s/Perl /Perl 6/;
}

sub foo ($bar) {
say $bar;
baz;
say $bar;
try {
++$bar;
}
say $!;
}

foo($global);

say "But at the end​: $global";
$ ./perl6 ../test/aliases.pl
Perl Rules
Perl Rules
Cannot assign to a readonly variable or a value
in sub prefix​:<++> at src/gen/CORE.setting​:1350
in sub foo at ../test/aliases.pl​:14
in block at ../test/aliases.pl​:19

But at the end​: Perl 6 Rules

I would have expected the second line to be "Perl 6 Rules", because
the
aliased value has been changed by the call to &baz().

$ ./perl6 -v
This is perl6 version 2012.07-270-g5e1b9a8 built on parrot 4.4.0
revision RELEASE_4_4_0

Yes, there is an ulterior motive to this bug report. I'm not confident
that
read only aliases are actually an optimiser win. You mustn't assume
that the
aliased value remains unchanged by any opaque action, such as a
function
call, else you break correctness.

Indeed, and we didn't implement it as readonly aliases, and if we did go with that behavior then it would enormously hinder things like spesh and invokedynamic in their optimization work. So, now the design docs are in line with what's actually been implemented​:

Raku/old-design-docs@1903a509e3

@p6rt
Copy link
Author

p6rt commented Dec 18, 2015

@jnthn - Status changed from 'open' to 'resolved'

@p6rt p6rt closed this as completed Dec 18, 2015
@p6rt p6rt added the Bug label Jan 5, 2020
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

1 participant