DIP 1016--ref T accepts r-values--Formal Assessment

Andrei Alexandrescu SeeWebsiteForEmail at erdani.org
Thu Jan 31 06:19:52 UTC 2019


On 1/30/19 10:05 PM, Manu wrote:
> On Wed, Jan 30, 2019 at 6:40 PM Nicholas Wilson via
> Digitalmars-d-announce <digitalmars-d-announce at puremagic.com> wrote:
>>
>> On Wednesday, 30 January 2019 at 18:29:37 UTC, Manu wrote:
>>> On Wed, Jan 30, 2019 at 9:20 AM Neia Neutuladh via
>>> Digitalmars-d-announce <digitalmars-d-announce at puremagic.com>
>>> wrote:
>>>> The result of a CastExpression is an rvalue. An implicit cast
>>>> is a compiler-inserted CastExpression. Therefore all lvalues
>>>> with a potential implicit cast are rvalues.
>>>
>>> But there's no existing language rule that attempts to perform
>>> an implicit cast where an lvalue is supplied to a ref arg...?
>>> Why is the cast being attempted? 'p' is an lvalue, and whatever
>>> that does should remain exactly as is (ie, emits a compile
>>> error).
>>>
>>> We could perhaps allow this for `const` args, but that feels
>>> like separate follow-up work to me, and substantially lesser
>>> value. This DIP doesn't want to change anything about lvalues.
>>
>> It appears to say it does:
>>
>> fun(my_short); // implicit type conversions (ie, short->int
>> promotion)
>>
>> You should clarify that ;)
> 
> Yes, as said above, read `short(10)`. I can understand the confusion
> that it may look like a variable when taken out of context; but listed
> beneath the heading immediately above which says:
> "This inconvenience extends broadly to every manner of **rvalue**
> passed to functions"
> It didn't occur to me the reader might interpret the clearly stated
> list of cases of rvalues passed to functions to include arguments that
> are not rvalues.
> The name was just chosen to indicate the argument is a short, perhaps
> an enum, or any expression that is a short... I could have used
> `short(10)`, but apparently I didn't think of it at the time.
> 
> Is this the basis for the claims of "a hole you could drive a truck
> through"?

Affirmative.

With the restriction that the expression passed into the function must 
be an rvalue to start with, by Walter's and my understanding, the 
proposed semantics would work and be helpful.

> Again, a request for clarification, and a
> couldn't-possibly-be-more-trivial revision may resolve this.

Negative.

It must be clear that the reason of this misunderstanding is squarely 
due to the DIP itself. It has multiple problems of informality and vague 
language that have worked together to cause said misunderstanding. (It 
is great it's just that, a misunderstanding; I have been worried people 
would believe such an awful semantics was considered just fine. That 
explains but does not justify my use of unkind language.)

The DIP must convince the reader, and in a way the reader does not "owe" 
the DIP. For good reason, they call the research theme chosen by a 
doctoral candidate a "charge"; the root of "dissertation" is Latin for 
"debate"; and the final doctoral examination is plainly called a 
"defense". The whole thing is structured like a criminal investigation 
:o). Of course we don't want to be as harsh as academics could get, but 
we don't want to transform DIP acceptance into a farmers market 
bargaining process.

So the code with my_short was open to interpretation. Cool. In a 
thorough submission, however, there would have been many places that 
clear that up:

* Use of a distinct notation (non-code non-text font for metalanguage, 
i.e. general expressions);

* Description of the typechecking process, with examples of code that 
passes and code that fails;

* A clarification that lowering proceeds not against all expressions, 
but only against rvalues;

* Several places in text in which it is explained that rvalues resulted 
from implicit conversions are not eligible;

* etc. etc. etc.

So if we rejected the DIP, we didn't do so on account of one word that 
can be so easily changed; we did so on account of a DIP that as a whole 
failed to clarify what it purports to do (and equally importantly, to 
not do).

The purpose of us all is to move things forward, and in that spirit 
allow me to put forward a short list of matters that a revised proposal 
should do, at a minimum:

* Walter has posted about a few issues with various parts of the 
proposal. Those should be addressed.

* The "Reference" section does good to mention the issues, but the 
litany of forum discussions has no value besides "there have been 
repeated discussion in community forums of the topic", and refer to a 
list in an bibliography. Placing them in the "Reference" section 
suggests the reader that they need to read the forum debates in order to 
understand the DIP, which isn't and shouldn't be the case.

* An "Existing Work" section discussing C++ (and possibly Rust) is a 
must. Studious neglect of what other languages do and what problems they 
have does not serve us well. I think Walter could help with that.

* The "Rationale" section currently focuses only on issues caused by the 
current rule. It should have three parts:

- Open with a brief description of the current rule and why it is that 
way. Here we have the advantage that confusing conversions are disallowed.
- Then continue with "However, the binding rule also causes a variety of 
undue limitations whereby valid and useful code is rejected". Insert 
examples.
- Then continue with "If the rule got relaxed so as to only allow 
certain bindings but not all, we could allow the sensible cases 
illustrated above, yet still disallow the problematic cases."

Boom! The reader is already loving it.

* Subsection "Why are we here?" is not necessary. Its first part is 
folded in the "Rationale", and its second part is actually clearly an 
argument that is part of the rationale. IMHO the "pipeline" argument is 
not necessary, or can be moved in an "Examples of use" section toward 
the end.

* "Description" needs a complete rewrite. Here typing rules, lowering, 
exception safety, should be explained in ultimate detail using 
metalanguage (not just a few simplistic examples). It should be 
mechanically clear how an arbitrary expression containing function calls 
can be lowered into preexisting D code. Again I very much recommend 
lowering expressions to expressions instead of statements to statements, 
but anything clear and thorough will do.

* Also the description should clarify what happens in certain odd cases, 
such as alias this, class inheritance, properties that return lvalues 
vs. rvalues using the same syntax, and probably more. An important 
aspect of the proposal is "rvalues look different than lvalues, so the 
user won't get confused".

* "Temporary destruction" is unnecessary.

* "Function calls as arguments" us unnecessary if "Description" 
describes the feature completely.

* "Interaction with return ref" is probably unnecessary as a subsection 
but it would be nice to have as an explanatory example after the general 
lowering has been introduced.

* "Overload resolution" - see Walter's comments.

* Eliminate imprecise language "It has been noted that..." (by whom? 
when? reference?) If no reference, fine - spend a sentence to create 
that note!

* "Why not XXX?" should be massaged into a "Workarounds" section that 
follows the "Rationale" section, or is a subsection of it.

* "Key use cases" is good, and more examples should be only better.

Hope this helps! The outlook is definitely better after this 
misunderstanding has been cleared.


Andrei


More information about the Digitalmars-d-announce mailing list