www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - mismatch and return value

reply celavek <cetatzeanum yahoo.com> writes:
Hi,

I am trying to use the function "mismatch" from 
std.algorithm.comparison like so:

int count = 0;
auto m = mismatch(lhs, rhs);

while (!m[0].empty)
{
     ++count;
     m = mismatch(m[0], m[1]);
}

That goes into an infinite loop. What does mismatch return when 
it cannot
actually find a mismatch? Is the return value immutable?
I do not get any warnings from the compiler(dmd).

As a side note the documentation of the standard library is not
digestible to say the least - there is missing info(e.g. what 
does mismatch return
if no mismatch found) and lacks user-friendliness and details.
Jul 13 2016
next sibling parent Mike Parker <aldacron gmail.com> writes:
On Wednesday, 13 July 2016 at 09:59:30 UTC, celavek wrote:

 As a side note the documentation of the standard library is not
 digestible to say the least - there is missing info(e.g. what 
 does mismatch return
 if no mismatch found) and lacks user-friendliness and details.
Whenever you find areas where the documentation needs any sort of improvements, please file an issue at [1] describing the problem. Then the next person that comes along won't be in the same boat. [1] https://issues.dlang.org/
Jul 13 2016
prev sibling next sibling parent reply ketmar <ketmar ketmar.no-ip.org> writes:
On Wednesday, 13 July 2016 at 09:59:30 UTC, celavek wrote:
 That goes into an infinite loop.
sure. let's read the docs: "Returns a tuple with the reduced ranges that start with the two mismatched values." so, if it will find mismatch, it will loop forever then, as you forgot to pop one of the values, making `mismatch` to infinitely return with the same ranges.
 What does mismatch return when it cannot
 actually find a mismatch?
let's read the doc again: "Returns a tuple with the reduced ranges that start with the two mismatched values." simple logic allows us to guess that it should return tuple with two empty ranges. and it really does.
 Is the return value immutable?
as with most other std.algo functions, the returned range has same properties as source range.
Jul 13 2016
parent reply celavek <cetatzeanum yahoo.com> writes:
On Wednesday, 13 July 2016 at 10:41:44 UTC, ketmar wrote:

 let's read the doc again: "Returns a tuple with the reduced 
 ranges that start with the two mismatched values." simple logic 
 allows us to guess that it should return tuple with two empty 
 ranges. and it really does.
I understand your point but it should not be a matter of guessing. It should be explicitly stated by the documentation.
Jul 13 2016
parent reply ketmar <ketmar ketmar.no-ip.org> writes:
On Wednesday, 13 July 2016 at 11:06:56 UTC, celavek wrote:
 On Wednesday, 13 July 2016 at 10:41:44 UTC, ketmar wrote:
 I understand your point but it should not be a matter of 
 guessing.
 It should be explicitly stated by the documentation.
then people will start to complain that documentation is "too wordy", hard to read and unnecessarily repeats the obvious things. good documentation omits obvious things just 'cause they are obvious. i believe that any sane person will read the description and assume that `mismatch` will return tuple with two empty ranges when there is no mismatch found. it's somewhat hard to keep the balance between "documenting everything" and "make documentation easy to read", i think.
Jul 13 2016
parent reply Mike Parker <aldacron gmail.com> writes:
On Wednesday, 13 July 2016 at 11:10:11 UTC, ketmar wrote:
 On Wednesday, 13 July 2016 at 11:06:56 UTC, celavek wrote:
 On Wednesday, 13 July 2016 at 10:41:44 UTC, ketmar wrote:
 I understand your point but it should not be a matter of 
 guessing.
 It should be explicitly stated by the documentation.
then people will start to complain that documentation is "too wordy", hard to read and unnecessarily repeats the obvious things. good documentation omits obvious things just 'cause they are obvious. i believe that any sane person will read the description and assume that `mismatch` will return tuple with two empty ranges when there is no mismatch found. it's somewhat hard to keep the balance between "documenting everything" and "make documentation easy to read", i think.
To be fair, I think it's only obvious to someone who has achieved a certain level of comfort and familiarity with ranges and the range-based functions in Phobos. This particular function could just as easily be inferred to return an empty tuple rather than a tuple of two empty ranges. Being more specific about the return value is only a few extra words that I wouldn't judge as being "too wordy".
Jul 13 2016
parent reply ketmar <ketmar ketmar.no-ip.org> writes:
On Wednesday, 13 July 2016 at 11:13:00 UTC, Mike Parker wrote:
 To be fair, I think it's only obvious to someone who has 
 achieved a certain level of comfort and familiarity with ranges 
 and the range-based functions in Phobos. This particular 
 function could just as easily be inferred to return an empty 
 tuple rather than a tuple of two empty ranges. Being more 
 specific about the return value is only a few extra words that 
 I wouldn't judge as being "too wordy".
probably you are right. it is somewhat hard to judge when you know the concept "by your heart". also, i always thought about phobos docs as "reference", not something people should learn from. i.e. "i already know how it works, and i just need to look for non-obvious details". it will be great to have "two-level documentation", with reference level and in-depth explanation level, but i understand how much efforts it will require...
Jul 13 2016
parent celavek <cetatzeanum yahoo.com> writes:
Thank you both for the very good insights. Community wise +1 :)
Jul 13 2016
prev sibling parent reply Mike Parker <aldacron gmail.com> writes:
On Wednesday, 13 July 2016 at 09:59:30 UTC, celavek wrote:
 Hi,

 I am trying to use the function "mismatch" from 
 std.algorithm.comparison like so:

 int count = 0;
 auto m = mismatch(lhs, rhs);

 while (!m[0].empty)
 {
     ++count;
     m = mismatch(m[0], m[1]);
 }

 That goes into an infinite loop. What does mismatch return when 
 it cannot
 actually find a mismatch? Is the return value immutable?
 I do not get any warnings from the compiler(dmd).
The return value is described as: "a tuple with the reduced ranges that start with the two mismatched values" This means given the following: void main() { import std.algorithm : mismatch; import std.stdio : writeln; auto lhs = [10, 20, 1, 22, 33, 44]; auto rhs = [10, 20, 2, 22, 33, 44]; auto m = mismatch(lhs, rhs); writeln(m[0]); writeln(m[1]); } The ranges following are printed: [1, 22, 33, 44] [2, 22, 33, 44] If you feed these back to mismatch, the 1 and the 2 are sill the mismatched values, so the return will again be identical: [[1, 22, 33, 44],[2, 22, 33, 44]] This is why you are getting an infinite loop, because the tuple values you get from the first call are fed back into mismatch infinitely. For your loop to work, you would need to pop the first value from each range in the tuple. Something like this: ``` void main() { import std.algorithm : mismatch; import std.stdio : writeln; // This example is using arrays as ranges, // so this is needed to give them the // correct interface import std.array : popFront, empty; auto lhs = [10, 20, 1, 22, 33, 44]; auto rhs = [10, 20, 2, 22, 33, 44]; auto m = mismatch(lhs, rhs); while(!m[0].empty && !m[1].empty) { m[0].popFront(); m[1].popFront(); m = mismatch(m[0], m[1]); } writeln("empty"); } ``` The return value when there is no mismatch is a tuple of two empty ranges. I've never used mismatch, but I learned everything I needed about the return values beyond what the documentation tells me by printing the return to the screen. Whenever you are confused about what a range-based function returns, writeln is your friend and can certainly save you some time.
Jul 13 2016
parent reply celavek <cetatzeanum yahoo.com> writes:
Thank you for the example.

I misunderstood the doc and I got a bit confused by the range - 
in C++ I would have incremented the iterators but here I did not 
know what to do exactly as I could not match the 2 different 
concepts in functionality.
Jul 13 2016
next sibling parent Mike Parker <aldacron gmail.com> writes:
On Wednesday, 13 July 2016 at 11:11:51 UTC, celavek wrote:
 Thank you for the example.

 I misunderstood the doc and I got a bit confused by the range - 
 in C++ I would have incremented the iterators but here I did 
 not know what to do exactly as I could not match the 2 
 different concepts in functionality.
Ranges can take some effort to wrap your head around. It's not that they're a difficult concept, it's just that they're different from what we've grown accustomed to in other languages. There's a tendency to treat them as containers or iterators, when they aren't quite either. This blog post [1] has some useful links for learning ranges. [1] http://www.learningd.org/2015/12/ranges-in-d/
Jul 13 2016
prev sibling parent ketmar <ketmar ketmar.no-ip.org> writes:
On Wednesday, 13 July 2016 at 11:11:51 UTC, celavek wrote:
 I misunderstood the doc and I got a bit confused by the range - 
 in C++ I would have incremented the iterators but here I did 
 not know what to do exactly as I could not match the 2 
 different concepts in functionality.
it mostly maps to `.popFront()` call in this case, to remove processed element(s). D ranges are somewhere between "iterators" and "generators" (and can represent both). this may be confusing, yeah.
Jul 13 2016