Bug 4603 – array(iota(1, 0)) error

Status
RESOLVED
Resolution
FIXED
Severity
normal
Priority
P2
Component
phobos
Product
D
Version
D2
Platform
x86
OS
All
Creation time
2010-08-09T07:49:00Z
Last change time
2012-04-20T04:28:15Z
Assigned to
andrei
Creator
bearophile_hugs

Attachments

IDFilenameSummaryContent-TypeSize
707range.d.patch[1]Patch for range.d to produce an empty range when pastLast <= current.text/plain839
708range.d.patch[2]Patch for range.d to throw when pastLast <= current.text/plain447

Comments

Comment #0 by bearophile_hugs — 2010-08-09T07:49:55Z
This generates an 'Access Violation' with dmd 2.048beta: import std.range; void main() { array(iota(1, 0)); } The expected result of this array() is an empty dynamic array of signed integers.
Comment #1 by kennytm — 2010-08-09T10:40:09Z
If you write --- import std.range; import std.stdio; void main() { foreach (a; iota(1, 0)) { writeln(a); } } --- the program will never stop writing. Looks like an integer overflow bug.
Comment #2 by kennytm — 2010-08-09T11:03:43Z
Created attachment 707 Patch for range.d to produce an empty range when pastLast <= current. This patch produces an empty range when pastLast <= current. But this is inconsistent with the behavior of floating point iota ranges.
Comment #3 by kennytm — 2010-08-09T11:08:17Z
Created attachment 708 Patch for range.d to throw when pastLast <= current. This patch simply enforces pastLast > current, so it is consistent with the floating point iota range. But it may be less useful.
Comment #4 by dsimcha — 2010-08-19T17:07:09Z
Fixed in changeset 1901. I chose to throw in this case. The proper way to create an empty range would be to do iota(0, 0), or iota(1, 1). The main reason for this choice was consistency with array slicing. For example, if bounds checking is enabled, array[3..2] throws a RangeError.
Comment #5 by bearophile_hugs — 2010-08-19T17:44:23Z
Throwing? No, look at Python: >>> range(1, 0) [] It needs to return an empty range. This: foreach (i; iota(1, 0)) is the same as: foreach (i; 1 .. 0) Or: for (int i = 1; i < 0; i++) It's like an empty loop.
Comment #6 by bearophile_hugs — 2010-08-19T17:49:22Z
And by the way, in Python This produces an empty string slice: >>> "abcdefg"[3:2] ''
Comment #7 by bearophile_hugs — 2010-08-20T05:16:23Z
Thank you for improving this bug. But I reopen the bug because I think raising an error is the wrong design. As I have explained iota() is to be meant as the ranges in for/foreach loops, so iota(1, 0) is like an empty loop, it's not an error.
Comment #8 by bearophile_hugs — 2011-06-29T13:34:52Z
See also bug 6222
Comment #9 by eco — 2012-04-19T18:41:12Z
This now seems to work as you want in DMD 2.059. The following: import std.stdio, std.range; void main() { auto empty_array = array(iota(1, 0)); writeln("type: ", typeof(empty_array).stringof, ", empty? ", empty_array.empty, ", contents: ", empty_array); } Outputs: type: int[], empty? true, contents: [] I'd say it can be closed and marked RESOLVED now.