Re: New to std.algorithm and generics, no idea how to make simple things to work
On Sunday, 9 March 2014 at 09:06:51 UTC, John Colvin wrote: std.container isn't great and hasn't received enough attention. There are plans to improve it, but I believe we're waiting on std.allocator and possibly a higher level layer on top of it before any significant revamp is made. It is perfectly usable in its current state however, just not always totally pleasant. Don't let this put you off std.algorithm and std.range, which are both very high quality. Actually, DList is very hard to use.
Re: New to std.algorithm and generics, no idea how to make simple things to work
On Friday, 7 March 2014 at 19:53:04 UTC, newguy wrote: I really can't wrap my head around these. I fought whole day trying to figure out how to do the simplest thing one can imagine: remove an element from a doubly linked list. Here's what I've tried, see if there is a recurring mistake of thought or something: import std.stdio; import std.algorithm; import std.range; import std.container; struct Point { int x; int y; } void main() { DList!Point points; points.insert(Point(0,0)); points.insert(Point(10,10)); points.insert(Point(5,5)); points.insert(Point(20,20)); points.remove(takeOne(find!(p = p.x 7)(points[]))); // test.d(18): Error: function std.container.DList!(Point).DList.remove (Range r) is not callable using argument types (Result) points.linearRemove(takeOne(find!(p = p.x 7)(points[]))); // test.d(21): Error: template std.container.DList!(Point).DList.linearRemove cannot deduce function from argument types !()(Result), candidates are: // /usr/include/dmd/phobos/std/container.d(2234): std.container.DList!(Point).DList.linearRemove(R)(R r) if (is(R == Range)) // /usr/include/dmd/phobos/std/container.d(2240): std.container.DList!(Point).DList.linearRemove(R)(R r) if (is(R == Range)) // /usr/include/dmd/phobos/std/container.d(2253): std.container.DList!(Point).DList.linearRemove(R)(R r) if (is(R == Take!Range)) points.remove(find!(p = p.x 7)(points[])); // 0 points.remove(takeOne(filter!(p = p.x 7)(points[]))); // test.d(30): Error: function std.container.DList!(Point).DList.remove (Range r) is not callable using argument types (Result) points.remove(filter!(p = p.x 7)(points[])); // test.d(33): Error: function std.container.DList!(Point).DList.remove (Range r) is not callable using argument types (FilterResult!(__lambda3, Range)) points.linearRemove(filter!(p = p.x 7)(points[])); // test.d(36): Error: template std.container.DList!(Point).DList.linearRemove cannot deduce function from argument types !()(FilterResult!(__lambda1, Range)), candidates are: // /usr/include/dmd/phobos/std/container.d(2234): std.container.DList!(Point).DList.linearRemove(R)(R r) if (is(R == Range)) // /usr/include/dmd/phobos/std/container.d(2240): std.container.DList!(Point).DList.linearRemove(R)(R r) if (is(R == Range)) // /usr/include/dmd/phobos/std/container.d(2253): std.container.DList!(Point).DList.linearRemove(R)(R r) if (is(R == Take!Range)) foreach (Point p; points) { if (p.x 7) { //points.remove(/* Somehow get the range */); break; } } foreach (Point p; points) { writeln(p.x); } } Purpose is to remove one element that matches predicate, or any amount really. Now DList.remove is defined as Range remove(Range r) and filter is auto filter(Range)(Range rs) if (isInputRange!(Unqual!Range)) with explanation The call filter!(predicate)(range) returns a new range only containing elements x in range for which predicate(x) is true. So if I understand correctly, filter should return a range that I can remove from the list. Why isn't this working? std.container isn't great and hasn't received enough attention. There are plans to improve it, but I believe we're waiting on std.allocator and possibly a higher level layer on top of it before any significant revamp is made. It is perfectly usable in its current state however, just not always totally pleasant. Don't let this put you off std.algorithm and std.range, which are both very high quality.
Re: New to std.algorithm and generics, no idea how to make simple things to work
Ok, I got it working with points.linearRemove(find!(p = p.x 7)(points[]).take(1)); I thought takeOne would work and didn't thought of trying take(1), but I guess not. I also learned that containers don't accept filter results as a range so no problem, I can accept that. Still, feels quite complicated. I hope it's worth it in the long run :)
Re: New to std.algorithm and generics, no idea how to make simple things to work
newguy: Still, feels quite complicated. I hope it's worth it in the long run :) It is complicated. Other parts of Phobos are both less complex and more useful. This means you have chosen a bad part of Phobos :-) Bye, bearophile
New to std.algorithm and generics, no idea how to make simple things to work
I really can't wrap my head around these. I fought whole day trying to figure out how to do the simplest thing one can imagine: remove an element from a doubly linked list. Here's what I've tried, see if there is a recurring mistake of thought or something: import std.stdio; import std.algorithm; import std.range; import std.container; struct Point { int x; int y; } void main() { DList!Point points; points.insert(Point(0,0)); points.insert(Point(10,10)); points.insert(Point(5,5)); points.insert(Point(20,20)); points.remove(takeOne(find!(p = p.x 7)(points[]))); // test.d(18): Error: function std.container.DList!(Point).DList.remove (Range r) is not callable using argument types (Result) points.linearRemove(takeOne(find!(p = p.x 7)(points[]))); // test.d(21): Error: template std.container.DList!(Point).DList.linearRemove cannot deduce function from argument types !()(Result), candidates are: // /usr/include/dmd/phobos/std/container.d(2234): std.container.DList!(Point).DList.linearRemove(R)(R r) if (is(R == Range)) // /usr/include/dmd/phobos/std/container.d(2240): std.container.DList!(Point).DList.linearRemove(R)(R r) if (is(R == Range)) // /usr/include/dmd/phobos/std/container.d(2253): std.container.DList!(Point).DList.linearRemove(R)(R r) if (is(R == Take!Range)) points.remove(find!(p = p.x 7)(points[])); // 0 points.remove(takeOne(filter!(p = p.x 7)(points[]))); // test.d(30): Error: function std.container.DList!(Point).DList.remove (Range r) is not callable using argument types (Result) points.remove(filter!(p = p.x 7)(points[])); // test.d(33): Error: function std.container.DList!(Point).DList.remove (Range r) is not callable using argument types (FilterResult!(__lambda3, Range)) points.linearRemove(filter!(p = p.x 7)(points[])); // test.d(36): Error: template std.container.DList!(Point).DList.linearRemove cannot deduce function from argument types !()(FilterResult!(__lambda1, Range)), candidates are: // /usr/include/dmd/phobos/std/container.d(2234): std.container.DList!(Point).DList.linearRemove(R)(R r) if (is(R == Range)) // /usr/include/dmd/phobos/std/container.d(2240): std.container.DList!(Point).DList.linearRemove(R)(R r) if (is(R == Range)) // /usr/include/dmd/phobos/std/container.d(2253): std.container.DList!(Point).DList.linearRemove(R)(R r) if (is(R == Take!Range)) foreach (Point p; points) { if (p.x 7) { //points.remove(/* Somehow get the range */); break; } } foreach (Point p; points) { writeln(p.x); } } Purpose is to remove one element that matches predicate, or any amount really. Now DList.remove is defined as Range remove(Range r) and filter is auto filter(Range)(Range rs) if (isInputRange!(Unqual!Range)) with explanation The call filter!(predicate)(range) returns a new range only containing elements x in range for which predicate(x) is true. So if I understand correctly, filter should return a range that I can remove from the list. Why isn't this working?
Re: New to std.algorithm and generics, no idea how to make simple things to work
Text went nuts at least for me so here's raw pastebin of it http://pastebin.com/raw.php?i=JfLFdsNj