Jump to page: 1 2
Thread overview
for, foreach identifier allowed in c throws error in d
Jun 02, 2014
Logesh Pillay
Jun 02, 2014
Logesh Pillay
Jun 02, 2014
Logesh Pillay
Jun 02, 2014
Logesh Pillay
Jun 02, 2014
John Colvin
Jun 03, 2014
John Colvin
Jun 02, 2014
John Colvin
June 02, 2014
It is common in a recursive function to amend a global array using the function parameter to refer to the element eg

int[10];

void foo (int i) {
  foreach (x; 0 .. 9) {
     t[i] = x;
     foo ();

C in a for loop allows use of t[i] directly as the iterating variable so you don't need the dummy variable x which has no real function.

D does not.  The error generated is "no identifier for declarator t[i]". For a long time, I thought that was specific to foreach but the same thing happens with for.

It looks like an unnecessary restriction.  Am I missing something?
June 02, 2014
Of course, in the first line I meant to say
int[10] t;
June 02, 2014
On Mon, 02 Jun 2014 15:21:06 -0400, Logesh Pillay <lp.court.jester@gmail.com> wrote:

> It is common in a recursive function to amend a global array using the function parameter to refer to the element eg
>
> int[10];
>
> void foo (int i) {
>    foreach (x; 0 .. 9) {
>       t[i] = x;
>       foo ();
>
> C in a for loop allows use of t[i] directly as the iterating variable so you don't need the dummy variable x which has no real function.
>
> D does not.  The error generated is "no identifier for declarator t[i]". For a long time, I thought that was specific to foreach but the same thing happens with for.
>
> It looks like an unnecessary restriction.  Am I missing something?

Can you post a full compiling example? I can't figure out what you are trying to do with this code.

-Steve
June 02, 2014
On Monday, 2 June 2014 at 19:21:07 UTC, Logesh Pillay wrote:
> It is common in a recursive function to amend a global array using the function parameter to refer to the element eg
>
> int[10];
>
> void foo (int i) {
>   foreach (x; 0 .. 9) {
>      t[i] = x;
>      foo ();
>
> C in a for loop allows use of t[i] directly as the iterating variable so you don't need the dummy variable x which has no real function.
>
> D does not.  The error generated is "no identifier for declarator t[i]". For a long time, I thought that was specific to foreach but the same thing happens with for.
>
> It looks like an unnecessary restriction.  Am I missing something?

works fine for me: http://dpaste.dzfl.pl/6ff9a3909fde
June 02, 2014
Issue has nothing to do with recursion.  That's only where I keep seeing it.

eg a function to generate combinations.

import std.stdio;

int[3] t;

void foo (int i) {
  if (i == 3)
    writef("%s\n", t);
  else foreach (x; 0 .. 3) {
    t[i] = x;
    foo(i+1);
  }
}

void main() {
  foo(0);
}

In C, I could put in the equivalent for statement for foreach, t[i] as the iterating variable. I won't need x which exists as a middleman only and save myself two lines.
June 02, 2014
On Mon, 02 Jun 2014 15:47:02 -0400, Logesh Pillay <lp.court.jester@gmail.com> wrote:

> Issue has nothing to do with recursion.  That's only where I keep seeing it.
>
> eg a function to generate combinations.
>
> import std.stdio;
>
> int[3] t;
>
> void foo (int i) {
>    if (i == 3)
>      writef("%s\n", t);
>    else foreach (x; 0 .. 3) {
>      t[i] = x;
>      foo(i+1);
>    }
> }
>
> void main() {
>    foo(0);
> }
>
> In C, I could put in the equivalent for statement for foreach, t[i] as the iterating variable. I won't need x which exists as a middleman only and save myself two lines.

OK, I get it. You want to do:

foreach(t[i]; 0 .. 3)

But this doesn't work.

This should (the equivalent for C):

for(t[i] = 0; t[i] < 3; ++t[i])

I'm trying to think of a way to do this without loops, but not sure. Note that foreach is expected to be given a new variable to declare, so you can't foreach with an existing variable on the left.

-Steve
June 02, 2014
Sorry, I am embarassed to say I've just tried the for equivalent and it works with t[i] as the iterating variable.

import std.stdio;

int[3] t;

void foo (int i) {
  if (i == 3)
    writef("%s\n", t);
  else for (t[i] = 0; t[i] < 3; t[i]++)
    foo(i+1);
}

void main() {
  foo(0);
}

Sorry, yet another overhasty post
June 02, 2014
On Mon, 02 Jun 2014 15:58:01 -0400, Steven Schveighoffer <schveiguy@yahoo.com> wrote:


> I'm trying to think of a way to do this without loops, but not sure.

I'm surprised, I looked for some kind of "apply" function like map, but just calls some function with each element in the range.

Something like this would make this a 1 (2?) liner:

if(i == t.length) writeln(t) else each!((x) => {t[i] = x; foo(i+1);})(iota(x.length));

But I can't find a phobos primitive for each. Would have expected it in std.algorithm or std.functional?

-Steve
June 02, 2014
On Monday, 2 June 2014 at 20:23:12 UTC, Steven Schveighoffer wrote:
> On Mon, 02 Jun 2014 15:58:01 -0400, Steven Schveighoffer <schveiguy@yahoo.com> wrote:
>
>
>> I'm trying to think of a way to do this without loops, but not sure.
>
> I'm surprised, I looked for some kind of "apply" function like map, but just calls some function with each element in the range.
>
> Something like this would make this a 1 (2?) liner:
>
> if(i == t.length) writeln(t) else each!((x) => {t[i] = x; foo(i+1);})(iota(x.length));
>
> But I can't find a phobos primitive for each. Would have expected it in std.algorithm or std.functional?
>
> -Steve

Its been discussed a few times. There were some objections (IIRC Walter thought that there was no significant advantage over plain foreach).
June 03, 2014
On Mon, 02 Jun 2014 17:25:24 -0400, John Colvin <john.loughran.colvin@gmail.com> wrote:

> On Monday, 2 June 2014 at 20:23:12 UTC, Steven Schveighoffer wrote:
>> On Mon, 02 Jun 2014 15:58:01 -0400, Steven Schveighoffer <schveiguy@yahoo.com> wrote:
>>
>>
>>> I'm trying to think of a way to do this without loops, but not sure.
>>
>> I'm surprised, I looked for some kind of "apply" function like map, but just calls some function with each element in the range.
>>
>> Something like this would make this a 1 (2?) liner:
>>
>> if(i == t.length) writeln(t) else each!((x) => {t[i] = x; foo(i+1);})(iota(x.length));
>>
>> But I can't find a phobos primitive for each. Would have expected it in std.algorithm or std.functional?
>>
>> -Steve
>
> Its been discussed a few times. There were some objections (IIRC Walter thought that there was no significant advantage over plain foreach).

Indeed, foreach is like such a construct:

... else each!((x) {t[i] = x; foo(i+1);})(iota(t.length));
... else foreach(x; 0 .. t.length) {t[i] = x; foo(i+1);}

It's even shorter and clearer.

I agree with Walter. Since such a construct by definition wouldn't return anything, you can't chain it. There really is little reason to have it.

-Steve
« First   ‹ Prev
1 2