<div class="gmail_quote">On 11 March 2012 20:57, Andrei Alexandrescu <span dir="ltr"><<a href="mailto:SeeWebsiteForEmail@erdani.org">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">I don't know what you mean by "structured type". What I mean by "product type" is this: <a href="http://en.wikipedia.org/wiki/Product_type" target="_blank">http://en.wikipedia.org/wiki/<u></u>Product_type</a></div>
</blockquote><div><br></div><div>The first line on that page states my meaning verbatim:</div><div><span style="background-color:rgb(255,255,255);font-family:sans-serif;font-size:13px;line-height:19px">"In </span><a href="http://en.wikipedia.org/wiki/Programming_language" title="Programming language" style="background-color:rgb(255,255,255);text-decoration:none;color:rgb(11,0,128);background-image:none;font-family:sans-serif;font-size:13px;line-height:19px">programming languages</a><span style="background-color:rgb(255,255,255);font-family:sans-serif;font-size:13px;line-height:19px"> and </span><a href="http://en.wikipedia.org/wiki/Type_theory" title="Type theory" style="background-color:rgb(255,255,255);text-decoration:none;color:rgb(11,0,128);background-image:none;font-family:sans-serif;font-size:13px;line-height:19px">type theory</a><span style="background-color:rgb(255,255,255);font-family:sans-serif;font-size:13px;line-height:19px">, a </span><b style="background-color:rgb(255,255,255);font-family:sans-serif;font-size:13px;line-height:19px">product</b><span style="background-color:rgb(255,255,255);font-family:sans-serif;font-size:13px;line-height:19px"> of </span><i style="background-color:rgb(255,255,255);font-family:sans-serif;font-size:13px;line-height:19px">types</i><span style="background-color:rgb(255,255,255);font-family:sans-serif;font-size:13px;line-height:19px"> is another, compounded, type <u><b>in a structure</b></u>."</span></div>
<div><br></div><div>The objectionable part to me is that as soon as it becomes 'structured' there are additional details in the mix; a defined memory layout and requirement to adhere by said layout. This allows the coder to do some things that should be conceptually impossible; take the pointer of the first item, perform some math, and arrive at another member. This shouldn't be applicable to a passing in registers ABI.</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 don't know how 'major' they'd really work out to be. It's not a</div><div class="im">
paradigm buster. There are some details, but I don't even think it would<br>
need to be a breaking change to the language (maybe some very subtle<br>
tweaks).<br>
</div></blockquote>
<br>
I am convinced you are underestimating. The notion that a function returns one typed value is strongly embedded in the language and the standard library.</blockquote><div><br></div><div>You're probably right, and I don't entirely object to the Tuple solution (given a nice little bit of sugar), as I've said before (and above), my concern is that it confuses 2 distinct operations (returning multiple things, and returning a struct by value), both of which should remain expressible by the language.</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">
D can return multiple values from a function by putting them in a tuple. This approach has many advantages, mostly related to avoiding awkward ambiguities (e.g. forwarding the result of a multi-return to a variadic or overloaded function). Regarding syntax, I am not convinced by arguments predicated on removing "Tuple!" from "Tuple!(int, int)". It's not progress, and pouring more magic in tuples that is not available anywhere else does not strike me as a good path to go.<br>
</blockquote><div><br></div><div>Well the feature becomes very ugly, clutters the intent with syntax, requires ugly lines of unpacking syntax, and also asserts to the programmer that they're exploiting a template library. When I encounter anything like this in C (*cough* STL), I will immediately lose all trust in the compilers codegen between compilers (even if the language implements some hacks to define an efficient ABI for this feature).</div>
<div><br></div><div>None of those are hard reasons against *IF* the codegen does exactly what it is supposed to. I'll swallow any of those if the codegen works, but it seems a crying shame to refuse some sugar to interact nicely:</div>
<div><br></div><div>void func(int x)</div><div>{</div><div>  someStruct s;</div><div><br></div><div>  (x, _, s.member, int err) = multiFunc();</div><div>  if(err == ...) { ... }</div><div>}</div><div><br></div><div>Results are written directly where they need to end up, saves lines, it's clear what I'm doing, I think that's valuable.</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">Regarding low-level efficiency, the main issue is that structs and function argument lists have distinct layouts. Consider:<br>

<br>
import std.stdio, std.typecons;<br>
int a(int b, int c) {<br>
    return b + c;<br>
}<br>
auto foo() {<br>
    return tuple(1, 1);<br>
}<br>
void main() {<br>
    writeln(a(foo().expand));<br>
}<br>
<br>
An adjustment may be needed from the output of a() to the arguments of foo(). (Probably not in this case.) I understand that someone very concerned with low-level performance would scrutinize such code carefully. </blockquote>
<div><br></div><div>Wow, I can't imagine how '.expand' could possibly work :) .. that looks like total magic. A parameter list can be populated by items collected in a tuple via a property?</div><div>If such magic is possible, surely the other stuff is equally possible...</div>
<div class="gmail_quote"><br></div><div>This is an example of where the return-multi ABI mirroring the call args ABI verbatim would really shine.</div><div>In this example, assuming the codegen did it's job, the call to foo() would return with the arg regs for the call to a() pre-populated. It could just call straight through without doing anything at all to setup the arguments. Beautiful!</div>
<div>In C, you could only get this via inline asm.</div><div><br></div><div>That said though, I feel this is an extension of the basic multi-return requirement, perhaps also of significantly lesser importance; chaining together this way would be rare I would imagine. Of course, if it's easily possible, no reason against :)</div>
<div><br></div><div> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">But I also believe that the same person is willing to forgo a whole category of language and library features that don't fulfill a demanding performance profile.</blockquote>
<div><br></div><div>I'm not sure what you're getting at here, this is a feature designed to enhance performance (and also enhance convenience + readability while at it)</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">In the tight loops of every program I've ever written, I can't recall a<br>
time when I haven't had a function that needs to return multiple things,<br>
and C/C++ has always forced me into unnecessary memory access to express<br>
this (ref parameters). For the first time in language/compiler history,<br>
D would finally be able to eliminate the last of the redundant memory<br>
accesses in my hottest code in a portable way, at a language/expression<br>
level.<br>
<br>
Are you saying it's impossible, that you don't think it should be done,<br>
or it's already solved?<br>
</blockquote>
<br></div>
I understand your pledge, and all I'm saying is that it is very difficult to implement (Walter and I discussed the matter many times over the years) and the feature will benefit only very, very few.<br></blockquote><div>
<br></div><div>If by 'few', you mean the number of programmers that actually write this code, perhaps... but that's not the full picture.</div><div>But all realtime software is ultimately bottlenecked by the performance of these few super-tight inner loops. More often than not, these exist in libraries that everyone uses. So the influence of this feature is much further reaching than the one person who exploited it to improve hottest part of their code. Those realtime library developers are all acutely aware of this stuff, will appreciate the feature, and users of said libraries will all enjoy being able to do a little more with their given system specs.</div>
<div>Average users will also appreciate the code clarity and convenience the syntax of this feature offers, so they get a direct kickback from this feature too.</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">Is it that you don't see the value in it? Is that what I need to<br>
convince you of?<br>
You haven't argued with any of the other points I raised, which leads me<br>
to suspect you either see my points, or you think the entire premise of<br>
my rant is wrong... if so, can you show how, and present a solution<br>
that's workable within existing constructs that meets my criteria<br></div>
without adding other implicit/logical baggage? Nobody has acknowledged<div class="im"><br>
or disputed the majority of my points :/<br>
</div></blockquote>
<br>
Your points are understood, but please also understand what exceptional circumstances you are invoking. You mention how transferring function results costs extra operations. If that cost is significant, that means the cost of the function proper is extremely low. So you want to call extremely small functions in extremely core loops. The first advice would be "avoid calling extremely small functions in extremely core loops"!</blockquote>
<div><br></div><div>In typical circumstances, once you've boiled your problem down, you no longer have any choice over the parameters of your algorithm design. Writing this sort of a system tends to be a mechanical process. Once the algorithm finds maximum efficiency, then low level efficiency comes in, and this is important. Saying not to call small functions it fallacious. Obviously I will have already inlined everything I can, but for whatever reason, there are still a couple of function calls left.</div>
<div>The interesting thing I often find about these sorts of algorithms is I can often structure the inner loop not to touch memory AT ALL, except for that one bloody by-ref return parameter, which needlessly reduces my whole algorithm down to the speed of memory access.</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">
D is a native language, that's it's most attractive feature, and while I<br>
appreciate all the high-level correct-ness D offers, it still needs to<br>
get the low level right and ideally improve on existing offerings in<br>
meaningful ways to motivate new users to switch. This is a big<br>
un-checked checkbox for me and my colleagues, and I'd wager any low<br>
level realtime programmer out there who has had to struggle with the<br>
codegen in their inner loops.. doubly so if they ever work on non-x86<br>
systems since the penalties are so much greater.<br>
</blockquote>
<br></div>
Are function returning tuples the first thing on your low-level efficiency list?</blockquote><div><br></div><div>No, virtual-by-default is by a million-fold... that is the biggest low level disaster in the language hands down! :)</div>
<div><br></div><div>In terms of efficiency, this isn't super high, I just know I'm going to be swearing the exact the same way I have with in C for years to come, and breaking out the bloody inline assembler needlessly :(</div>
<div>In terms of convenience however, as said in my OP, I'm finding myself wishing for this most days.</div><div><br></div><div>When taking efficiency & convenience aspects together, and the fact it ticks a big language feature checkbox, it really does feel worth doing to me.</div>
<div><br></div><div>I do note that those 2 aspects of this feature are actually separate jobs, and the sugar one is clearly higher priority, it'll make everyone else talking here happy too... I just don't want to see it end there. The issue is that from the efficiency aspect (if implemented via a tuple, and not special cased), is an ABI breaking change, which should be done sooner than later to break as little future code as possible.</div>
</div>