digitalmars.D.learn - Foreach problem
- Tim M (14/14) Jan 10 2009 Why is this an error. Dmd wants to make sure that I declare a new variab...
- Daniel Keep (4/24) Jan 10 2009 Yes; as the error states, you're not allowed to define variables with
- Tim M (3/21) Jan 10 2009 Why does it still work for some objects?
- Tim M (30/55) Jan 10 2009 This works:
- Bill Baxter (5/36) Jan 10 2009 Interesting. But there the inner 'a' is actually a B. So it
- Tim M (4/47) Jan 10 2009 Sorry for my typo but change that line to:
- Bill Baxter (5/56) Jan 10 2009 'Still compiles" or "then it will compile"?
- Denis Koroskin (2/59) Jan 10 2009 It is a bug and should be reported.
- Tim M (6/74) Jan 10 2009 Yep that probibly is a slight bug. What I would like to know is why cant...
- Denis Koroskin (12/90) Jan 10 2009 You got it wrong, foreach never use an existing variable. Try yourself:
- Tim M (6/10) Jan 11 2009 Just re reading my own question I think it is clear what I meant. I mean...
- Denis Koroskin (2/13) Jan 11 2009 Example, please? I never noticed any difference.
- Tim M (5/24) Jan 11 2009 Ok just did another test. Objects are handled the same way like you said...
- Steven Schveighoffer (27/95) Jan 12 2009 I'm not so sure.
- Bill Baxter (5/10) Jan 12 2009 That's an implementation detail and shouldn't effect the behavior
- Jarrett Billingsley (2/4) Jan 10 2009 You can't reuse existing variables as foreach loop indices, long story s...
- Bill Baxter (15/29) Jan 10 2009 I think this should be allowable.
Why is this an error. Dmd wants to make sure that I declare a new variable in the foreach statement and not use an existing one? module test; void main() { int i; int[] nums; foreach(i; nums) { // } } dmd test.d test.d(7): Error: shadowing declaration test.main.i is deprecated
Jan 10 2009
Tim M wrote:Why is this an error. Dmd wants to make sure that I declare a new variable in the foreach statement and not use an existing one? module test; void main() { int i; int[] nums; foreach(i; nums) { // } } dmd test.d test.d(7): Error: shadowing declaration test.main.i is deprecatedYes; as the error states, you're not allowed to define variables with the same name as variables in an enclosing scope any more. -- Daniel
Jan 10 2009
On Sun, 11 Jan 2009 15:50:54 +1300, Daniel Keep <daniel.keep.lists gmail.com> wrote:Tim M wrote:Why does it still work for some objects?Why is this an error. Dmd wants to make sure that I declare a new variable in the foreach statement and not use an existing one? module test; void main() { int i; int[] nums; foreach(i; nums) { // } } dmd test.d test.d(7): Error: shadowing declaration test.main.i is deprecatedYes; as the error states, you're not allowed to define variables with the same name as variables in an enclosing scope any more. -- Daniel
Jan 10 2009
On Sun, 11 Jan 2009 15:59:26 +1300, Tim M <a b.com> wrote:On Sun, 11 Jan 2009 15:50:54 +1300, Daniel Keep <daniel.keep.lists gmail.com> wrote:This works: module test; class A { this() { // } } class B { this() { // } int opApply (int delegate (inout B) dg) { return 1; } } void main() { A a; B b; foreach(a; b) { // } }Tim M wrote:Why does it still work for some objects?Why is this an error. Dmd wants to make sure that I declare a new variable in the foreach statement and not use an existing one? module test; void main() { int i; int[] nums; foreach(i; nums) { // } } dmd test.d test.d(7): Error: shadowing declaration test.main.i is deprecatedYes; as the error states, you're not allowed to define variables with the same name as variables in an enclosing scope any more. -- Daniel
Jan 10 2009
On Sun, Jan 11, 2009 at 12:04 PM, Tim M <a b.com> wrote:On Sun, 11 Jan 2009 15:59:26 +1300, Tim M <a b.com> wrote:Interesting. But there the inner 'a' is actually a B. So it compiles, but there's no way it's using the outer 'a' as the counter variable. --bbWhy does it still work for some objects?This works: module test; class A { this() { // } } class B { this() { // } int opApply (int delegate (inout B) dg) { return 1; } } void main() { A a; B b; foreach(a; b) { // } }
Jan 10 2009
On Sun, 11 Jan 2009 16:10:39 +1300, Bill Baxter <wbaxter gmail.com> wrote:On Sun, Jan 11, 2009 at 12:04 PM, Tim M <a b.com> wrote:Sorry for my typo but change that line to: int opApply (int delegate (inout A) dg) and it still compiles.On Sun, 11 Jan 2009 15:59:26 +1300, Tim M <a b.com> wrote:Interesting. But there the inner 'a' is actually a B. So it compiles, but there's no way it's using the outer 'a' as the counter variable. --bbWhy does it still work for some objects?This works: module test; class A { this() { // } } class B { this() { // } int opApply (int delegate (inout B) dg) { return 1; } } void main() { A a; B b; foreach(a; b) { // } }
Jan 10 2009
On Sun, Jan 11, 2009 at 12:15 PM, Tim M <a b.com> wrote:On Sun, 11 Jan 2009 16:10:39 +1300, Bill Baxter <wbaxter gmail.com> wrote:'Still compiles" or "then it will compile"? Anyway, I'm curious if it's using the outer A or not. Can you add a line or two to actually modify 'a' in the loop? --bbOn Sun, Jan 11, 2009 at 12:04 PM, Tim M <a b.com> wrote:Sorry for my typo but change that line to: int opApply (int delegate (inout A) dg) and it still compiles.On Sun, 11 Jan 2009 15:59:26 +1300, Tim M <a b.com> wrote:Interesting. But there the inner 'a' is actually a B. So it compiles, but there's no way it's using the outer 'a' as the counter variable. --bbWhy does it still work for some objects?This works: module test; class A { this() { // } } class B { this() { // } int opApply (int delegate (inout B) dg) { return 1; } } void main() { A a; B b; foreach(a; b) { // } }
Jan 10 2009
On Sun, 11 Jan 2009 06:04:01 +0300, Tim M <a b.com> wrote:On Sun, 11 Jan 2009 15:59:26 +1300, Tim M <a b.com> wrote:It is a bug and should be reported.On Sun, 11 Jan 2009 15:50:54 +1300, Daniel Keep <daniel.keep.lists gmail.com> wrote:This works: module test; class A { this() { // } } class B { this() { // } int opApply (int delegate (inout B) dg) { return 1; } } void main() { A a; B b; foreach(a; b) { // } }Tim M wrote:Why does it still work for some objects?Why is this an error. Dmd wants to make sure that I declare a new variable in the foreach statement and not use an existing one? module test; void main() { int i; int[] nums; foreach(i; nums) { // } } dmd test.d test.d(7): Error: shadowing declaration test.main.i is deprecatedYes; as the error states, you're not allowed to define variables with the same name as variables in an enclosing scope any more. -- Daniel
Jan 10 2009
On Sun, 11 Jan 2009 19:56:55 +1300, Denis Koroskin <2korden gmail.com> wrote:On Sun, 11 Jan 2009 06:04:01 +0300, Tim M <a b.com> wrote:Yep that probibly is a slight bug. What I would like to know is why cant I do foreach with primitive types like I can with objects. The objects use an existing variable but an int would require a new int defined with the foreach params.On Sun, 11 Jan 2009 15:59:26 +1300, Tim M <a b.com> wrote:It is a bug and should be reported.On Sun, 11 Jan 2009 15:50:54 +1300, Daniel Keep <daniel.keep.lists gmail.com> wrote:This works: module test; class A { this() { // } } class B { this() { // } int opApply (int delegate (inout B) dg) { return 1; } } void main() { A a; B b; foreach(a; b) { // } }Tim M wrote:Why does it still work for some objects?Why is this an error. Dmd wants to make sure that I declare a new variable in the foreach statement and not use an existing one? module test; void main() { int i; int[] nums; foreach(i; nums) { // } } dmd test.d test.d(7): Error: shadowing declaration test.main.i is deprecatedYes; as the error states, you're not allowed to define variables with the same name as variables in an enclosing scope any more. -- Daniel
Jan 10 2009
On Sun, 11 Jan 2009 10:08:47 +0300, Tim M <a b.com> wrote:On Sun, 11 Jan 2009 19:56:55 +1300, Denis Koroskin <2korden gmail.com> wrote:You can use foreach to iterate over arrays and tuples, if that's what you mean. Iterating over over primitive types makes little sense.On Sun, 11 Jan 2009 06:04:01 +0300, Tim M <a b.com> wrote:Yep that probibly is a slight bug. What I would like to know is why cant I do foreach with primitive types like I can with objects.On Sun, 11 Jan 2009 15:59:26 +1300, Tim M <a b.com> wrote:It is a bug and should be reported.On Sun, 11 Jan 2009 15:50:54 +1300, Daniel Keep <daniel.keep.lists gmail.com> wrote:This works: module test; class A { this() { // } } class B { this() { // } int opApply (int delegate (inout B) dg) { return 1; } } void main() { A a; B b; foreach(a; b) { // } }Tim M wrote:Why does it still work for some objects?Why is this an error. Dmd wants to make sure that I declare a new variable in the foreach statement and not use an existing one? module test; void main() { int i; int[] nums; foreach(i; nums) { // } } dmd test.d test.d(7): Error: shadowing declaration test.main.i is deprecatedYes; as the error states, you're not allowed to define variables with the same name as variables in an enclosing scope any more. -- DanielThe objects use an existing variable but an int would require a new int defined with the foreach params.You got it wrong, foreach never use an existing variable. Try yourself: void main() { B b; foreach (a; b) { } } Variable shadowing is disallowed for this very reason - to avoid "what variable do I use here" type of confusion. The code you provided is incorrect, but compiler currently accepts it (which is a bug). You should remove "A a;" from the main, it is never used anyway.
Jan 10 2009
On Sun, 11 Jan 2009 20:31:51 +1300, Denis Koroskin <2korden gmail.com> wrote:Just re reading my own question I think it is clear what I meant. I meant array of primitives so yes iterating over an array, but an array of primitives. Dmd handles foreach over SomeObject[] a lot more relaxed than int[].Yep that probibly is a slight bug. What I would like to know is why cant I do foreach with primitive types like I can with objects.You can use foreach to iterate over arrays and tuples, if that's what you mean. Iterating over over primitive types makes little sense.
Jan 11 2009
On Sun, 11 Jan 2009 11:04:38 +0300, Tim M <a b.com> wrote:On Sun, 11 Jan 2009 20:31:51 +1300, Denis Koroskin <2korden gmail.com> wrote:Example, please? I never noticed any difference.Just re reading my own question I think it is clear what I meant. I meant array of primitives so yes iterating over an array, but an array of primitives. Dmd handles foreach over SomeObject[] a lot more relaxed than int[].Yep that probibly is a slight bug. What I would like to know is why cant I do foreach with primitive types like I can with objects.You can use foreach to iterate over arrays and tuples, if that's what you mean. Iterating over over primitive types makes little sense.
Jan 11 2009
On Sun, 11 Jan 2009 21:39:55 +1300, Denis Koroskin <2korden gmail.com> wrote:On Sun, 11 Jan 2009 11:04:38 +0300, Tim M <a b.com> wrote:Ok just did another test. Objects are handled the same way like you said. The "problem" is actually in the opApply where it can work just fine (runs ok not just compiles ok) using the exisiting variable.On Sun, 11 Jan 2009 20:31:51 +1300, Denis Koroskin <2korden gmail.com> wrote:Example, please? I never noticed any difference.Just re reading my own question I think it is clear what I meant. I meant array of primitives so yes iterating over an array, but an array of primitives. Dmd handles foreach over SomeObject[] a lot more relaxed than int[].Yep that probibly is a slight bug. What I would like to know is why cant I do foreach with primitive types like I can with objects.You can use foreach to iterate over arrays and tuples, if that's what you mean. Iterating over over primitive types makes little sense.
Jan 11 2009
"Denis Koroskin" wroteOn Sun, 11 Jan 2009 06:04:01 +0300, Tim M <a b.com> wrote:I'm not so sure. Would you say this is a bug (it compiles)? int foo() { int i; int innerfoo(int i) { return i; } return innerfoo(2); // returns 2 } because that's basically what a foreach does when using opApply: create an inner function and then pass a delegate pointing to that function to opApply. I think the difference between the two is that the compiler handles foreach on an array in a special manner without using an inner function/delegate. This also fails to compile: void main() { A a; A[] b; foreach(a; b) { // } }On Sun, 11 Jan 2009 15:59:26 +1300, Tim M <a b.com> wrote:It is a bug and should be reported.On Sun, 11 Jan 2009 15:50:54 +1300, Daniel Keep <daniel.keep.lists gmail.com> wrote:This works: module test; class A { this() { // } } class B { this() { // } int opApply (int delegate (inout B) dg) { return 1; } } void main() { A a; B b; foreach(a; b) { // } }Tim M wrote:Why does it still work for some objects?Why is this an error. Dmd wants to make sure that I declare a new variable in the foreach statement and not use an existing one? module test; void main() { int i; int[] nums; foreach(i; nums) { // } } dmd test.d test.d(7): Error: shadowing declaration test.main.i is deprecatedYes; as the error states, you're not allowed to define variables with the same name as variables in an enclosing scope any more. -- Daniel
Jan 12 2009
On Tue, Jan 13, 2009 at 6:25 AM, Steven Schveighoffer <schveiguy yahoo.com> wrote:because that's basically what a foreach does when using opApply: create an inner function and then pass a delegate pointing to that function to opApply. I think the difference between the two is that the compiler handles foreach on an array in a special manner without using an inner function/delegate.That's an implementation detail and shouldn't effect the behavior visible to the user. --bb
Jan 12 2009
On Sat, Jan 10, 2009 at 9:33 PM, Tim M <a b.com> wrote:Why is this an error. Dmd wants to make sure that I declare a new variable in the foreach statement and not use an existing one?You can't reuse existing variables as foreach loop indices, long story short.
Jan 10 2009
On Sun, Jan 11, 2009 at 11:33 AM, Tim M <a b.com> wrote:Why is this an error. Dmd wants to make sure that I declare a new variable in the foreach statement and not use an existing one? module test; void main() { int i; int[] nums; foreach(i; nums) { // } } dmd test.d test.d(7): Error: shadowing declaration test.main.i is deprecatedI think this should be allowable. It's basically an unfortunate side effect of the decision to make the loop variables in foreach implicitly 'auto'. I'd kinda forgotten about that, but I remember when I first saw it thinking it looked like a particularly odious bit of special casing just in the name of saving a few keystrokes. It's the only place in D where you can declare a variable without any type or storage class AFAIK. The only think like it is some of the crazy 'is( )' expressions where you can define a new type without any 'alias' or 'typedef'. I wouldn't cry if D2 made specifying 'auto' a requirement in foreach. And allowed using an outer variable as the index like every other loop. It would certainly be more consistent. --bb
Jan 10 2009