<div class="gmail_quote">On 15 May 2012 16:28, Andrei Alexandrescu <span dir="ltr"><<a href="mailto:SeeWebsiteForEmail@erdani.org" target="_blank">SeeWebsiteForEmail@erdani.org</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
<div class="im">On 5/15/12 8:16 AM, Manu wrote:<br>
<blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
Okay, here's another problem due to ref not being a type constructor.<br>
If I have some function that receives an argument by ref, and then I<br>
take parameterTypeTuple! of that functions parameter list, the ref bits<br>
are gone from the typetuple.<br>
If I give that tuple as a template arg, then the template parameters no<br>
longer match the function it's wrapping...<br>
</blockquote>
<br></div>
Correct. That means there needs to be an additional trait that tells which parameters of a function are ref.<br></blockquote><div><br></div><div>This just creates a mess, and lots of redundant work. Now, rather than simply:</div>
<div> template myTemplate(T...) {}</div><div> myTemplate!(parameterTypeTuple!func)</div><div><br></div><div>I need to jump through a whole bunch of hoops to reconstruct an argument list that actually represents the function args.</div>
<div>I'm CONSTANTLY working around this, I have a file approaching 1000 loc just full of these sorts of workarounds given different situations.</div><div>Most of which elevate the problem beyond a simple template arg to a full blown string mixin where I have to start coding in between quotes, and with ~ as every second token.</div>
<div><br></div><div><br></div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
<div class="im">I'm still thinking more and more that there's no solution to all the<br>
problems with ref, other than changing it to use the syntax: ref(type),<br>
and be a type constructor, like const/immutable/shared/etc...<br>
I have problems with ref almost every day. If not in templates, in<br></div>
function/delegate definitions, and the prior issues previously discussed..<div class="im"><br>
<br>
No matter how I look at it, 'ref' really should be a type constructor.<br>
</div></blockquote>
<br>
Ref on a parameter or the return value is a property of the function, not a property of the parameter.</blockquote><div><br></div><div>I can't agree with that. Whether a parameter is a size_t pointer, or a 10kb struct is absolutely a property of the parameter. The data actually being passed is fundamentally different (size_t or buffer), the local storage mechanism for that data is fundamentally different, it affects the ABI, interaction with other languages is affected.</div>
<div><br></div><div>Additionally, ref shouldn't only be for function parameters. This is the source of a bunch more problems.</div><div><br></div><div><div>ref T func();</div><div>auto r = func(); <-- r is not a ref. D can't express local references, but it needs to in many cases.</div>
<div><br></div><div>This is also extremely common in loops to reduce code noise and clutter; improve readability.</div><div><br></div><div>I listed a bunch of problem cases with ref in another thread (thought it was this one), they would all be solved instantly (and intuitively) if ref(T) were a type constructor.</div>
</div><div><br></div><div><br></div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div class="im"><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
The use of 'ref' fundamentally changes the variable from T to T*, that's<br>
a critical difference, and can't just be lost when taking the typeof<br>
something.<br>
</blockquote>
<br></div>
Ref int is not int*</blockquote><div><br></div><div>Well... it is and it isn't. It's a pointer with some usage/syntactical tweaks; must be assigned on declaration, suppress pointer assignment syntax (enabling regular objective assignment) + arithmetic/indexing suppressed, etc.</div>
<div><br></div><div><br></div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">Ref fundamentally dictates how the parameter binds to the argument; otherwise, it doesn't affect the behavior of the parameter's type itself.<br>
</blockquote><div><br></div><div>I can see this point, but I don't know if that breaks my argument. Ie. this isn't a problem, and there are so many real issues with the existing implementation.<br><br></div><div><br>
</div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">To lift this one level up, what problem are you trying to solve?</blockquote><div><br></div><div>1. I can't 'cut and paste' arguments/argument lists from functions to templates; the ref properties are lost. Leads to bloat, workarounds and inevitable string mixins.</div>
<div>2. auto doesn't work with ref return values.</div><div>3. Syntax is obscure and confused, how to I pass a reference to a function that returns a ref? Intuitive solution: void func( ref(ref(T) function()) fp )</div>
<div>4. I want to use ref anywhere: ref return values need to assign to ref locals, loops frequently create a ref as a resolution of a complex lookup expression for each iteration of the loop, etc.</div><div><br></div><div>
Right now, the problem is that template args do not transfer the ref-ness of a given argument; it is an important detail of the type that must be conveyed.</div><div><br></div><div><br></div><div>Perhaps you can clarify why it was done this way; ie, intentionally break the mould of existing familiar (and perfectly good) implementation like C++ and C#? (C# being a great example of a modern implementation)</div>
<div>There must be some advantages the current implementation offers? I can only see losses of functionality.</div></div>