Automatic Foreach
janderson
askme at me.com
Sat Apr 26 23:45:36 PDT 2008
I know Walter has his head stuck in Const/Invarient/Pure multithreading
land at the moment. I thought I'd fire off this interesting proposal
anyway.
This is a follow up proposal/suggestion to one I sent a while back. I
hope to flesh it out a bit more.
The idea is to automatically generate for loops for arrays that are used
as parameters. It will reduces type safety in one area but makes the
language more expressive, particularly for templates.
Basically:
void foo(char c)
{
...
}
...
char[] array;
...
This part:
foreach(auto value; array)
{
foo(array);
}
becomes:
foo(array);
More advanced stuff:
//////////////////////////////////////////////////
//Example 1
//////////////////////////////////////////////////
// The return value is called multiple times:
float[] array;
array ~= sqrt(array2);
Where sqrt is:
float sqrt(float value);
Would be equivalent to:
int i = array.length;
array.length += array2.length;
foreach(auto val; array2)
{
array[i++] = sqrt(val);
}
//////////////////////////////////////////////////
//Example 2
//////////////////////////////////////////////////
// When assigned to an array, that array should automatically be resized
to the number of iterations the function is be called.
float[] array = sqrt(array2); //array is resized to the correct size
Would be equivalent to:
float[] array;
array.length = array2.length;
int i = 0;
foreach(auto val; array2)
{
array[i++] = sqrt(val);
}
//////////////////////////////////////////////////
//Example 3
//////////////////////////////////////////////////
// Multiple array inputs should work like nested arrays.
vector[] vertex = dot(array1, array2);
Equivalent too:
vector[] vertex;
vector.length = array1.length * array2.length;
int i=0;
foreach (auto val1; array1)
{
foreach (auto val2; array2)
{
vertex[i++] = sqrt(val1, val2);
}
}
//////////////////////////////////////////////////
//Example Member functions
//////////////////////////////////////////////////
// This is potentially less useful and could be made illegal. I'll
mention it for completeness.
class A
{
void foo();
}
...
A[] a;
...
a.foo(); //Call foo for the length of a
Equivalent to:
foreach (auto val; a)
{
a.foo();
}
//////////////////////////////////////////////////
//Example Return types
//////////////////////////////////////////////////
proccess(array).foo().foo2();
Equivalent too:
foreach (auto val; )
{
proccess(val).foo().foo2();
}
//////////////////////////////////////////////////
//Use example nested
//////////////////////////////////////////////////
results ~= func(foo(array1), foo2(array2));
Equivalent too:
results.length += array1.length * array2.length;
int i = results.length;
foreach (auto val1; array1)
{
foreach (auto val2; array2)
{
results[i++] = func(foo(val1), foo2(val2));
}
}
//////////////////////////////////////////////////
//Use example
//////////////////////////////////////////////////
results ~= func(foo(array1)).method(array2);
results.length += array1.length * array2.length;
int i = results.length;
foreach (auto val1; array1)
{
foreach (auto val2; array2)
{
results[i++] = func(foo(val1)).method(val2);
}
}
//////////////////////////////////////////////////
//Use example with templates
//////////////////////////////////////////////////
void print(A ...)(A a)
{
write(a);
}
print(array1, array2, value);
//What happens here is the array is passed into the template, because an
array is a valid input into a template. The value is only evaluated
when inside the template. See overloading rules below.
So it's equivalent to:
foreach (auto val; array1)
{
write(val);
}
foreach (auto val; array2)
{
write(val);
}
Overloading rules:
This auto foreach is given the lowest priority. If there's already a
way to call the function then that will be used. That will enable
people to specialize how arrays are handled for different functions be
overloading it. Templates for example, an array is a valid input so it
won't call the template function multiple times.
Working with the future:
The proposal should work well with features such as pure functions. It
should be as optimal as foreach statements however the compiler would
have to do less work to realize optimizations.
Interchangeable methods/functions: If this feature comes in, I don't see
any problem with the proposal working.
Rantional:
Half the time I create a for loop I endup encapsulating it in a
function. If D automatically created the function it would be one less
thing to worry about. If I need specialize behavior I could always
specialize the function later by providing an overload.
I think having this functionality would remove much of the need for
being able to iterate over 2 arrays at the same time.
Comment:
I know python has syntax not unlike this, however I believe the above is
even simpler.
What do you think?
More information about the Digitalmars-d
mailing list