www.digitalmars.com         C & C++   DMDScript  

digitalmars.D - foreach (x; a .. b) and foreach_reverse (x; a .. b) should be disallowed

reply Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> writes:
Consider:

     foreach (x; 1.0 .. 4.1) writeln(x);
     foreach_reverse (x; 1.0 .. 4.1) writeln(x);

This sucks. foreach with interval for floating-point types should be 
disallowed.


Andrei
May 17 2009
next sibling parent dsimcha <dsimcha yahoo.com> writes:
== Quote from Andrei Alexandrescu (SeeWebsiteForEmail erdani.org)'s article
 Consider:
      foreach (x; 1.0 .. 4.1) writeln(x);
      foreach_reverse (x; 1.0 .. 4.1) writeln(x);
 This sucks. foreach with interval for floating-point types should be
 disallowed.
 Andrei
This one I agree with. I wasn't even aware that the syntax above worked. The use of 4.1 to deal with the fact that the interval is exclusive is a really silly kludge caused by this feature not being intended to be used with floating point intervals. It would be an argument for making the foreach interval loop more powerful instead, except that if you're going to do that, you may as well just use a regular for loop, since foreach interval loops are just a shortcut for this anyhow.
May 17 2009
prev sibling next sibling parent reply Jason House <jason.james.house gmail.com> writes:
Andrei Alexandrescu Wrote:

 Consider:
 
      foreach (x; 1.0 .. 4.1) writeln(x);
      foreach_reverse (x; 1.0 .. 4.1) writeln(x);
 
 This sucks. foreach with interval for floating-point types should be 
 disallowed.
 
 
 Andrei
I agree that makes little sense. I'm curious, why the sudden pruning of features? Can you please consider removing SFINAE? I'd also love to see is expressions go the way of the dinosaur. I don't know what their replacement should look like, but there _has_ to be a better and less error prone syntax!
May 17 2009
next sibling parent Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> writes:
Jason House wrote:
 Andrei Alexandrescu Wrote:
 
 Consider:
 
 foreach (x; 1.0 .. 4.1) writeln(x); foreach_reverse (x; 1.0 .. 4.1)
 writeln(x);
 
 This sucks. foreach with interval for floating-point types should
 be disallowed.
 
 
 Andrei
I agree that makes little sense. I'm curious, why the sudden pruning of features? Can you please consider removing SFINAE? I'd also love to see is expressions go the way of the dinosaur. I don't know what their replacement should look like, but there _has_ to be a better and less error prone syntax!
I'm ready to submit the first 121 pages of TDPL to Rough Cuts. Those include an introductory chapter, expressions, and statements. It's hard for me to explain how I feel when I must write about features that I just know are straight wrong. I understand Hal now! Walter has been very accommodating, huge props to him. He is working on eliminating narrowing conversions for integrals, with a very cool scheme that eliminates most unnecessary narrowing casts. SFINAE sucks and I hope will be removed too. I don't feel very strongly about is(). Andrei
May 17 2009
prev sibling next sibling parent reply Robert Fraser <fraserofthenight gmail.com> writes:
Jason House wrote:
 Andrei Alexandrescu Wrote:
 
 Consider:

      foreach (x; 1.0 .. 4.1) writeln(x);
      foreach_reverse (x; 1.0 .. 4.1) writeln(x);

 This sucks. foreach with interval for floating-point types should be 
 disallowed.


 Andrei
I agree that makes little sense. I'm curious, why the sudden pruning of features? Can you please consider removing SFINAE? I'd also love to see is expressions go the way of the dinosaur. I don't know what their replacement should look like, but there _has_ to be a better and less error prone syntax!
I agree about SFINAE, but what's so bad about is()? If it does get removed, I hope whatever replaces it can do all the weird things is can (e.x. is(typeof({}())))
May 17 2009
next sibling parent Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> writes:
Robert Fraser wrote:
 Jason House wrote:
 Andrei Alexandrescu Wrote:

 Consider:

      foreach (x; 1.0 .. 4.1) writeln(x);
      foreach_reverse (x; 1.0 .. 4.1) writeln(x);

 This sucks. foreach with interval for floating-point types should be 
 disallowed.


 Andrei
I agree that makes little sense. I'm curious, why the sudden pruning of features? Can you please consider removing SFINAE? I'd also love to see is expressions go the way of the dinosaur. I don't know what their replacement should look like, but there _has_ to be a better and less error prone syntax!
I agree about SFINAE, but what's so bad about is()? If it does get removed, I hope whatever replaces it can do all the weird things is can (e.x. is(typeof({}())))
If-clauses in template definitions should do everything SFINAE does, cleaner. Andrei
May 17 2009
prev sibling parent reply grauzone <none example.net> writes:
Robert Fraser wrote:
 Jason House wrote:
 Andrei Alexandrescu Wrote:

 Consider:

      foreach (x; 1.0 .. 4.1) writeln(x);
      foreach_reverse (x; 1.0 .. 4.1) writeln(x);

 This sucks. foreach with interval for floating-point types should be 
 disallowed.


 Andrei
I agree that makes little sense. I'm curious, why the sudden pruning of features? Can you please consider removing SFINAE? I'd also love to see is expressions go the way of the dinosaur. I don't know what their replacement should look like, but there _has_ to be a better and less error prone syntax!
I agree about SFINAE, but what's so bad about is()? If it does get removed, I hope whatever replaces it can do all the weird things is can (e.x. is(typeof({}())))
Isn't is() also a kind of SFINAE? SFINAE is Substitution Failure Is Not An Error (or so). That means, if there's an error trying to apply a template, the error is silently ignored, and the compiler tries the next template declaration. (Correct me if I'm wrong.) is() does something similar: it tries to compile the expression inside is(), and if it fails, the compiler silently ignores the error and returns "false" to the if. The problem is: you can't really know if that what you intended to test with is() was false, or if another random semantic error happened inside the is() expression. Look at this for example:
 writefln("%s", is(typeof(rtzx) == char));
This compiles even if rtzx doesn't exist. But you probably wanted to check the type of rtzx, not it if rtzx exists. If you mistyped rtzx, the compiler will never tell you. Now Andrei didn't really explain his problem with is()...
May 17 2009
parent reply Christopher Wright <dhasenan gmail.com> writes:
grauzone wrote:
 Look at this for example:
  > writefln("%s", is(typeof(rtzx) == char));
 This compiles even if rtzx doesn't exist. But you probably wanted to 
 check the type of rtzx, not it if rtzx exists. If you mistyped rtzx, the 
 compiler will never tell you.
You can do 'is(typeof(rtzx)) && is(typeof(rtzx) == char)', or wrap it in a template.
May 18 2009
parent grauzone <none example.net> writes:
Christopher Wright wrote:
 grauzone wrote:
 Look at this for example:
  > writefln("%s", is(typeof(rtzx) == char));
 This compiles even if rtzx doesn't exist. But you probably wanted to 
 check the type of rtzx, not it if rtzx exists. If you mistyped rtzx, 
 the compiler will never tell you.
You can do 'is(typeof(rtzx)) && is(typeof(rtzx) == char)', or wrap it in a template.
The first is() in your expression is completely redundant, though. Not sure what you mean. Anyway, my point was not about what's possible, but that it leads to not very robust code. Besides, you can't even tell what exactly went wrong inside the is(), because the compiler (of course) doesn't emit any error messages if that code isn't compileable.
May 18 2009
prev sibling parent Jesse Phillips <JesseKPhillips gmail.com> writes:
On Sun, 17 May 2009 21:25:50 -0400, Jason House wrote:

 
 I agree that makes little sense.
 
 I'm curious, why the sudden pruning of features? Can you please consider
 removing SFINAE? I'd also love to see is expressions go the way of the
 dinosaur. I don't know what their replacement should look like, but
 there _has_ to be a better and less error prone syntax!
So, what is SFINAE?
May 17 2009
prev sibling next sibling parent reply Georg Wrede <georg.wrede iki.fi> writes:
Andrei Alexandrescu wrote:
 Consider:
 
     foreach (x; 1.0 .. 4.1) writeln(x);
     foreach_reverse (x; 1.0 .. 4.1) writeln(x);
 
 This sucks. foreach with interval for floating-point types should be 
 disallowed.
As long as you don't also remove the regular for loop with floating-point types.
May 17 2009
parent Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> writes:
Georg Wrede wrote:
 Andrei Alexandrescu wrote:
 Consider:

     foreach (x; 1.0 .. 4.1) writeln(x);
     foreach_reverse (x; 1.0 .. 4.1) writeln(x);

 This sucks. foreach with interval for floating-point types should be 
 disallowed.
As long as you don't also remove the regular for loop with floating-point types.
Yah. Great, I'm glad to see that others think the same. Andrei
May 17 2009
prev sibling next sibling parent "Lars T. Kyllingstad" <public kyllingen.NOSPAMnet> writes:
Andrei Alexandrescu wrote:
 Consider:
 
     foreach (x; 1.0 .. 4.1) writeln(x);
     foreach_reverse (x; 1.0 .. 4.1) writeln(x);
 
 This sucks. foreach with interval for floating-point types should be 
 disallowed.
 
 
 Andrei
I didn't even know this was possible, but I agree, it's an ugly thing. -Lars
May 18 2009
prev sibling next sibling parent reply "Denis Koroskin" <2korden gmail.com> writes:
On Mon, 18 May 2009 04:28:24 +0400, Andrei Alexandrescu
<SeeWebsiteForEmail erdani.org> wrote:

 Consider:

      foreach (x; 1.0 .. 4.1) writeln(x);
      foreach_reverse (x; 1.0 .. 4.1) writeln(x);

 This sucks. foreach with interval for floating-point types should be  
 disallowed.


 Andrei
It's useless, unless a step is specified (btw, integer iteration would benefit from having a step, too) I don't mind if the whole .. feature is removed. It could be implemented in a library, with an optional step: foreach (x; range(0, 100)) { // step is 1 implicitly // ... } foreach (x; range(0, 100, 2)) { // explicit step // ... } This feels more functional, although slightly longer to type.
May 18 2009
parent Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> writes:
Denis Koroskin wrote:
 On Mon, 18 May 2009 04:28:24 +0400, Andrei Alexandrescu 
 <SeeWebsiteForEmail erdani.org> wrote:
 
 Consider:

      foreach (x; 1.0 .. 4.1) writeln(x);
      foreach_reverse (x; 1.0 .. 4.1) writeln(x);

 This sucks. foreach with interval for floating-point types should be 
 disallowed.


 Andrei
It's useless, unless a step is specified (btw, integer iteration would benefit from having a step, too) I don't mind if the whole .. feature is removed. It could be implemented in a library, with an optional step: foreach (x; range(0, 100)) { // step is 1 implicitly // ... } foreach (x; range(0, 100, 2)) { // explicit step // ... } This feels more functional, although slightly longer to type.
It's actually there already: std.range.iota. Incidentally it does the right thing with floats because it iterates by the recurrence formula iter(i) = lowest + i * step (where i is an integer). But there's an unrelated bugzilla about it. Andrei
May 18 2009
prev sibling parent reply "Steven Schveighoffer" <schveiguy yahoo.com> writes:
On Sun, 17 May 2009 20:28:24 -0400, Andrei Alexandrescu  
<SeeWebsiteForEmail erdani.org> wrote:

 Consider:

      foreach (x; 1.0 .. 4.1) writeln(x);
      foreach_reverse (x; 1.0 .. 4.1) writeln(x);

 This sucks. foreach with interval for floating-point types should be  
 disallowed.
foreach_reverse sucks in its own right, while you're looking for stuff to get rid of, I think it can be done better. foreach(x; 4 .. 1 ) should do a reverse interval (and looks way more readable). foreach(x; array.reverse) should iterate in reverse. for classes, using a method called reverse should work fine: foreach(x; myclass.reverse) Having to implement opApplyReverse is rediculous, and having a keyword like foreach_reverse is rediculous. Reverse isn't the only interesting iteration pattern, so why focus a whole keyword and syntax on that? -Steve
May 18 2009
next sibling parent reply Jacob Carlborg <doob me.com> writes:
Steven Schveighoffer wrote:
 On Sun, 17 May 2009 20:28:24 -0400, Andrei Alexandrescu 
 <SeeWebsiteForEmail erdani.org> wrote:
 
 Consider:

      foreach (x; 1.0 .. 4.1) writeln(x);
      foreach_reverse (x; 1.0 .. 4.1) writeln(x);

 This sucks. foreach with interval for floating-point types should be 
 disallowed.
foreach_reverse sucks in its own right, while you're looking for stuff to get rid of, I think it can be done better. foreach(x; 4 .. 1 ) should do a reverse interval (and looks way more readable). foreach(x; array.reverse) should iterate in reverse. for classes, using a method called reverse should work fine: foreach(x; myclass.reverse) Having to implement opApplyReverse is rediculous, and having a keyword like foreach_reverse is rediculous. Reverse isn't the only interesting iteration pattern, so why focus a whole keyword and syntax on that? -Steve
I agree with that, but how would you differ foreach(x; array.reverse) from the array.reverse that modifies the array?
May 18 2009
parent reply "Steven Schveighoffer" <schveiguy yahoo.com> writes:
On Mon, 18 May 2009 09:54:16 -0400, Jacob Carlborg <doob me.com> wrote:

 Steven Schveighoffer wrote:
 On Sun, 17 May 2009 20:28:24 -0400, Andrei Alexandrescu  
 <SeeWebsiteForEmail erdani.org> wrote:

 Consider:

      foreach (x; 1.0 .. 4.1) writeln(x);
      foreach_reverse (x; 1.0 .. 4.1) writeln(x);

 This sucks. foreach with interval for floating-point types should be  
 disallowed.
foreach_reverse sucks in its own right, while you're looking for stuff to get rid of, I think it can be done better. foreach(x; 4 .. 1 ) should do a reverse interval (and looks way more readable). foreach(x; array.reverse) should iterate in reverse. for classes, using a method called reverse should work fine: foreach(x; myclass.reverse) Having to implement opApplyReverse is rediculous, and having a keyword like foreach_reverse is rediculous. Reverse isn't the only interesting iteration pattern, so why focus a whole keyword and syntax on that? -Steve
I agree with that, but how would you differ foreach(x; array.reverse) from the array.reverse that modifies the array?
D'oh! I picked the wrong property name. Forgot about the existing reverse property! Just to clarify, I am *not* advocating that the propery way to iterate an array in reverse is to first reverse the array! So pick some other property name: foreach(x; array.backwards) or whatever. Too bad reverse is already taken :( -Steve
May 18 2009
next sibling parent reply dsimcha <dsimcha yahoo.com> writes:
== Quote from Steven Schveighoffer (schveiguy yahoo.com)'s article
 On Mon, 18 May 2009 09:54:16 -0400, Jacob Carlborg <doob me.com> wrote:
 Steven Schveighoffer wrote:
 On Sun, 17 May 2009 20:28:24 -0400, Andrei Alexandrescu
 <SeeWebsiteForEmail erdani.org> wrote:

 Consider:

      foreach (x; 1.0 .. 4.1) writeln(x);
      foreach_reverse (x; 1.0 .. 4.1) writeln(x);

 This sucks. foreach with interval for floating-point types should be
 disallowed.
foreach_reverse sucks in its own right, while you're looking for stuff to get rid of, I think it can be done better. foreach(x; 4 .. 1 ) should do a reverse interval (and looks way more readable). foreach(x; array.reverse) should iterate in reverse. for classes, using a method called reverse should work fine: foreach(x; myclass.reverse) Having to implement opApplyReverse is rediculous, and having a keyword like foreach_reverse is rediculous. Reverse isn't the only interesting iteration pattern, so why focus a whole keyword and syntax on that? -Steve
I agree with that, but how would you differ foreach(x; array.reverse) from the array.reverse that modifies the array?
D'oh! I picked the wrong property name. Forgot about the existing reverse property! Just to clarify, I am *not* advocating that the propery way to iterate an array in reverse is to first reverse the array! So pick some other property name: foreach(x; array.backwards) or whatever. Too bad reverse is already taken :( -Steve
I think what you're looking for is retro() in std.range. There are a few problemswith getting rid of foreach_reverse, though: 1. It would have to stay in D1. This is not a serious problem, since D2 already introduces so many breaking changes. 2. Using retro() would not be a full replacement when it comes to arrays. For example, you can't get the indices by doing a foreach(i, elem; retro(someArray)) {} 3. As discussed here before, opApply has legitimate uses and is likely not going anywhere. In this case, foreach_reverse is the only way to iterate over a range backwards. 4. Iteration using the range interface is currently slower than with arrays. I posted some benchmarks a while back that were meant to demonstrate something else but demonstrated this as a side effect. This is unlikely to matter unless you're in a very small inner loop, such that the loop overhead is significant compared to the contents of the loop, but some people with insane performance requirements might care.
May 18 2009
next sibling parent reply Leandro Lucarella <llucax gmail.com> writes:
dsimcha, el 18 de mayo a las 14:58 me escribiste:
 2.  Using retro() would not be a full replacement when it comes to arrays.  For
 example, you can't get the indices by doing a
 
 foreach(i, elem; retro(someArray)) {}
Python has an "enumerate" function exactly for this. Is a generator that returns a tuple with (index, element). That should be easily implemented in D2 as a range, I guess. -- Leandro Lucarella (luca) | Blog colectivo: http://www.mazziblog.com.ar/blog/ ---------------------------------------------------------------------------- GPG Key: 5F5A8D05 (F8CD F9A7 BF00 5431 4145 104C 949E BFB6 5F5A 8D05) ----------------------------------------------------------------------------
May 18 2009
parent reply bearophile <bearophileHUGS lycos.com> writes:
Leandro Lucarella:

 foreach(i, elem; retro(someArray)) {}
Python has an "enumerate" function exactly for this.
Not exactly for that. To have something like that you need something more (reversed is lazy):
 iterable = "abcd"
 for i, elem in enumerate(reversed(iterable)):
... print i, elem ... 0 d 1 c 2 b 3 a Bye, bearophile
May 18 2009
parent Leandro Lucarella <llucax gmail.com> writes:
bearophile, el 18 de mayo a las 11:19 me escribiste:
 Leandro Lucarella:
 
 foreach(i, elem; retro(someArray)) {}
Python has an "enumerate" function exactly for this.
Not exactly for that. To have something like that you need something more (reversed is lazy):
 iterable = "abcd"
 for i, elem in enumerate(reversed(iterable)):
... print i, elem ... 0 d 1 c 2 b 3 a
That's exactly what I was saying, you removed the context of my message. In D2 that would be: foreach (i, elem; enumerate(retro(someArray))) {} -- Leandro Lucarella (luca) | Blog colectivo: http://www.mazziblog.com.ar/blog/ ---------------------------------------------------------------------------- GPG Key: 5F5A8D05 (F8CD F9A7 BF00 5431 4145 104C 949E BFB6 5F5A 8D05) ----------------------------------------------------------------------------
May 18 2009
prev sibling next sibling parent "Steven Schveighoffer" <schveiguy yahoo.com> writes:
On Mon, 18 May 2009 10:58:46 -0400, dsimcha <dsimcha yahoo.com> wrote:

 I think what you're looking for is retro() in std.range.  There are a few
 problemswith getting rid of foreach_reverse, though:

 1.  It would have to stay in D1.  This is not a serious problem, since  
 D2 already
 introduces so many breaking changes.
Agreed, not a problem.
 2.  Using retro() would not be a full replacement when it comes to  
 arrays.  For
 example, you can't get the indices by doing a

 foreach(i, elem; retro(someArray)) {}
I'm talking about having a builtin property to arrays that signals it should be iterated in reverse, not a library solution. It can enjoy the same benefits of the current foreach_reverse. As a side note, we need to figure out how to make ranges so they can do things like get indices, there has been some discussion on that. Not having indices is going to make interesting ranges hard to use. For example, iterating over a dictionary using a range will have to return some kind of key/value pair.
 3.  As discussed here before, opApply has legitimate uses and is likely  
 not going
 anywhere.  In this case, foreach_reverse is the only way to iterate over  
 a range
 backwards.
Not true. You can call foreach(x; delegate) to iterate using any delegate that has the "opApply" form. One minor restriction (that I proposed be removed, see issue 2443) is that it has to be a delegate, which means that you normally have to call it like this: foreach(x; &obj.inReverse)
 4.  Iteration using the range interface is currently slower than with  
 arrays.  I
 posted some benchmarks a while back that were meant to demonstrate  
 something else
 but demonstrated this as a side effect.  This is unlikely to matter  
 unless you're
 in a very small inner loop, such that the loop overhead is significant  
 compared to
 the contents of the loop, but some people with insane performance  
 requirements
 might care.
Again, this is moot because I'm not proposing using library functions, they would be builtins (for arrays only of course, user objects still need to define an opApply-like function). However, I think this will be fixed in the future, because range method calls should be inlined in the foreach loop (they are probably not currently). And no feature should be discounted because it doesn't perform well today, unless you can prove that it's impossible to make it perform well. I hate this mentality some people have about D. Goes along with the mentality that modules should be small because the compiler/linker sucks at trimming unused portions from object files... -Steve
May 18 2009
prev sibling parent Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> writes:
dsimcha wrote:
 2.  Using retro() would not be a full replacement when it comes to arrays.  For
 example, you can't get the indices by doing a
 
 foreach(i, elem; retro(someArray)) {}
This needs fixing.
 4.  Iteration using the range interface is currently slower than with arrays. 
I
 posted some benchmarks a while back that were meant to demonstrate something
else
 but demonstrated this as a side effect.  This is unlikely to matter unless
you're
 in a very small inner loop, such that the loop overhead is significant
compared to
 the contents of the loop, but some people with insane performance requirements
 might care.
Yah, popFront changes two words instead of one. Andrei
May 18 2009
prev sibling parent Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> writes:
Steven Schveighoffer wrote:
 On Mon, 18 May 2009 09:54:16 -0400, Jacob Carlborg <doob me.com> wrote:
 
 Steven Schveighoffer wrote:
 On Sun, 17 May 2009 20:28:24 -0400, Andrei Alexandrescu 
 <SeeWebsiteForEmail erdani.org> wrote:

 Consider:

      foreach (x; 1.0 .. 4.1) writeln(x);
      foreach_reverse (x; 1.0 .. 4.1) writeln(x);

 This sucks. foreach with interval for floating-point types should be 
 disallowed.
foreach_reverse sucks in its own right, while you're looking for stuff to get rid of, I think it can be done better. foreach(x; 4 .. 1 ) should do a reverse interval (and looks way more readable). foreach(x; array.reverse) should iterate in reverse. for classes, using a method called reverse should work fine: foreach(x; myclass.reverse) Having to implement opApplyReverse is rediculous, and having a keyword like foreach_reverse is rediculous. Reverse isn't the only interesting iteration pattern, so why focus a whole keyword and syntax on that? -Steve
I agree with that, but how would you differ foreach(x; array.reverse) from the array.reverse that modifies the array?
D'oh! I picked the wrong property name. Forgot about the existing reverse property! Just to clarify, I am *not* advocating that the propery way to iterate an array in reverse is to first reverse the array! So pick some other property name: foreach(x; array.backwards) or whatever. Too bad reverse is already taken :( -Steve
sort and reverse for slices should go, by the way. Andrei
May 18 2009
prev sibling parent reply Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> writes:
Steven Schveighoffer wrote:
 On Sun, 17 May 2009 20:28:24 -0400, Andrei Alexandrescu 
 <SeeWebsiteForEmail erdani.org> wrote:
 
 Consider:

      foreach (x; 1.0 .. 4.1) writeln(x);
      foreach_reverse (x; 1.0 .. 4.1) writeln(x);

 This sucks. foreach with interval for floating-point types should be 
 disallowed.
foreach_reverse sucks in its own right, while you're looking for stuff to get rid of, I think it can be done better. foreach(x; 4 .. 1 ) should do a reverse interval (and looks way more readable).
I'm a bit leery about this - what if user code has a bug and I transform that into a feature?
 foreach(x; array.reverse) should iterate in reverse.
foreach (x; array.retro) already works.
 for classes, using a method called reverse should work fine:
 
 foreach(x; myclass.reverse)
 
 Having to implement opApplyReverse is rediculous, and having a keyword 
 like foreach_reverse is rediculous.  Reverse isn't the only interesting 
 iteration pattern, so why focus a whole keyword and syntax on that?
I agree. Andrei
May 18 2009
parent reply "Steven Schveighoffer" <schveiguy yahoo.com> writes:
On Mon, 18 May 2009 12:02:30 -0400, Andrei Alexandrescu  
<SeeWebsiteForEmail erdani.org> wrote:

 Steven Schveighoffer wrote:
 On Sun, 17 May 2009 20:28:24 -0400, Andrei Alexandrescu  
 <SeeWebsiteForEmail erdani.org> wrote:

 Consider:

      foreach (x; 1.0 .. 4.1) writeln(x);
      foreach_reverse (x; 1.0 .. 4.1) writeln(x);

 This sucks. foreach with interval for floating-point types should be  
 disallowed.
foreach_reverse sucks in its own right, while you're looking for stuff to get rid of, I think it can be done better. foreach(x; 4 .. 1 ) should do a reverse interval (and looks way more readable).
I'm a bit leery about this - what if user code has a bug and I transform that into a feature?
hm... I guess that's one way to look at it. I don't anticipate many typing this by mistake. One thing that would be left to decide, 1..4 means 1-2-3, should 4..1 mean 4-3-2 or 3-2-1? I'd vote for 4-3-2 to be consistent on having x..y mean inclusive to exclusive.
 foreach(x; array.reverse) should iterate in reverse.
foreach (x; array.retro) already works.
As I said later, I'm not stuck on the name. Just that it should be a property (BTW, has the requirement for parens after an array "property" been fixed yet?). I don't care if it's a library solution as long as the library solution can perform as well as the current solution, and can implement the api of the current solution (i.e. can also iterate indexes). Otherwise, you'll have grumbling ;) -Steve
May 18 2009
next sibling parent bearophile <bearophileHUGS lycos.com> writes:
Steven Schveighoffer:

 hm... I guess that's one way to look at it.  I don't anticipate many  
 typing this by mistake.  One thing that would be left to decide, 1..4  
 means 1-2-3, should 4..1 mean 4-3-2 or 3-2-1?  I'd vote for 4-3-2 to be  
 consistent on having x..y mean inclusive to exclusive.
Python shows the coherent behavior:
 list(xrange(4, 1))
[]
 list(xrange(4, 1, -1))
[4, 3, 2] It's easy to convince me that other behaviors are more correct. Bye, bearophile
May 18 2009
prev sibling parent reply Bill Baxter <wbaxter gmail.com> writes:
On Mon, May 18, 2009 at 9:21 AM, Steven Schveighoffer
<schveiguy yahoo.com> wrote:
 On Mon, 18 May 2009 12:02:30 -0400, Andrei Alexandrescu
 I'm a bit leery about this - what if user code has a bug and I transform
 that into a feature?
hm... I guess that's one way to look at it. =A0I don't anticipate many ty=
ping
 this by mistake.
Can't you use variables in those ".." expressions? If so it's not so obvious when you see x..y that y is less than x. --bb
May 18 2009
parent "Steven Schveighoffer" <schveiguy yahoo.com> writes:
On Mon, 18 May 2009 13:30:19 -0400, Bill Baxter <wbaxter gmail.com> wrote:

 On Mon, May 18, 2009 at 9:21 AM, Steven Schveighoffer
 <schveiguy yahoo.com> wrote:
 On Mon, 18 May 2009 12:02:30 -0400, Andrei Alexandrescu
 I'm a bit leery about this - what if user code has a bug and I  
 transform
 that into a feature?
hm... I guess that's one way to look at it.  I don't anticipate many typing this by mistake.
Can't you use variables in those ".." expressions? If so it's not so obvious when you see x..y that y is less than x.
And what happens today if y is less than x? Just no loop iterations, or does it wrap? Honestly, I thought it was a compile time feature only. Can you use delegates/properties also? In that case, returning a range that's reversed is the only alternative... It's still better than foreach_reverse(x; 1..4) IMO. -Steve
May 18 2009