October 04, 2002
"Mike Wynn" <mike.wynn@l8night.co.uk> wrote in message news:anjvh8$aes$1@digitaldaemon.com...
> I think this example show exactly what is require/expected,
> foreach should iterate an array forward there is not need for an assoc
array
> foreach
> my reason is simple, this covers both cases; those who don't care and
those
> who do

I think you're right.

> I would like to see 'foreach' used and not 'for' reused.
> foreach ( <var> in <array_expr> ) <block>

D already has too many keywords <g>.

> to iterate backwards you an use
> foreach( item in array.reverse ) { ... }
> which I assume should be quite easy for the optimiser to detect and
> shortcut.

That's a great idea! The only flaw is that array.reverse reverses the array in place, which might not be what's intended.

> for hashtables/assoc arrays by key
> foreach( item in hash.keys ) { ... } if your not bothered by order
> foreach( item in hash.keys.sort ) { ... } if you are bothered by order
> or by value
> foreach( item in hash.values) { ... } if your not bothered by order
> foreach( item in hash.values.sort ) { ... } if you are bothered by order
>
> again the optimiser should be able to detect some (if not all) of these
> conditions and rearrange them
> foreach( item in hash.keys ) { ... }can be reordered such in to the order
> most efficient order for the hashtable (this does not contradict my later
> statement about determanism because hash table key order IS ALWAYS non
> determanistic (unlike array item order)).

Great ideas!

> if you want values in key order then you'll have the below code with
> `hash[item]` to get the required item.
> foreach( item in hash.keys.sort ) { hash[item] ... } if you are bothered
by
> order



October 04, 2002
> > to iterate backwards you an use
> > foreach( item in array.reverse ) { ... }
> > which I assume should be quite easy for the optimiser to detect and
> > shortcut.
>
> That's a great idea! The only flaw is that array.reverse reverses the
array
> in place, which might not be what's intended.
>
then
 for( item in array.dup.reverse ) { ... }
// compiler will have to detect that the copy is not truely required
or change the array semantics to be (Perl again) pass by value
so array.reverse returns a new array
and adding a new operator .=
syntax object .= method( params );  equiv to object = object.method(
params );
so
Foo [] bar = getMyArray();
bar .= reverse; // instead of bar.reverse;
other = bar.reverse; // instead of other = bar.dup.reverse; or other[] =
bar[]; other.reverse;

this could go as far as makeing arrays by default be passed by value
'in int[]' means pass-by-value
'inout int[]' means pass-by-ref
'out int[]' returns a new array

I accept that predomantly only script languages have array default pass by value, and most compiled languages pass arrays by reference. and does effect perfromance if used too much.


October 04, 2002

"Mike Wynn" <mike.wynn@l8night.co.uk> wrote in message news:ankglo$sl5$1@digitaldaemon.com...
>
> > > to iterate backwards you an use
> > > foreach( item in array.reverse ) { ... }
> > > which I assume should be quite easy for the optimiser to detect and
> > > shortcut.
> >
> > That's a great idea! The only flaw is that array.reverse reverses the
> array
> > in place, which might not be what's intended.
> >
> then
>  for( item in array.dup.reverse ) { ... }
> // compiler will have to detect that the copy is not truely required

I am wondering if it might be better to define .reverse as doing a copy rather than in-place. You're right in that a better D compiler could optimize the .reverse away entirely in a foreach.


October 05, 2002
Walter wrote:
> "Mike Wynn" <mike.wynn@l8night.co.uk> wrote in message
> news:ankglo$sl5$1@digitaldaemon.com...
> 
>>>>to iterate backwards you an use
>>>>foreach( item in array.reverse ) { ... }
>>>>which I assume should be quite easy for the optimiser to detect and
>>>>shortcut.
>>>
>>>That's a great idea! The only flaw is that array.reverse reverses the
>>
>>array
>>
>>>in place, which might not be what's intended.
>>>
>>
>>then
>> for( item in array.dup.reverse ) { ... }
>>// compiler will have to detect that the copy is not truely required
> 
> 
> I am wondering if it might be better to define .reverse as doing a copy
> rather than in-place. You're right in that a better D compiler could
> optimize the .reverse away entirely in a foreach.

Is the array completely, totally immutable inside?  If not (and it shouldn't be), then the optimiser can't do anything no matter what.  I don't think there's much advantages to playing games here - there should be iterator properties instead (and iterators should be structs, not classes, so that they can usually be inlined).

Also, I think the iterated item should be an inout parameter, so that I can modify it, and that would also be faster.  So it should be declared in the for:

   for (Type item in array.ireverse)
       item = sin (item);

IMO this should keep the three-section form of for, which was a wise decision; otherwise things tend to break down rather horribly when the assumption that you don't need anything more complex is wrong (Python in particular is simply _awful_):

   each (int index; Type item in array; index ++)
       ...

And of course, I think putting new semantics in for is a bad idea.  Time for a new keyword.

October 05, 2002
Walter wrote:
>I am wondering if it might be better to define .reverse as doing a copy rather than in-place. You're right in that a better D compiler could optimize the .reverse away entirely in a foreach.

Why not offer both to the programmer, .reverse.inplace and .reverse.copy or something.

Mark


October 05, 2002
"Mark Evans" <Mark_member@pathlink.com> wrote in message news:anlsvl$2997$1@digitaldaemon.com...
> Walter wrote:
> >I am wondering if it might be better to define .reverse as doing a copy rather than in-place. You're right in that a better D compiler could optimize the .reverse away entirely in a foreach.
>
> Why not offer both to the programmer, .reverse.inplace and .reverse.copy
or
> something.

Each permutation makes the language more complicated. The goal is instead of providing m*n features, only provide m+n features which, when combined, offer m*n capabilities. In other words, provide a small base set of orthogonal building blocks, each easy to understand, that can be combined to form complex tasks that have obvious meanings from the base set.

This is why I'm a bit slow to adopt new features <g>.


October 05, 2002
In article <ann6h0$1c57$1@digitaldaemon.com>, Walter says...
>>
>> Why not offer both to the programmer, .reverse.inplace and .reverse.copy
>
>Each permutation makes the language more complicated. The goal is instead of
>providing m*n features, only provide m+n features which, when combined,
>offer m*n capabilities.>
>This is why I'm a bit slow to adopt new features <g>.
>

I agree.  The reverse indexing suggested earlier, but discounted by opponents as featuritis, would eliminate the need to reverse arrays inplace.

Mark


October 05, 2002
"Walter" <walter@digitalmars.com> wrote in news:ann6h0$1c57$1@digitaldaemon.com:

> Each permutation makes the language more complicated. The goal is instead of providing m*n features, only provide m+n features which, when combined, offer m*n capabilities. In other words, provide a small base set of orthogonal building blocks, each easy to understand, that can be combined to form complex tasks that have obvious meanings from the base set.
> 
> This is why I'm a bit slow to adopt new features <g>.
> 
> 



I think allowing object and structs to support
and iterator function like getNext would provide
a versatile solution to a lot of these cases.

// define iterator template
template Iterators(T)
{
  struct ReverseArr
  {
    T[] tArr;
    int curPos;

    bit getNext(out T t)
    {
      --curPos;
      if(curPos < 0)
        return false;

      t = tArr[curPos];

      return true;
    }
  }

  ReverseArr reverse(T[] t)
  {
    ReverseArr r;

    r.curPos = t.length;
    r.tArr = t;

    return r;
  }
}

// use iterator template

int[] a;

Iterators(int) intIter;

// calls getNext until it returns false
for(item in intIter.reverse(a))
{
}
October 07, 2002
> Looks like a good way of doing this, I never though of using it with associative arrays. Parhaps it could be multi-leveled...
>
> foo a[][];
> foo z[];
> foo v;
>
> for(v in z in a) ...

You can write it in this way:
for(z in a) for(v in z) ...

Or maybe:
for(v in z) ...
should be valid since the compiler knows the types of the variables.
_________________________________________
Sometimes this type of loop is used too:

char[] a, b;
assert(a.length == b.length);
for(int i; i < a.length; i++) {a[i] = b[i];}

Maybe it would be nice to have a sintax like this:
char[] a, b;
char i, j;
for(i in a; j in b) {i = j;}

But then three iterations will cause confusion with the for(;;) sintax!
The solution would be a new keyword ('foreach' or simply 'each').
_____________________________________
Only another observation. Think about the in keyword used to check if a
value is in an array (as suggested by Russell Lewis). It makes the for(a in
b) sintax ambiguous in the following example:
for(a in b ? c : d in e) {}
Do you understand what is intended? =)
for(((a in b) ? c : d) in e) {}

To avoid these ambiguity problems will can have a more intelligent use of parenthesis. See below.

char a, b[], c, d;
for(a) in(b) {}
/* as you can see, the in keyword is NOT between parenthesis */
for(c in b ? a : d) in(b) {}

Another solution is to use ':' instead if 'in'.
foreach(a : b) {}

However I agree that the "for each" construct is simply too useful to be not implemented.


October 07, 2002
"Dario" <supdar@yahoo.com> wrote in message news:ans0fk$o2a$1@digitaldaemon.com...
> Only another observation. Think about the in keyword used to check if a
> value is in an array (as suggested by Russell Lewis). It makes the for(a
in
> b) sintax ambiguous in the following example:
> for(a in b ? c : d in e) {}
> Do you understand what is intended? =)
> for(((a in b) ? c : d) in e) {}
>
> To avoid these ambiguity problems will can have a more intelligent use of parenthesis. See below.
>
> char a, b[], c, d;
> for(a) in(b) {}
> /* as you can see, the in keyword is NOT between parenthesis */
> for(c in b ? a : d) in(b) {}
>
> Another solution is to use ':' instead if 'in'.
> foreach(a : b) {}

Yeah, I know the in syntax is ambiguous, I need to come up with something that will work. Your ideas are good.


1 2
Next ›   Last »