digitalmars.D - questions: remove from SList
- enuhtac (41/41) Oct 11 2011 Hello,
- Steven Schveighoffer (15/51) Oct 11 2011 Yes, I'd agree either remove's implementation or its constraint
- kennytm (4/8) Oct 11 2011 I think remove's constraint is fine. With a SList you don't really want ...
- Steven Schveighoffer (10/20) Oct 12 2011 See the definition of std.algorithm.remove here:
Hello, I have two issues removing items from a SList. Consider following code: import std.container; import std.algorithm; void main() { SList!int a = [ 5, 4, 3, 2, 1 ]; auto r = a[]; remove( r, 2 ); // ERROR! Needed member function are not // implemented by SList(T).Range a.remove( r ); // ERROR! There is no member function remove } * The call to algorithm.remove produces these error messages: /usr/include/d/dmd/phobos/std/algorithm.d(5951): Error: src.front() is not an lvalue /usr/include/d/dmd/phobos/std/algorithm.d(5951): Error: tgt.front() is not an lvalue /usr/include/d/dmd/phobos/std/algorithm.d(5954): Error: no property 'popFrontN' for type 'Range' /usr/include/d/dmd/phobos/std/algorithm.d(5956): Error: no property 'popBack' for type 'Range' I would presume that phobos algorithms should work for all phobos containers, right? - At least if the prerequisites are met. The relevant prerequisite for this version of "remove" is "isForwardRange!Range" which is clearly the case for SList(T).Range. Nevertheless "remove" tries to access "popFrontN" and "popBack" which are not part of the ForwardRange specification. The lvalue-errors are another issue. I would clearly say this implementation of remove is buggy - or am I wrong? * The second call to remove does not succeed because there is no member function "remove". Instead there is "linearRemove". This is not a bug of course. But if I want to write code that uses some unspecific container it is very inconvenient that instead of "remove" I might have to call "linearRemove" or "stableRemove". Why not add a simple alias linearRemove remove ? This is sensible as "linearRemove" is a specialization of "remove". So the general function "remove" would always be present but the specialized function "linearRemove" or "stableRemove" would only be present if it makes sense for the specific container. Regards, enuhtac
Oct 11 2011
On Tue, 11 Oct 2011 05:19:41 -0400, enuhtac <enuhtac_lists gmx.de> wrote:Hello, I have two issues removing items from a SList. Consider following code: import std.container; import std.algorithm; void main() { SList!int a = [ 5, 4, 3, 2, 1 ]; auto r = a[]; remove( r, 2 ); // ERROR! Needed member function are not // implemented by SList(T).Range a.remove( r ); // ERROR! There is no member function remove } * The call to algorithm.remove produces these error messages: /usr/include/d/dmd/phobos/std/algorithm.d(5951): Error: src.front() is not an lvalue /usr/include/d/dmd/phobos/std/algorithm.d(5951): Error: tgt.front() is not an lvalue /usr/include/d/dmd/phobos/std/algorithm.d(5954): Error: no property 'popFrontN' for type 'Range' /usr/include/d/dmd/phobos/std/algorithm.d(5956): Error: no property 'popBack' for type 'Range' I would presume that phobos algorithms should work for all phobos containers, right? - At least if the prerequisites are met. The relevant prerequisite for this version of "remove" is "isForwardRange!Range" which is clearly the case for SList(T).Range. Nevertheless "remove" tries to access "popFrontN" and "popBack" which are not part of the ForwardRange specification. The lvalue-errors are another issue. I would clearly say this implementation of remove is buggy - or am I wrong?Yes, I'd agree either remove's implementation or its constraint specification are buggy. It should not specify that it needs a forward range and then use bi-directional range primitives. However, I don't think std.algorithm.remove does what you want, I think it moves data that is not desired to the end of the range (not exactly sure).* The second call to remove does not succeed because there is no member function "remove". Instead there is "linearRemove". This is not a bug of course. But if I want to write code that uses some unspecific container it is very inconvenient that instead of "remove" I might have to call "linearRemove" or "stableRemove". Why not add a simple alias linearRemove remove ?The exact point of why SList contains linearRemove and not remove is so that code which expects sub-linear remove function will not compile for SList, because SList does not support quick removal. Aliasing remove to linearRemove would defeat the purpose of using function names to imply complexity and side-effects, which is one of the main charters of std.container. There's always dcollections ;) http://www.dsource.org/projects/dcollections -Steve
Oct 11 2011
"Steven Schveighoffer" <schveiguy yahoo.com> wrote:Yes, I'd agree either remove's implementation or its constraint specification are buggy. It should not specify that it needs a forward range and then use bi-directional range primitives.I think remove's constraint is fine. With a SList you don't really want to remove the current node, but the 'next' node. SList should provide the O(1) removeNext and insertNext functions (c.f. C++11's std::forward_list).
Oct 11 2011
On Tue, 11 Oct 2011 13:29:02 -0400, kennytm <kennytm gmail.com> wrote:"Steven Schveighoffer" <schveiguy yahoo.com> wrote:See the definition of std.algorithm.remove here: https://github.com/D-Programming-Language/phobos/blob/master/std/algorithm.d#L5927 And see line 5956 which uses popBack on the range which is determined not to be a bidirectional range. Looking at the code, I'd say the bug is simply that remove is overloaded for forward ranges. I'd remove this whole overload. But your points on SList are valid -- a linked list of any kind that does not support O(1) removal or insertion is DOA. -SteveYes, I'd agree either remove's implementation or its constraint specification are buggy. It should not specify that it needs a forward range and then use bi-directional range primitives.I think remove's constraint is fine. With a SList you don't really want to remove the current node, but the 'next' node. SList should provide the O(1) removeNext and insertNext functions (c.f. C++11's std::forward_list).
Oct 12 2011