-preview=in might break code

Steven Schveighoffer schveiguy at gmail.com
Sat Oct 3 17:05:12 UTC 2020


On 10/3/20 12:49 PM, Ola Fosheim Grøstad wrote:
> On Saturday, 3 October 2020 at 15:58:53 UTC, Steven Schveighoffer wrote:
>> Given that it's a parameter, and the parameter is const, it can only 
>> change through another reference. And this means, the function has to 
>> deal with the possibility that it can change, but ALSO cannot depend 
>> on or enforce being able to change it on purpose. On that, I think I 
>> agree with the concept of being able to switch to a value.
> 
> But you can expect it to not change in parallell as it is not shared!? 
> It can change if you call another function or in the context of a 
> coroutine (assuming that coroutines cannot move to other threads).

You can expect it to change but due to the way it enters your function, 
you can't rely on that expectation, even today.

For example:

void foo(const ref int x, ref int y)
{
    auto z = x;
    bar(); // might change x, but doesn't necessarily
    y = 5; // might change x, but doesn't necessarily
}

So given that it *might* change x, but isn't *guaranteed* to change x, 
you can reason that the function needs to deal with both of these 
possibilities. There isn't a way to say "parameter which is an alias of 
this other parameter".

In that sense, altering the function to actually accept x by value 
doesn't change what the function needs to deal with.

On the other hand, if the compiler normally passes x by value, and you 
rely on that current definition, and the definition changes later to 
mean pass by reference, then you now have code that may have had a 
correct assumption before, but doesn't now.

> 
> My key point was this, I've never seen "ref" mean anything else than a 
> live view of an object. If D is going to be an easy to learn language 
> anything named "ref" has to retain that expectation.

And in a sense, you can rely on that. At a function level, you can't 
tell whether mutating other data is going to affect `in ref` or `const 
ref` data. You have to assume in some cases it can, and in some cases it 
cannot.

>> What I don't agree with is the idea that one can write code expecting 
>> something is passed by value, and then have the compiler later switch 
>> it to a reference. `in` means by value in all code today. The fact 
>> that we tried -preview=in on a bunch of projects and they "didn't 
>> break" is not reassuring.
> 
> Well, it is common for compilers (e.g. Ada/SPARK) to optimize by-value 
> as a reference, but it should not be observable.

If we could have this, it would be useful as well, but doesn't need a 
language change. You might be able to do this in pure functions.

> You could get around this by making the by-value parameter transfer 
> "no-alias" with associated undefined behaviour (or "__restricted__" in 
> C++ as Kinke pointed out). This would be great actually, except...
> 
> "in" looks very innocent to a newbie so it should have simple 
> semantics... Advanced features ought to look advanced (at least more 
> advanced than "in" or "out").

Yeah, that's why I think `in ref`, can be used (or even `const ref`).

That being said, if `in` didn't have the definition it already has, this 
would not be as controversial.

-Steve


More information about the Digitalmars-d mailing list