www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - Playing with ranges and ufcs

reply "Andrea Fontana" <nospam example.com> writes:
This command:

writeln(iota(10).cycle()[5..2].take(4));

print:

[5, 6, 7, 8]


Shouldn't [5..2] slice throw a compile/runtime error?
Feb 27 2013
parent reply "bearophile" <bearophileHUGS lycos.com> writes:
Andrea Fontana:

 writeln(iota(10).cycle()[5..2].take(4));

 print:

 [5, 6, 7, 8]


 Shouldn't [5..2] slice throw a compile/runtime error?
Please file it in bugzilla. The opSlice of cycle() lacks those pre-conditions or tests, and there are not enough unittests in Phobos to catch this simple bug: auto opSlice(size_t i, size_t j) { auto retval = this.save; retval._index += i; return takeExactly(retval, j - i); } j - i is positive because those numbers are unsigned, and because D lacks a run-time errors for integral values because the stupid Walter thinks those run-time are too much slow (it's not actually true. Even Clang designers have understood it), and Don thinks that Everything is Fine in D: import std.stdio; struct Foo { auto opSlice(size_t i, size_t j) { writeln(j - i); // Prints: 4294967293 } } void main() { Foo f; f[5 .. 2]; } Maybe we need to run something similar to QuickCheck (http://en.wikipedia.org/wiki/QuickCheck ) on Phobos. Bye, bearophile
Feb 27 2013
next sibling parent reply "Jonathan M Davis" <jmdavisProg gmx.com> writes:
On Wednesday, February 27, 2013 23:48:05 bearophile wrote:
 Andrea Fontana:
 writeln(iota(10).cycle()[5..2].take(4));
 
 print:
 
 [5, 6, 7, 8]
 
 
 Shouldn't [5..2] slice throw a compile/runtime error?
Please file it in bugzilla. The opSlice of cycle() lacks those pre-conditions or tests, and there are not enough unittests in Phobos to catch this simple bug: auto opSlice(size_t i, size_t j) { auto retval = this.save; retval._index += i; return takeExactly(retval, j - i); }
What it should be doing is using version(assert) to throw a RangeError if the arguments are invalid, but the addition of version(assert) is quite recent (previously, the best that could have been done was to assert). That's the general policy, but it's not always followed like it should be. - Jonathan M Davis
Feb 27 2013
parent reply "bearophile" <bearophileHUGS lycos.com> writes:
Jonathan M Davis:

 What it should be doing is using version(assert) to throw a 
 RangeError if the
 arguments are invalid, but the addition of version(assert) is 
 quite recent
 (previously, the best that could have been done was to assert).
Do you mean something like this? auto opSlice(size_t i, size_t j) { version(assert) { if (i > j) throw new RangeError("some message here"); } auto retval = this.save; retval._index += i; return takeExactly(retval, j - i); } What's the advantage of that compared to using a normal contract? auto opSlice(size_t i, size_t j) in { assert(i <= j, "some message here"); } body { auto retval = this.save; retval._index += i; return takeExactly(retval, j - i); } Bye, bearophile
Feb 27 2013
next sibling parent reply "bearophile" <bearophileHUGS lycos.com> writes:
 auto opSlice(size_t i, size_t j)
 in {
     assert(i <= j, "some message here");
 } body {
     auto retval = this.save;
     retval._index += i;
     return takeExactly(retval, j - i);
 }
This is the bug opened by Andrea Fontana for this thread: http://d.puremagic.com/issues/show_bug.cgi?id=9612 At its start I show this code, that contains a but that the D compiler is able to catch at compile-time: void main() { auto a = [0,1,2,3,4,5,6,7,8,9][5 .. 2]; } To do the same with user-defined structures time ago I have suggested this, that is currently closed waiting for a better solution: http://d.puremagic.com/issues/show_bug.cgi?id=5906 Bye, bearophile
Feb 27 2013
next sibling parent reply "bearophile" <bearophileHUGS lycos.com> writes:
 To do the same with user-defined structures time ago I have 
 suggested this, that is currently closed waiting for a better 
 solution:
What I meant to say is that if the assert(i <= j) is inside the pre-condition then there's a hope to run it at compile time introducing some new trick inside the D language. But if you put code inside a version(assert) inside the body of opSlice() then the possibility of inventing a trick to do it is much lower. Bye, bearophile
Feb 27 2013
parent "Jonathan M Davis" <jmdavisProg gmx.com> writes:
On Thursday, February 28, 2013 00:46:56 bearophile wrote:
 To do the same with user-defined structures time ago I have
 suggested this, that is currently closed waiting for a better
 solution:
What I meant to say is that if the assert(i <= j) is inside the pre-condition then there's a hope to run it at compile time introducing some new trick inside the D language. But if you put code inside a version(assert) inside the body of opSlice() then the possibility of inventing a trick to do it is much lower.
Honestly, I think that that's a complete pipe dream anyway, but the point is to make it act like arrays, and they use RangeError. - Jonathan M Davis
Feb 27 2013
prev sibling parent "Andrea Fontana" <nospam example.com> writes:
On Wednesday, 27 February 2013 at 23:43:49 UTC, bearophile wrote:
 void main() {
     auto a = [0,1,2,3,4,5,6,7,8,9][5 .. 2];
 }
I tried it too, hoping for something like [5,4,3] or at least [4,3,2] (== [0,1,2,3,4,5,6,7,8,9][2..5].reverse)
Feb 28 2013
prev sibling parent reply "Jonathan M Davis" <jmdavisProg gmx.com> writes:
On Thursday, February 28, 2013 00:35:08 bearophile wrote:
 Jonathan M Davis:
 What it should be doing is using version(assert) to throw a
 RangeError if the
 arguments are invalid, but the addition of version(assert) is
 quite recent
 (previously, the best that could have been done was to assert).
Do you mean something like this? auto opSlice(size_t i, size_t j) { version(assert) { if (i > j) throw new RangeError("some message here"); } auto retval = this.save; retval._index += i; return takeExactly(retval, j - i); } What's the advantage of that compared to using a normal contract?
Because then it more closely matches how arrays work. The only part that doesn't is that it's fully tied to -release rather than -noboundschecked. - Jonathan M Davis
Feb 27 2013
parent "bearophile" <bearophileHUGS lycos.com> writes:
Jonathan M Davis:

 Because then it more closely matches how arrays work. The only 
 part that
 doesn't is that it's fully tied to -release rather than 
 -noboundschecked.
I see, thank you.
 Honestly, I think that that's a complete pipe dream anyway,
I will keep dreaming for some more decades. In technology progress comes from dreamers that have the skills to create things like the Whiley (http://whiley.org/ ) language. Bye, bearophile
Feb 27 2013
prev sibling parent reply "Andrea Fontana" <nospam example.com> writes:
On Wednesday, 27 February 2013 at 22:48:06 UTC, bearophile wrote:
 Andrea Fontana:

 writeln(iota(10).cycle()[5..2].take(4));

 print:

 [5, 6, 7, 8]


 Shouldn't [5..2] slice throw a compile/runtime error?
Please file it in bugzilla. The opSlice of cycle() lacks those pre-conditions or tests, and there are not enough unittests in Phobos to catch this simple bug: auto opSlice(size_t i, size_t j) { auto retval = this.save; retval._index += i; return takeExactly(retval, j - i); } j - i is positive because those numbers are unsigned, and because D lacks a run-time errors for integral values because the stupid Walter thinks those run-time are too much slow (it's not actually true. Even Clang designers have understood it), and Don thinks that Everything is Fine in D: import std.stdio; struct Foo { auto opSlice(size_t i, size_t j) { writeln(j - i); // Prints: 4294967293 } } void main() { Foo f; f[5 .. 2]; } Maybe we need to run something similar to QuickCheck (http://en.wikipedia.org/wiki/QuickCheck ) on Phobos. Bye, bearophile
Done!
Feb 27 2013
parent "bearophile" <bearophileHUGS lycos.com> writes:
Andrea Fontana:

 Done!
I was about to file it myself, so I have added a bit more meat to your bug report. Bye, bearophile
Feb 27 2013