www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - dmd 2.049 bug with take and SList?

reply Nick Treleaven <nospam example.net> writes:
Hi,
I'm new to D2 ranges but have been following D for some time. I'm posting 
here because I want to check if I'm doing anything wrong before filing a 
bug.

The code below is a test case I made after hitting the problem in real 
code. Basically the pyramid recursive function should print out:
[1, 2, 3]
[1, 2]
[1]

This works fine when calling with an int[] range, but calling with
SList!int seems to make the compiler hang, eating up memory.

Should I file a bug?


import std.stdio;
import std.range;
import std.container;

void pyramid(Range)(Range items)
{
	if (items.empty)
		return;
	writeln(items);
	auto len = walkLength(items);
	auto r = take(items, len - 1);
	pyramid(r);
}

void main()
{
	/* array version is fine */
	int[] arr = [1, 2, 3];
	pyramid(arr[]);
	
	SList!int list = [1, 2, 3];
	pyramid(list[]);	/* infinite loop with dmd 2.049 */
}
Oct 13 2010
parent reply "Lars T. Kyllingstad" <public kyllingen.NOSPAMnet> writes:
On Wed, 13 Oct 2010 16:46:09 +0000, Nick Treleaven wrote:

 Hi,
 I'm new to D2 ranges but have been following D for some time. I'm
 posting here because I want to check if I'm doing anything wrong before
 filing a bug.
 
 The code below is a test case I made after hitting the problem in real
 code. Basically the pyramid recursive function should print out: [1, 2,
 3]
 [1, 2]
 [1]
 
 This works fine when calling with an int[] range, but calling with
 SList!int seems to make the compiler hang, eating up memory.
 
 Should I file a bug?
 
 
 import std.stdio;
 import std.range;
 import std.container;
 
 void pyramid(Range)(Range items)
 {
 	if (items.empty)
 		return;
 	writeln(items);
 	auto len = walkLength(items);
 	auto r = take(items, len - 1);
 	pyramid(r);
 }
 
 void main()
 {
 	/* array version is fine */
 	int[] arr = [1, 2, 3];
 	pyramid(arr[]);
 	
 	SList!int list = [1, 2, 3];
 	pyramid(list[]);	/* infinite loop with dmd 2.049 */
 }
You are creating an infinite recursion of templates. For an array the return type of take() is the same array type. For other ranges, the return type of take() is Take!Range. So when you instantiate pyramid! Range, it instantiates pyramid!(Take!Range), and then pyramid!(Take!(Take! Range)), and so on ad infinitum. A solution could be to make take!(Take!Range)() just return another Take! Range. I can look into that, but you should file a bug report on it so it's not forgotten. -Lars
Oct 13 2010
parent reply "Lars T. Kyllingstad" <public kyllingen.NOSPAMnet> writes:
On Wed, 13 Oct 2010 18:06:15 +0000, Lars T. Kyllingstad wrote:

 On Wed, 13 Oct 2010 16:46:09 +0000, Nick Treleaven wrote:
 
 Hi,
 I'm new to D2 ranges but have been following D for some time. I'm
 posting here because I want to check if I'm doing anything wrong before
 filing a bug.
 
 The code below is a test case I made after hitting the problem in real
 code. Basically the pyramid recursive function should print out: [1, 2,
 3]
 [1, 2]
 [1]
 
 This works fine when calling with an int[] range, but calling with
 SList!int seems to make the compiler hang, eating up memory.
 
 Should I file a bug?
 
 
 import std.stdio;
 import std.range;
 import std.container;
 
 void pyramid(Range)(Range items)
 {
 	if (items.empty)
 		return;
 	writeln(items);
 	auto len = walkLength(items);
 	auto r = take(items, len - 1);
 	pyramid(r);
 }
 
 void main()
 {
 	/* array version is fine */
 	int[] arr = [1, 2, 3];
 	pyramid(arr[]);
 	
 	SList!int list = [1, 2, 3];
 	pyramid(list[]);	/* infinite loop with dmd 2.049 */
 }
You are creating an infinite recursion of templates. For an array the return type of take() is the same array type. For other ranges, the return type of take() is Take!Range. So when you instantiate pyramid! Range, it instantiates pyramid!(Take!Range), and then pyramid!(Take!(Take! Range)), and so on ad infinitum. A solution could be to make take!(Take!Range)() just return another Take! Range. I can look into that, but you should file a bug report on it so it's not forgotten. -Lars
http://d.puremagic.com/issues/show_bug.cgi?id=5052
Oct 13 2010
parent reply "Lars T. Kyllingstad" <public kyllingen.NOSPAMnet> writes:
On Thu, 14 Oct 2010 06:54:17 +0000, Lars T. Kyllingstad wrote:

 On Wed, 13 Oct 2010 18:06:15 +0000, Lars T. Kyllingstad wrote:
 
 On Wed, 13 Oct 2010 16:46:09 +0000, Nick Treleaven wrote:
 
 Hi,
 I'm new to D2 ranges but have been following D for some time. I'm
 posting here because I want to check if I'm doing anything wrong
 before filing a bug.
 
 The code below is a test case I made after hitting the problem in real
 code. Basically the pyramid recursive function should print out: [1,
 2, 3]
 [1, 2]
 [1]
 
 This works fine when calling with an int[] range, but calling with
 SList!int seems to make the compiler hang, eating up memory.
 
 Should I file a bug?
 
 
 import std.stdio;
 import std.range;
 import std.container;
 
 void pyramid(Range)(Range items)
 {
 	if (items.empty)
 		return;
 	writeln(items);
 	auto len = walkLength(items);
 	auto r = take(items, len - 1);
 	pyramid(r);
 }
 
 void main()
 {
 	/* array version is fine */
 	int[] arr = [1, 2, 3];
 	pyramid(arr[]);
 	
 	SList!int list = [1, 2, 3];
 	pyramid(list[]);	/* infinite loop with dmd 2.049 */
 }
You are creating an infinite recursion of templates. For an array the return type of take() is the same array type. For other ranges, the return type of take() is Take!Range. So when you instantiate pyramid! Range, it instantiates pyramid!(Take!Range), and then pyramid!(Take!(Take! Range)), and so on ad infinitum. A solution could be to make take!(Take!Range)() just return another Take! Range. I can look into that, but you should file a bug report on it so it's not forgotten. -Lars
http://d.puremagic.com/issues/show_bug.cgi?id=5052
Fixed. http://www.dsource.org/projects/phobos/changeset/2102
Oct 14 2010
parent Nick Treleaven <nospam example.net> writes:
On Thu, 14 Oct 2010 07:18:48 +0000, Lars T. Kyllingstad wrote:

 You are creating an infinite recursion of templates.  For an array the
 return type of take() is the same array type.  For other ranges, the
 return type of take() is Take!Range.  So when you instantiate pyramid!
 Range, it instantiates pyramid!(Take!Range), and then
 pyramid!(Take!(Take! Range)), and so on ad infinitum.
OK, makes sense.
 A solution could be to make take!(Take!Range)() just return another
 Take! Range.  I can look into that, but you should file a bug report
 on it so it's not forgotten.
 
 -Lars
http://d.puremagic.com/issues/show_bug.cgi?id=5052
Fixed. http://www.dsource.org/projects/phobos/changeset/2102
Thanks!
Oct 14 2010