-preview=in might break code

Ola Fosheim Grøstad ola.fosheim.grostad at gmail.com
Sat Oct 3 19:36:43 UTC 2020


On Saturday, 3 October 2020 at 17:05:12 UTC, Steven Schveighoffer 
wrote:
> 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.

I am happy that we seem to agree on the principles, but I am a 
bit perplexed by this statement as we seem to draw different 
conclusions from the same principles...
:-D

I think maybe we have different use-cases in mind. So let me give 
you one. Assume that many SimulationObject instances form a graph 
accessible through a Simulation instance:

void run_and_print(const ref SimulationObject objview, ref 
Simulation world){
    auto old_state = objview.get_state();
    world.run_simulation();
    print_difference(old_state, objview.get_state());
}

If "objview" is turned into a value, nothing changes. objview is 
a view of one object in the "world" graph. A deliberate aliasing 
reference.

I don't want this behaviour from something named "ref", const or 
not const.

> 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.

Do you mean the compiler or the programmer? As a programmer I 
most certainly can know this, which is why "__restricted__" 
semantics would be acceptable for me (although not newbie 
friendly).

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

I think it would be interesting if "in", "in out" and "out" had 
100% compatible semantics with SPARK. D could get verification 
for free as the SPARK verifier is a separate tool. All you have 
to do is find a mapping from D to SPARK and generate the 
verification-condition output. (or just transpile to SPARK).

I think that could be a very powerful upgrade that could make D 
more favourable for embedded programming.



More information about the Digitalmars-d mailing list