www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - Trouble with lockstep

reply "Craig Dillabaugh" <cdillaba cg.scs.carleton.ca> writes:
Hello,
I have code which generates a histogram from an array and prints
out the histogram bins/counts. However I cannot get the code to
iterate and print
out the histogram to work.  The following is a minimal example:

import std.range;
import std.stdio;

void main()
{
    ubyte[] data =
[17,32,32,32,38,39,39,47,47,47,47,109,111,111,128];
    uint[ubyte.max - ubyte.min] bins;

    foreach(ubyte val; data) bins[val]++;

    foreach( idx, count; lockstep( iota!ubyte(ubyte.min,
ubyte.max), bins ) )
    {
      if(count > 0 ) {
	writeln("Bin = ", idx, " count = ", count );
      }
    }
}

Alternately:  http://dpaste.com/hold/1267929/

I get the following error messages which I cannot decipher.

test.d(11): Error: template std.range.lockstep does not match any
function template declaration. Candidates are:
/usr/include/dmd/phobos/std/range.d(4724):
std.range.lockstep(Ranges...)(Ranges ranges) if
(allSatisfy!(isInputRange, Ranges))
/usr/include/dmd/phobos/std/range.d(4730):
std.range.lockstep(Ranges...)(Ranges ranges, StoppingPolicy s) if
(allSatisfy!(isInputRange, Ranges))
/usr/include/dmd/phobos/std/range.d(4724): Error: template
std.range.lockstep cannot deduce template function from argument
types !()(Result, uint[255LU])
Failed: 'dmd' '-v' '-o-' 'test.d' '-I.'

Can anyone identify what I am doing wrong.  Also I am curious to
know why std.range includes both Lockstep and lockstep - they
seem like the same thing.

Craig
Jun 24 2013
next sibling parent reply Joseph Rushton Wakeling <joseph.wakeling webdrake.net> writes:
On 06/24/2013 03:05 PM, Craig Dillabaugh wrote:
 Can anyone identify what I am doing wrong.  Also I am curious to
 know why std.range includes both Lockstep and lockstep - they
 seem like the same thing.
lockstep is a helper function that returns an instance of Lockstep. The reason is that if you instantiate a struct/class template directly you have to explicitly state the template parameters. A function template call can infer the template parameters and use them to instantiate a class instance.
Jun 24 2013
parent "Craig Dillabaugh" <cdillaba cg.scs.carleton.ca> writes:
On Monday, 24 June 2013 at 14:15:55 UTC, Joseph Rushton Wakeling
wrote:
 On 06/24/2013 03:05 PM, Craig Dillabaugh wrote:
 Can anyone identify what I am doing wrong.  Also I am curious 
 to
 know why std.range includes both Lockstep and lockstep - they
 seem like the same thing.
lockstep is a helper function that returns an instance of Lockstep. The reason is that if you instantiate a struct/class template directly you have to explicitly state the template parameters. A function template call can infer the template parameters and use them to instantiate a class instance.
Thanks. That makes sense ... I think.
Jun 24 2013
prev sibling next sibling parent reply David <d dav1d.de> writes:
lockstep(iota!ubyte(ubyte.min, ubyte.max), bins[])

Works, but this leaves you with other errors, I couldn't find a solution
for. Something seems to be wrong with opApply of lockstep.
Or maybe I miss something obvious...
Jun 24 2013
parent reply "bearophile" <bearophileHUGS lycos.com> writes:
David:

 Something seems to be wrong with opApply of lockstep.
 Or maybe I miss something obvious...
I have suggested to remove lockstep from Phobos: http://d.puremagic.com/issues/show_bug.cgi?id=8155 Why don't you try to use std.range.zip? Bye, bearophile
Jun 24 2013
parent reply "Craig Dillabaugh" <cdillaba cg.scs.carleton.ca> writes:
On Monday, 24 June 2013 at 14:56:41 UTC, bearophile wrote:
 David:

 Something seems to be wrong with opApply of lockstep.
 Or maybe I miss something obvious...
I have suggested to remove lockstep from Phobos: http://d.puremagic.com/issues/show_bug.cgi?id=8155 Why don't you try to use std.range.zip? Bye, bearophile
Funny you should mention that, I vaguely recalled you old thread, and replaced lockstep with zip. After making the following changes: uint[ubyte.max - ubyte.min+1] bins; ... foreach( e; zip( iota(ubyte.min, ubyte.max+1), bins ) ) { if(count > 0 ) { writeln("Bin = ", e[0], " count = ", e[1] ); } } I now get the error (which seems to be the same problem I had before - see the last error): test.d(11): Error: template std.range.zip does not match any function template declaration. Candidates are: /usr/include/dmd/phobos/std/range.d(4451): std.range.zip(Ranges...)(Ranges ranges) if (Ranges.length && allSatisfy!(isInputRange, Ranges)) /usr/include/dmd/phobos/std/range.d(4458): std.range.zip(Ranges...)(StoppingPolicy sp, Ranges ranges) if (Ranges.length && allSatisfy!(isInputRange, Ranges)) /usr/include/dmd/phobos/std/range.d(4451): Error: template std.range.zip cannot deduce template function from argument types !()(Result, uint[256LU])
Jun 24 2013
parent reply "bearophile" <bearophileHUGS lycos.com> writes:
Craig Dillabaugh:

 I now get the error (which seems to be the same problem I had
 before - see the last error):
 ...
 /usr/include/dmd/phobos/std/range.d(4451): Error: template
 std.range.zip cannot deduce template function from argument 
 types
 !()(Result, uint[256LU])
Most range/algorithm functions unfortunately don't accept a fixes size array. So you have to slice it: void main() { import std.stdio, std.range; ubyte[] data = [17, 32, 32, 32, 38, 39, 39, 47, 47, 47, 47, 109, 111, 111, 128]; uint[ubyte.max - ubyte.min + 1] bins; foreach (immutable val; data) bins[val]++; foreach (uint idx, count; iota(ubyte.min, ubyte.max + 1).zip(bins[])) if (count > 0) writeln("Bin = ", idx, " count = ", count); } Bye, bearophile
Jun 24 2013
parent "Craig Dillabaugh" <cdillaba cg.scs.carleton.ca> writes:
On Monday, 24 June 2013 at 15:15:46 UTC, bearophile wrote:
 Craig Dillabaugh:

 clip
Most range/algorithm functions unfortunately don't accept a fixes size array. So you have to slice it: void main() { import std.stdio, std.range; ubyte[] data = [17, 32, 32, 32, 38, 39, 39, 47, 47, 47, 47, 109, 111, 111, 128]; uint[ubyte.max - ubyte.min + 1] bins; foreach (immutable val; data) bins[val]++; foreach (uint idx, count; iota(ubyte.min, ubyte.max + 1).zip(bins[])) if (count > 0) writeln("Bin = ", idx, " count = ", count); } Bye, bearophile
Thanks. Now it works, if I use .zip().
Jun 24 2013
prev sibling next sibling parent reply "bearophile" <bearophileHUGS lycos.com> writes:
Craig Dillabaugh:

    foreach( idx, count; lockstep( iota!ubyte(ubyte.min,
 ubyte.max), bins ) )
Also note that doesn't iterate the whole ubyte range. Maybe we need another iota range for that, with a different name or with an optional template argument string like "[]" as std.random.uniform. Opinions welcome. Bye, bearophile
Jun 24 2013
parent reply "Craig Dillabaugh" <cdillaba cg.scs.carleton.ca> writes:
On Monday, 24 June 2013 at 14:33:48 UTC, bearophile wrote:
 Craig Dillabaugh:

   foreach( idx, count; lockstep( iota!ubyte(ubyte.min,
 ubyte.max), bins ) )
Also note that doesn't iterate the whole ubyte range. Maybe we need another iota range for that, with a different name or with an optional template argument string like "[]" as std.random.uniform. Opinions welcome. Bye, bearophile
Opps. Of course. The optional template argument sounds like a good idea. Any idea why the original wouldn't compile though? Craig
Jun 24 2013
parent "bearophile" <bearophileHUGS lycos.com> writes:
Craig Dillabaugh:

 Also note that doesn't iterate the whole ubyte range. Maybe we 
 need another iota range for that, with a different name or 
 with an optional template argument string like "[]" as 
 std.random.uniform. Opinions welcome.

 Bye,
 bearophile
Opps. Of course. The optional template argument sounds like a good idea.
http://d.puremagic.com/issues/show_bug.cgi?id=10466 Bye, bearophile
Jun 24 2013
prev sibling next sibling parent reply Joseph Rushton Wakeling <joseph.wakeling webdrake.net> writes:
On 06/24/2013 03:05 PM, Craig Dillabaugh wrote:
 I get the following error messages which I cannot decipher.
Oddly enough, I'm also getting lockstep-related error messages at compile-time: /opt/gdc/include/d/4.8.1/std/range.d:4716: Error: delegate dg (ref double, ref ulong) is not callable using argument types (double, ulong) test.d:122: Error: opApply() function for Lockstep!(Result, ulong[]) must return an int /opt/gdc/include/d/4.8.1/std/range.d:4717: Error: delegate dg (ulong, ref double, ref ulong) is not callable using argument types (ulong, double, ulong) test.d:122 is a foreach over a lockstep: foreach(r, x; itemDegree) ... where itemDegree is generated by the following function: auto degreeRank(NodeT)(NodeT nodes) { size_t[] x; foreach(node; nodes) x ~= node.links.length; x.sort; auto r = iota(1.0, 0, -1.0/x.length); return lockstep(r, x); } By the way, yes, I know I can probably find a better and more efficient way to generate x than what's there. It's what I wrote some time ago and never had a pressing enough need to improve. :-P
Jun 24 2013
parent "Craig Dillabaugh" <cdillaba cg.scs.carleton.ca> writes:
On Monday, 24 June 2013 at 15:29:21 UTC, Joseph Rushton Wakeling
wrote:
 On 06/24/2013 03:05 PM, Craig Dillabaugh wrote:
 I get the following error messages which I cannot decipher.
Oddly enough, I'm also getting lockstep-related error messages at compile-time: /opt/gdc/include/d/4.8.1/std/range.d:4716: Error: delegate dg (ref double, ref ulong) is not callable using argument types (double, ulong) test.d:122: Error: opApply() function for Lockstep!(Result, ulong[]) must return an int /opt/gdc/include/d/4.8.1/std/range.d:4717: Error: delegate dg (ulong, ref double, ref ulong) is not callable using argument types (ulong, double, ulong) test.d:122 is a foreach over a lockstep: foreach(r, x; itemDegree) ... where itemDegree is generated by the following function: auto degreeRank(NodeT)(NodeT nodes) { size_t[] x; foreach(node; nodes) x ~= node.links.length; x.sort; auto r = iota(1.0, 0, -1.0/x.length); return lockstep(r, x); } By the way, yes, I know I can probably find a better and more efficient way to generate x than what's there. It's what I wrote some time ago and never had a pressing enough need to improve. :-P
I think my original attempt compiled at home (where I was using and older version 2.062), but I couldn't compile it at work with the latest DMD (2.063). I didn't mention it in the original post because I couldn't recall for sure if I had successfully compiled it. You appear to be using GDC, but maybe this has something to do with recent changes.
Jun 24 2013
prev sibling parent reply =?UTF-8?B?QWxpIMOHZWhyZWxp?= <acehreli yahoo.com> writes:
On 06/24/2013 07:05 AM, Craig Dillabaugh wrote:

 The following is a minimal example:
Further reduced: import std.range; void main() { lockstep(iota(0, 10), [ 1 ]); } Strangely, the error message points at two comment lines in my installation of 2.063: /usr/include/dmd/phobos/std/range.d(4716): Error: delegate dg (ref int, ref int) is not callable using argument types (int, int) /usr/include/dmd/phobos/std/range.d(4717): Error: delegate dg (ulong, ref int, ref int) is not callable using argument types (ulong, int, int) Lines 4716 and 4717 are the two lines of the following comment: // For generic programming, make sure Lockstep!(Range) is well defined for a // single range. template Lockstep(Range) { alias Range Lockstep; } Ali
Jun 24 2013
next sibling parent reply "Craig Dillabaugh" <cdillaba cg.scs.carleton.ca> writes:
On Monday, 24 June 2013 at 16:03:17 UTC, Ali Çehreli wrote:
 On 06/24/2013 07:05 AM, Craig Dillabaugh wrote:

 The following is a minimal example:
Further reduced: import std.range; void main() { lockstep(iota(0, 10), [ 1 ]); } Strangely, the error message points at two comment lines in my installation of 2.063: /usr/include/dmd/phobos/std/range.d(4716): Error: delegate dg (ref int, ref int) is not callable using argument types (int, int) /usr/include/dmd/phobos/std/range.d(4717): Error: delegate dg (ulong, ref int, ref int) is not callable using argument types (ulong, int, int) Lines 4716 and 4717 are the two lines of the following comment: // For generic programming, make sure Lockstep!(Range) is well defined for a // single range. template Lockstep(Range) { alias Range Lockstep; } Ali
Well, I guess my example wasn't so minimal after all :o) So is this worthy of a bug report then?
Jun 24 2013
parent =?UTF-8?B?QWxpIMOHZWhyZWxp?= <acehreli yahoo.com> writes:
On 06/24/2013 11:01 AM, Craig Dillabaugh wrote:

 So is this worthy of a bug report then?
Yes, please. Ali
Jun 24 2013
prev sibling next sibling parent Andrej Mitrovic <andrej.mitrovich gmail.com> writes:
On 6/24/13, Ali =C7ehreli <acehreli yahoo.com> wrote:
 Strangely, the error message points at two comment lines in my
 installation of 2.063:
It's a regression which I've caused. I've made a fixup pull: http://d.puremagic.com/issues/show_bug.cgi?id=3D10468 I'm very sorry for this mishap.
Jun 24 2013
prev sibling parent reply Andrej Mitrovic <andrej.mitrovich gmail.com> writes:
On 6/25/13, Andrej Mitrovic <andrej.mitrovich gmail.com> wrote:
 It's a regression which I've caused. I've made a fixup pull:

 http://d.puremagic.com/issues/show_bug.cgi?id=10468

 I'm very sorry for this mishap.
It's now fixed in git-head. Chances are we're not going to have another 2.063 point release (I'm only speculating) so you may have to use the latest git-head version to use lockstep.
Jun 25 2013
parent "Joseph Rushton Wakeling" <joseph.wakeling webdrake.net> writes:
On Tuesday, 25 June 2013 at 10:52:22 UTC, Andrej Mitrovic wrote:
 On 6/25/13, Andrej Mitrovic <andrej.mitrovich gmail.com> wrote:
 It's now fixed in git-head. Chances are we're not going to have
 another 2.063 point release (I'm only speculating) so you may 
 have to
 use the latest git-head version to use lockstep.
That's a shame, I'd like to think there'd be a commitment to release regression fixes. Anyway, thanks for getting a fix made, and don't feel too guilty about the regression -- you're just pushing people towards the superior zip :-) Besides DMD, this fix needs to be propagated to GDC and LDC.
Jun 25 2013