On 16-Nov-2015 19:44, Steven Schveighoffer wrote:
On 11/14/15 3:42 AM, Dmitry Olshansky wrote:
On 14-Nov-2015 02:10, Andrei Alexandrescu wrote:

* Lines 141-152: I couldn't make tail() work with inout. Generally I'm
very unhappy about inout. I don't know how to use it. Everything I read
about it is extremely complicated compared to its power. I wish we
removed it from the language and replaced it with an understandable
idiom.


I can't agree more. Every time dealing with inout when I finally think I
grok how it works the next instant I see that it doesn't do what I
expect.

For me inout inevitably stops at the boundary of being unnable to have
List!(inout(T)) and the like.

One thing we could allow is types that contain inout member variables,
but ONLY in the context of inout functions. In other words, you can
create a type for it, but can only use it in the context of an inout
function.

inout should be indistinguishable of const but the moment you pass inout(T) to a template it becomes murky.

Appender!(inout(int)) - which qualifier to instantiate?


A List!(inout(T)) outside an inout function has no meaning. This is why
we disallowed it.

However, my belief is that it's the lack of a mechanism to apply an
attribute to the tail of some struct that prevents the most utility
here. If you returned a List!(inout(T)) there is no way to magically
convert it to a List!(const(T)) or List!(immutable(T)).

Consider that Node in this code has a "const(Node)* next" as its tail.

I believe we should be able to achieve both.

Looks a lot like tail-const problem. That is immutable T!E has no way to convert to T!(immutable E) and similarly to T!(const E).

Overall I see const/immutable a fine thing at low-level scope but not applicable at all to high-level constructs.

If something is conceptually const - its the task of implementation which may rely on physical const qualifier somewhere deep inside.

-Steve


--
Dmitry Olshansky

Reply via email to