On 12 September 2014 18:06, via Digitalmars-d <digitalmars-d@puremagic.com> wrote:
On Thursday, 11 September 2014 at 20:45:09 UTC, Marc Schütz wrote:
On Thursday, 11 September 2014 at 16:32:54 UTC, Ivan Timokhin wrote:
1. AFAIK, all current D type modifiers can be safely removed from the topmost level (i.e. it is OK to assign immutable(int[]) to immutable(int)[]), because they currently apply to particular variable, so there's no good reason to impose same restrictions on its copy. Situation seems different with scope: it is absolutely not safe to cast away and it applies to a *value*, not a variable holding it.

The types in your example are implicitly convertable, indeed no explicit cast is necessary. This is because when you copy a const value, the result doesn't need to be const. But with scope, it makes sense (and is of course necessary) to keep the ownership. I don't see that as an inconsistency, but as a consequence of the different things const and scope imply: mutability vs. ownership.

I've addressed this in the Wiki now. There were only a few changes to be made to move away from type modifiers. I had even suggested it as an implementation detail, but didn't think of making it part of the specification. Thank you for that insight, it makes the proposal more consistent and avoids the troubles with the types.

I'm not convinced this is a good change.
It sounds like you're just trading one problem with another more sinister problem...

What happens when a scope() thing finds it's way into generic code? If the type doesn't carry that information, then you end up in a situation like ref. Have you ever had to wrestle with ref in generic code?
ref is the biggest disaster zone in D, and I think all it's problems will translate straight to scope if you do this.


This is not only inconsistent, but may also cause trouble with interaction with existing features. For example, what should be std.traits.Unqual!(scope(int*)) ?

Good question. I would say it needs to keep scope, as it was clearly designed with mutability in mind (although it also removes shared, which is however related to mutability in a way). Ownership is an orthogonal concept to mutability.

After the changes, this is now the case.

This is a bit troublesome, because this is how things like std.range.ElementType work currently, so they may break. For example,
what would be ElementType!ByLineImpl (from the "scope(const...)" section)?

I see... it can _not_ be:

    scope!(const ByLineImpl!(char, "\n").init)(ByLineImpl!(char, "\n"))

because the init value is copied and thus becomes a temporary. This is ugly. It would however work if ElementType would take an instance instead of a type.

Ditto, this works now. The type is now simply `char[]` (or whatever), the owner is tracked separately.