December 29, 2014
On 12/29/14 2:04 PM, Dicebot wrote:
> On Monday, 29 December 2014 at 19:00:06 UTC, Andrei Alexandrescu wrote:
>> I tend to agree. You seem to have shown that reusing inout for scope
>> information becomes confusing. -- Andrei
>
> What is the problem with using inout exactly as it is now (== both for
> argument and return type) but defining it to propagate aliasing
> information as it is decribed in DIP25?

It can, and I don't have a problem for that.

But I think disallowing:

ref T foo(T)(ref T t) { return t;}

Is no good. The DIP seems to be indicating inout can have another use that has nothing to do with const, but I'm not exactly sure.

Ironically, inout used to be an alias for ref :)

-Steve
December 29, 2014
On Monday, 29 December 2014 at 19:54:33 UTC, Steven Schveighoffer wrote:
> On 12/29/14 2:04 PM, Dicebot wrote:
>> On Monday, 29 December 2014 at 19:00:06 UTC, Andrei Alexandrescu wrote:
>>> I tend to agree. You seem to have shown that reusing inout for scope
>>> information becomes confusing. -- Andrei
>>
>> What is the problem with using inout exactly as it is now (== both for
>> argument and return type) but defining it to propagate aliasing
>> information as it is decribed in DIP25?
>
> It can, and I don't have a problem for that.
>
> But I think disallowing:
>
> ref T foo(T)(ref T t) { return t;}
>
> Is no good.

It is to be disallowed only in @safe code, right?

> The DIP seems to be indicating inout can have another use that has nothing to do with const, but I'm not exactly sure.

I see its potential as a  generic wildcard for attribute/qualifier propagation through the functions.
December 29, 2014
On 12/29/14 2:57 PM, Dicebot wrote:
> On Monday, 29 December 2014 at 19:54:33 UTC, Steven Schveighoffer wrote:
>> On 12/29/14 2:04 PM, Dicebot wrote:
>>> On Monday, 29 December 2014 at 19:00:06 UTC, Andrei Alexandrescu wrote:
>>>> I tend to agree. You seem to have shown that reusing inout for scope
>>>> information becomes confusing. -- Andrei
>>>
>>> What is the problem with using inout exactly as it is now (== both for
>>> argument and return type) but defining it to propagate aliasing
>>> information as it is decribed in DIP25?
>>
>> It can, and I don't have a problem for that.
>>
>> But I think disallowing:
>>
>> ref T foo(T)(ref T t) { return t;}
>>
>> Is no good.
>
> It is to be disallowed only in @safe code, right?

Even in safe code, if it's safe to do so, it should be allowed.

I think the driving point behind this push is that when you see:

ref T foo(ref T t);

how do you know if the return of foo is somehow related to t or not? The DIP is saying if you return something related to t, you have to mark t as inout. At least, this is my understanding. But this precludes doing anything with a mutable t inside foo, since inout means "const within the function".

>
>> The DIP seems to be indicating inout can have another use that has
>> nothing to do with const, but I'm not exactly sure.
>
> I see its potential as a  generic wildcard for attribute/qualifier
> propagation through the functions.

It's not generic at all. It's a concrete type qualifier that does not generate a template. When inside an 'inout' function, anything marked as inout is transitively const.

-Steve
December 29, 2014
On 12/29/14 2:50 PM, Walter Bright wrote:
> On 12/29/2014 5:53 AM, Steven Schveighoffer wrote:
>> On 12/28/14 4:33 PM, Walter Bright wrote:
>>> inout is not transitive, so a ref on the container doesn't apply to a
>>> ref on the contents if there's another level of indirection in there.
>> I'm not sure what you mean by this, but inout as a type modifier is
>> definitely
>> transitive.
>
> As a type modifier, yes, it is transitive. As transferring lifetime to
> the return value, it is not.
>

I strongly suggest not to use inout to mean this. This idea would be a disaster.

-Steve
December 29, 2014
On Monday, 29 December 2014 at 20:20:45 UTC, Steven Schveighoffer wrote:
> But this precludes doing anything with a mutable t inside foo, since inout means "const within the function".

Hm, yes, this is indeed quite the problem. I have totally forgot that compiler has no means of figuring out which invocation of inout is currently used.

But something very similar feels necessary to me. There is constness, lifetime, purity - inventing new dedicated keyword for each case does not feel like scaling approach. Especially when existing one is named so generic.
December 29, 2014
On 12/29/14 3:42 PM, Dicebot wrote:
> On Monday, 29 December 2014 at 20:20:45 UTC, Steven Schveighoffer wrote:
>> But this precludes doing anything with a mutable t inside foo, since
>> inout means "const within the function".
>
> Hm, yes, this is indeed quite the problem. I have totally forgot that
> compiler has no means of figuring out which invocation of inout is
> currently used.
>
> But something very similar feels necessary to me. There is constness,
> lifetime, purity - inventing new dedicated keyword for each case does
> not feel like scaling approach. Especially when existing one is named so
> generic.

My original inkling was to name it scoped const or sconst, since that's what the proposal was originally named. The idea to use inout was because of the allergic reaction all the maintainers had at the time to adding any new keywords -- inout was fully superseded by ref, and technically "available" without introducing any new keywords. I almost wish we had never named it that, but I was too happy to have the feature at the time.

I think it wouldn't be a bad idea to investigate a new way to express attributes, but I think no matter what we do, we need to rein in the explosion of attributes that needs to be put on every function.

-Steve
December 29, 2014
On Monday, 29 December 2014 at 21:29:21 UTC, Steven Schveighoffer wrote:
> I think it wouldn't be a bad idea to investigate a new way to express attributes, but I think no matter what we do, we need to rein in the explosion of attributes that needs to be put on every function.

For that I think attribute inference is the way to go - though in a bit more structured fashion than it was originally proposed ages ago ("just infer everything")
December 30, 2014
On 29 December 2014 at 14:13, Andrei Alexandrescu via Digitalmars-d <digitalmars-d@puremagic.com> wrote:
> On 12/28/14 7:40 PM, Manu via Digitalmars-d wrote:
>>
>> On 28 December 2014 at 13:09, Andrei Alexandrescu via Digitalmars-d <digitalmars-d@puremagic.com> wrote:
>>>
>>> Walter and I have been working on revamping DIP25, which focuses on tightening the screws of ref. This should then simplify DIP69 significantly.
>>>
>>> Please comment: http://wiki.dlang.org/DIP25
>>>
>>>
>>> Thanks,
>>>
>>> Andrei
>>
>>
>> I could generally understand the intent, but I don't really understand
>> the connection between ref and inout.
>> They seem like unrelated things. I feel like conflating them could
>> only lead to unexpected problem cases when the concepts coincide
>> naturally, but the intent wasn't this assigned special case.
>> I wonder if we're just narrowing the window of edge cases, and
>> possibly into a slightly more awkward position for later fixes?
>
>
> Walter's reasoning was: we have inout for propagating qualifiers from a parameter ("this" is also a parameter) to the output, so we can use it for propagating aliasing information as well.

Okay, that's an interesting perspective. I'm not sure I'm feeling it,
but I'll see how it sits overnight :)
The problem is that inout is clearly a type modifier; it resolves to
const, or immutable... adding additional conceptual baggage that's not
type-related seems problematic. Some non-type part of it's meaning
will be lost (or incorrectly transferred) in templates?


> One idea we discussed was to use "return" like this:
>
> ref int fun(return ref int x); // may return x
>
> Walter didn't like it. I'm somewhat neutral.

It feels like a problem for 'scope' to me.


> Any examples of cases when having inout do both would cause trouble?

Well, the case where something should be (or already is) inout, but it's not intended for it to be safe to return from the function. It remains unsafe, even though we've specified the magic special case that tells the compiler it's okay.


>> I'd like to see 'ref inout(int)' rather than 'ref inout int', to make
>> inout look like the type modifier that it is, rather than a storage
>> class, which it isn't.
>> That distinction made me start second-guessing my assumptions
>> throughout, and reduced my confidence in my understanding of the
>> proposal.
>
>
> When applied to a parameter, the parens are redundant.

A terrible decision if you ask me. I really prefer to see the parens present on type modifiers, since they affect the 'layering' of type modifiers, and also distinguish them from storage classes.

const int *: is it const(int)*, or const(int*)?
What about when layers are deeper: const(int*)[]?
You can produce any number of unclear scenarios of this kind.

or:
  void eg(ref const S x)
  {
    f(x);
  }

  void f(T)(T x) // <- x is const, but not ref? why did some
attributes disappear but not others?
  {
  }

I like the clear visual distinction so people aren't wondering what happened.


>> I'd also like to know how this will help DIP69?
>
>
> Just takes the entire ref handling out of the equation.

Then DIP69 seems to lose all purpose?
The whole thing is about safer indirections.


>> I can't imagine how
>> this could help DIP69 address the basic problems I was concerned with
>> (ie, distilling towards; 'storage class' is practically a bad design
>> for D, and my numerous rants and walls of text that follow).
>
>
> I did want to say something about this. I've given a close read to the "Lost a new commercial user this week" thread, through and through. It seems I've identified a problem that belongs to us. ("Us" is a vacuous term meaning "the leaders of the D community").
>
> My initial read of your complaint went like this: it's about Windows (I don't even have an installation), it's about vibe.d (haven't used it yet), and it's also discussing documentation (which is something we can indeed improve and I know how to). So a large part of the problem wasn't even mine to work on.

I was giving a context with vibe.d, but I think they key take-aways were:

First-impressions; in our case, that was Windows environment setup, but the point should be taken generally, and that includes IDE integration. The effect of a poor experience here is eroding user confidence before they've even written a single line of code. Expectations are high, other programming communities are nailing this.

Debugging was the biggest issue, and turned out to be the dealbreaker. We couldn't get behind something that we were unable to fix if we have to. (I say 'we', meaning the general office perception, and that perception was definitely coloured by the prior experiences re; first-impressions)

Also documentation received a lot of criticism from the new-users, although I didn't identify it as a deal-breaker. I experienced this same frustration myself years ago. It's easy to address, I just wanted to demonstrate importance.


Trust me that these guys were REALLY excited to try out D when we got
started. But their confidence was eroded very quickly by these factors
in aggregate.
I think D will get another shot with this lot at some later stage when
demonstrable progress has been made.


> Others harbored similar perceptions. The corollary has been that essentially you're asking them to stop working on D aspects they do care about and start working on D aspects you and others care about - all on their free time.

I've already argued against this assertion, because it got kind of
aggressive. I was just reporting a case-study.
People can do whatever they want, I'm only trying to reaffirm the
reality of the importance of the same stuff that I've been going on
about since the day I showed up here.
There has been really great improvement, and we're getting awfully
close to the line, but we're still just a little way short.

It's a shame, because that boring stuff that nobody is interested in working on is inhibiting people from getting amongst the cool stuff that's going on here.


> Then I figured we must take ownership of D issues. Your initial post was pure and simple user feedback - a knowledgeable and well-informed and well-meaning user but nevertheless a user who is not quite willing to roll sleeves up and proceed with adding work. If we consider ourselves a free-wheeling grassroots tribe, best we can do invite you to do the work and review and merge it in (or snicker at you if you're not up for it). If, on the other hand, we want to be a real organization, we must take the feedback and own it.
>
> A simple simile: say you mention to the manager of a grocery store that they should have more organic fruit, and mention anecdotes of potential customers shunning the store because it doesn't. If the store is a cooperative of folks selling stuff they grow on their own, the manager might invite you to join in with your produce. If, on the other hand, the store is an established supermarket, they'd do good to take your suggestion seriously.
>
> We're in the "cooperative" stage of D, and we need to move toward the "established organization" stage. We should start transitioning to that next year; part of it is I plan to look seriously at the non-profit organization angle.

Right, this will be interesting. First I've heard of it.
I'm sure corporate users would put their money on the table if they
were purchasing some sort of support package, ie, greater confidence
in the tooling and infrastructure.
Especially in Windows-land, we're accustomed to paying for polished experiences.


> There is a rub though. Not only you're telling what we'd need to do to be more successful, you're also telling us how to do it. Please don't. We are not adding type qualifiers to D if we can avoid it, and generally we want to achieve what we need to achieve with minimum aggravation. Instead please focus on what you're trying to accomplish, not on whether an artifact is a type qualifier or a storage class. Thanks.

I only make the distinction because years of experience to date has
demonstrated clearly that the storage class concept is the source of
most of the awkward language problems I encounter.
Focusing on the current high-level goal will only lead to
context-specific patches (ie, further edge cases), and in this case
where I can clearly see the root of a series of problems spanning
years, it seems like the wrong thing to do.
There is time to approach a problem as you say, but I don't think this
is one of them. That said, if there is a vision presented that keeps
storage class and fixes the problems, I'm all for it, but nobody's
presented one, I can't envision one, and I've thought about it a lot.
The solution practically implies building a system of tools to
manipulate storage classes that parallels the existing system for
types... I don't see the point.

Surely it's not a bad thing to explore the thought that 'storage class' may have actually been a mistake? There's room for retrospect. You don't need to defend a bad idea when it's proven to be a problem.

ref is basically a broken design, it works in only the simplest of use
cases, and otherwise adds unwieldy complication to any more complex
language structures. The primary reason for that is because
semantically, it lives external to the 'meat' of the D language.
I suspect its original design is the direct result of the kind of
approach to the problem you're asking me to take; "user wants to pass
by ref, we'll try something that satisfies exactly the target use
case, and tries to isolate itself from any language side-effects", but
I think that attempt to isolate itself from cascading side-effects is
precisely the reason for all of it's awkward side-effects.
Perhaps there will be awkward side-effects either way? ...in this case
though, we have no tools to mitigate them manually. Code duplication
and text mixin are the only effective tools we have to manage ref
problems.
December 30, 2014
On 30 December 2014 at 01:52, Andrei Alexandrescu via Digitalmars-d <digitalmars-d@puremagic.com> wrote:
> On 12/29/14 2:58 AM, John Colvin wrote:
>>
>> On Monday, 29 December 2014 at 04:13:18 UTC, Andrei Alexandrescu wrote:
>>>
>>> There is a rub though. Not only you're telling what we'd need to do to be more successful, you're also telling us how to do it. Please don't. We are not adding type qualifiers to D if we can avoid it, and generally we want to achieve what we need to achieve with minimum aggravation. Instead please focus on what you're trying to accomplish, not on whether an artifact is a type qualifier or a storage class. Thanks.
>>>
>>>
>>> Andrei
>>
>>
>> But (one of) his point(s) is that the choice between type qualifier and
>> storage class directly impacts his work. Why shouldn't a user express
>> such a point?
>
>
> Making that point is fine so long as the costs are discussed alongside with the applicability to one particular task. -- Andrei

It's not one particular task. It is the common theme for almost all
ref related problems (other than rvalue->ref, which is just
arbitrarily rejected currently).
I'm trying to raise that topic for discussions, but nobody wants to
talk about it, and would rather focus on patches instead.
I don't know exactly where ref as type constructor would lead. Sure,
it would be complex no doubt, but not necessarily any more or less
complex than the awkward network of edge cases we're trying to deal
with in these discussions currently.
My feeling is, all these discussions are essentially arguing an
*extremely* complex suite of language patches. I'm interested in
considering the root problem for contrast... I think we'd find
ourselves in a position with a lot less edges as result.
December 30, 2014
On 30 December 2014 at 07:29, Steven Schveighoffer via Digitalmars-d <digitalmars-d@puremagic.com> wrote:
> On 12/29/14 3:42 PM, Dicebot wrote:
>
> I think it wouldn't be a bad idea to investigate a new way to express attributes, but I think no matter what we do, we need to rein in the explosion of attributes that needs to be put on every function.

The approach is to infer everything, right?
The only time you are required to make it explicit is when it's an
important detail of your API, and you want to receive compile errors
when you violate such explicit request.