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