D issues are now tracked on GitHub. This Bugzilla instance remains as a read-only archive.
Issue 5124 - Make std.algorithm.sort weakly pure
Summary: Make std.algorithm.sort weakly pure
Status: RESOLVED WORKSFORME
Alias: None
Product: D
Classification: Unclassified
Component: phobos (show other issues)
Version: D2
Hardware: All All
: P2 enhancement
Assignee: No Owner
URL:
Keywords: bootcamp
Depends on:
Blocks: 10318
  Show dependency treegraph
 
Reported: 2010-10-26 17:20 UTC by bearophile_hugs
Modified: 2018-05-18 10:24 UTC (History)
2 users (show)

See Also:


Attachments

Note You need to log in before you can comment on or make changes to this issue.
Description bearophile_hugs 2010-10-26 17:20:57 UTC
A pure sort allows to sort data even in strongly pure functions, this will be useful.

Using DMD 2.050beta I have modified a little many Phobos functions and now the following testing code works:


import std.algorithm: sort;
import std.traits: FunctionAttribute, functionAttributes;

alias FunctionAttribute FA; // shorten the enum name

pure int[] foo1(int[] arr) {
    sort(arr);
    return arr;
}

pure int[] foo2(int[] arr) {
    sort!q{ a > b }(arr);
    return arr;
}

pure bool myComp1(int x, int y) { return x > y; }
pure int[] foo3(int[] arr) {
    sort!(myComp1)(arr);
    return arr;
}

pure int[] foo4(int[] arr) {
    static pure bool myComp2(int x, int y) { return x > y; }
    // static assert(functionAttributes!(myComp2) & FA.PURE); // asserts
    //sort!(myComp2)(arr);
    return arr;
}

void main() {
    assert(foo1([5, 1, 7, 4]) == [1, 4, 5, 7]);
    assert(foo2([5, 1, 7, 4]) == [7, 5, 4, 1]);
    assert(foo3([5, 1, 7, 4]) == [7, 5, 4, 1]);
    //assert(foo4([5, 1, 7, 4]) == [7, 5, 4, 1]);
}


To make it compile I have had to turn pure many functions and change few things. Here are some of the changes:

-------------------

std.functional, line 179:

pure Body!(ElementType1, ElementType2).ReturnType

This is possible and safe because the functions defined as strings are always static.

-------------------

A problem is in std.algorithm, an assert calls text() that may become pure, but it will require some more work:

Commented out line 5167 of std.algorithm:

//assert(isSorted!lessFun(r), text(Range.stringof, ": ", r));

-------------------

Change the return type of std.range.assumeSorted, line 5405:

pure SortedRange!(R, pred) assumeSorted(alias pred = "a < b", R)(R r)

Note:
pure auto assumeSorted(alias pred = "a < b", R)(R r)

Can't be used because of bug 3934 (see also bug 5006 )

-------------------

SortedRange needs a pure this():

struct SortedRange(Range, alias pred = "a < b")
if(isRandomAccessRange!(Unqual!Range))
{
    alias Unqual!Range R;
    private R _input;

    pure this(R input)
Comment 1 Andrei Alexandrescu 2016-10-14 12:55:42 UTC
sort is weakly pure, bootcamping for the other issues
Comment 2 Dmitry Olshansky 2018-05-18 10:24:07 UTC
The provided example now compiles, so whatever changes required were introduced w/o ever noticing this ticket. Just clarifies my understanding that NOBODY is looking at enhancements in Bugzilla (except for select few), but rather only bugs.

///

import std.algorithm: sort;
import std.traits: FunctionAttribute, functionAttributes;

alias FunctionAttribute FA; // shorten the enum name

pure int[] foo1(int[] arr) {
    sort(arr);
    return arr;
}

pure int[] foo2(int[] arr) {
    sort!q{ a > b }(arr);
    return arr;
}

pure bool myComp1(int x, int y) { return x > y; }
pure int[] foo3(int[] arr) {
    sort!(myComp1)(arr);
    return arr;
}

pure int[] foo4(int[] arr) {
    static pure bool myComp2(int x, int y) { return x > y; }
    // static assert(functionAttributes!(myComp2) & FA.PURE); // asserts
    //sort!(myComp2)(arr);
    return arr;
}

void main() {
    assert(foo1([5, 1, 7, 4]) == [1, 4, 5, 7]);
    assert(foo2([5, 1, 7, 4]) == [7, 5, 4, 1]);
    assert(foo3([5, 1, 7, 4]) == [7, 5, 4, 1]);
    //assert(foo4([5, 1, 7, 4]) == [7, 5, 4, 1]);
}