www.digitalmars.com         C & C++   DMDScript  

digitalmars.D - using unaryFun in functions that take a comparator (eg sort etc):

reply Timothee Cour <thelastmammoth gmail.com> writes:
--047d7b2e496262f20204ddc2e233
Content-Type: text/plain; charset=ISO-8859-1

very often I would wish that sort (+ related functions) could take unaryFun
arguments and convert them to binaryFun as follows:

//pseudocode:
template unaryToBinaryComp(alias foo) {
bool unaryToBinaryComp(T)(T a, T b) if (__traits(compiles,foo(a) < foo(b))
) {
return foo(a) < foo(b);
}
}


Using this we could support much nicer syntax for sorting with unary
functions, for example:

sort!"foo(a)" <=>sort!(unaryToBinaryComp!(unaryFun!"foo(a)"))
<=> sort!"foo(a) < foo(a)"
sorting in reverse order is easy: just use sort!"-foo(a)" (works for
signed, unsigned, floating point types etc).

Examples of use:

E1)

struct A{
double score;
int index;
}

[A.init,A.init].sort!"a.score";
instead of:
[A.init,A.init].sort!"a.score < b.score";

E2)

mytuple.sort!"a[0]"
instead of:
[A.init,A.init].sort!"a[0]<b[0]"

I find that in large majority of cases, binary fun is used in that way. So
let's support both unaryFun and binaryFun.

--047d7b2e496262f20204ddc2e233
Content-Type: text/html; charset=ISO-8859-1
Content-Transfer-Encoding: quoted-printable

<div>very often I would wish that sort (+ related functions) could take una=
ryFun arguments and convert them to binaryFun as follows:</div><div><br></d=
iv><div>//pseudocode:<br><div>template unaryToBinaryComp(alias foo) {</div>
<div>bool unaryToBinaryComp(T)(T a, T b) if (__traits(compiles,foo(a) &lt; =
foo(b)) ) {</div><div>return foo(a) &lt; foo(b);</div><div>}</div><div>}</d=
iv><div><br></div><div><br></div></div><div>Using this we could support muc=
h nicer syntax for sorting with unary functions, for example:</div>
<div><br></div><div><div>sort!&quot;foo(a)&quot; &lt;=3D&gt;sort!(unaryToBi=
naryComp!(unaryFun!&quot;foo(a)&quot;)) &lt;=3D&gt;=A0sort!&quot;foo(a) &lt=
; foo(a)&quot;</div></div><div>sorting in reverse order is easy: just use s=
ort!&quot;-foo(a)&quot; (works for signed, unsigned, floating point types e=
tc).</div>
<div><br></div><div>Examples of use:</div><div><br></div><div>E1)</div><div=
<br></div><div>struct A{</div><div>double score;</div><div>int index;</div=
<div>}</div><div><br></div><div>[A.init,A.init].sort!&quot;a.score&quot;;<=

<div>instead of:=A0</div><div><div>[A.init,A.init].sort!&quot;a.score &lt; = b.score&quot;;</div></div><div><br></div><div><div>E2)</div></div><div><br>= </div><div>mytuple.sort!&quot;a[0]&quot;</div><div>instead of:=A0</div><div=

v><div>I find that in large majority of cases, binary fun is used in that w= ay. So let&#39;s support both unaryFun and binaryFun.</div><div><br></div> --047d7b2e496262f20204ddc2e233--
May 28 2013
next sibling parent "David Nadlinger" <see klickverbot.at> writes:
On Tuesday, 28 May 2013 at 08:16:47 UTC, Timothee Cour wrote:
 sort!"foo(a)" <=>sort!(unaryToBinaryComp!(unaryFun!"foo(a)"))
 <=> sort!"foo(a) < foo(a)"
 sorting in reverse order is easy: just use sort!"-foo(a)"

In this case, schwartzSort might actually be more appropriate. But in general, I see your point. David
May 28 2013
prev sibling parent Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> writes:
On 5/28/13 4:16 AM, Timothee Cour wrote:
 very often I would wish that sort (+ related functions) could take
 unaryFun arguments and convert them to binaryFun as follows:

 //pseudocode:
 template unaryToBinaryComp(alias foo) {
 bool unaryToBinaryComp(T)(T a, T b) if (__traits(compiles,foo(a) <
 foo(b)) ) {
 return foo(a) < foo(b);
 }
 }

I actually have a branch in my code that does exactly that. I abandoned it because the code, error messages, and documentation got really confusing. It may be worth to add a keySort algorithm that only works with unary keys, but then I thought people can always write a small lambda. Andrei
May 28 2013