preview in: it seems that return type auto solves scope variable assignment to this

tsbockman thomas.bockman at gmail.com
Fri Feb 10 02:45:21 UTC 2023


On Thursday, 9 February 2023 at 21:28:54 UTC, Dmytro Katyukha 
wrote:
> So, the next questions:
> - Do it have sense to explicitly annotate all (most) member 
> methods of a struct with `scope` attribute?
> ...
> - What drawbacks of annotating all (most) parameters as scope?

`scope` restricts what a function's implementation can do, while 
giving more freedom to the caller. (Mostly, this is the freedom 
to allocate less things with the GC.)

This is generally a good thing, provided that you understand when 
`scope` and `return scope` apply well enough not to be slowed 
down or confused by them too much.

Of course, sometimes you will actually have a good reason to 
escape a reference to a global or whatever, and `scope` doesn't 
do anything for types without indirections, so obviously you 
shouldn't put `scope` *everwhere*.

> Or it is better to use `auto` everywhere?.

Whether it is better to explicitly write out attributes and 
types, or have the compiler infer them via `auto` and/or 
templatization, depends on whether you want the compiler to give 
you an error message if you change the implementation in a way 
that alters the API, and how you value explicit documentation of 
the API versus keeping your code concise.

I recommend being as explicit as practical for public APIs, and 
for any aspect of any API that is fundamental to its purpose. 
(For example, a function intended to be used in CTFE should be 
explicitly `pure`.)

Just be careful not to over-constrain template APIs without a 
good reason.

> - What about `in` parameter attribute? Why it is not used wide 
> in Phobos?

Most of Phobos was written before the semantics of `in` or 
`scope` were finalized. That's why there is `-preview=in` and 
`-dip1000`, because them actually working is a somewhat new, 
work-in-progress feature.

> How to correctly call method from standard lib (for example 
> [expandTilde](https://dlang.org/phobos/std_path.html#expandTilde)) that does not annotated param with `scope` attribute?

If there is no obvious valid reason for the function to be 
escaping one of its parameters, it's likely a bug in Phobos - a 
bit of code that hasn't been fully updated yet for `-dip1000`. 
This is especially likely to be the case if the parameter in 
question is not `immutable`.

> For example:
>
> ```d
> @safe unittest {
>     scope string p1 = "~/projects/d";
>     scope string p2 = expandTilde(p1);
>     assert(p1 != p2);
> }
> ```
>
> In this case, following error raised:
>
> ```
> source/app.d(41,35): Error: scope variable `p1` assigned to 
> non-scope parameter `inputPath` calling `expandTilde`
>
> ```
>
> Is it correct, to use `.dup` method?
>
> ```diff
>  @safe unittest {
>      scope string p1 = "~/projects/d";
> -    scope string p2 = expandTilde(p1);
> +    scope string p2 = expandTilde(p1.dup);
>      assert(p1 != p2);
>  }
> ```

Either use `.dup`, `.idup`, or don't make `p1` `scope` in the 
first place.

The last option is preferred if you know you would otherwise need 
to `.dup` the majority of the time. Also, the compiler is 
generally pretty good about inferring `scope` where needed for 
local stack variables, so `scope` should mostly only appear 
explicitly when receiving `scope` parameters, not when sending 
them.


More information about the Digitalmars-d mailing list