Thread overview
About Array Operations
Aug 12, 2004
Mikola Lysenko
Aug 12, 2004
Mikola Lysenko
Aug 12, 2004
Stephen Waits
Aug 12, 2004
Mikola Lysenko
Aug 12, 2004
Ilya Minkov
Aug 14, 2004
Norbert Nemec
August 12, 2004
I really like the idea of array operations, since it seems like an elegant

and intuitive shorthand for working with vectors.  I have a few

(unreasonable) requests though.

I'd like to see the idea of array operations extended to any expression

involving arrays, for instance:



float[3] a = 0.0f;

printf("a := { ");
printf("%f ",a[]);
printf("}\n");



Creates the output,

a := { 0.0000 }




However, it would be very nice if using the empty block braces or a slice

automatically expanded the statement into a loop, so this code would expand

to



float[3] a = 0.0f;

printf("a := { ");
for(int i=0; i<a.length; i++)
printf(" %f",a[i]);
printf("}\n");


And have the output,

a := { 0.0000 0.0000 0.0000 }




Also array operations on multidimensional arrays don't work.  Something

like:



float[2][2] a = 1.0f, b = 2.0f, c;
c[][] = a[][] + b[][];



Generates a compiler error.  However, if multi-arrays were unrolled in a

logical left-to-right fashion, you would get the following equivalent

listing:



for(int i=0; i<c.length; i++)
for(int j=0; j<c[i].length; j++)
c[i][j] = a[i][j] + b[i][j];





I can also foresee some trickiness with this automated looping.  For

example, trying to normalize a vector quantity using this method is flawed:



real Magnitude(real[] v)
{
real sum = 0.0;
foreach(real r;v)
sum += r*r;
return sqrt(r);
}

real[3] a = { 1.0, 2.0, 3.0 };

a[] /= Magnitude(a);




Would cause Magnitude() to be called 3 times, each returning a different

value.  A correct way to normalize a would be




real Magnitude(real[] v)
{
real sum = 0.0;
foreach(real r;v)
sum += r*r;
return sqrt(r);
}

real[3] a = {0.0, 1.0, 2.0};

real maga = Magnitude(a);

a[] /= maga;


August 12, 2004
Sorry about the repost, but my text became completely and unreadably mangled after I copied and pasted from my text editor.  Hopefully it will look better this time.



I really like the idea of array operations, since it seems like an elegant and intuitive shorthand for working with vectors.  I have a few (unreasonable) requests though. I'd like to see the idea of array operations extended to any expression involving arrays, for instance:

#  float[3] a = 0.0f;
#
#  printf("a := { ");
#  printf("%f ",a[]);
#  printf("}\n");

Creates the output,

a := { 0.0000 }

However, it would be very nice if using the empty block braces or a slice automatically expanded the statement into a loop, so this code would expand to

#  float[3] a = 0.0f;
#
#  printf("a := { ");
#  for(int i=0; i<a.length; i++)
#  printf(" %f",a[i]);
#  printf("}\n");

And have the output,

a := { 0.0000 0.0000 0.0000 }

Also array operations on multidimensional arrays don't work.  Something like:

#  float[2][2] a = 1.0f, b = 2.0f, c;
#  c[][] = a[][] + b[][];

Generates a compiler error.  However, if multi-arrays were unrolled in a logical left-to-right fashion, you would get the following equivalent listing:

#  for(int i=0; i<c.length; i++)
#  for(int j=0; j<c[i].length; j++)
#  c[i][j] = a[i][j] + b[i][j];

I can also foresee some trickiness with this automated looping.  For example, trying to normalize a vector quantity using this method is flawed:

#  real Magnitude(real[] v)
#  {
#	real sum = 0.0;
#	foreach(real r;v)
# 	sum += r*r;
#	return sqrt(r);
#  }
#
#  real[3] a = { 1.0, 2.0, 3.0 };
#
#  a[] /= Magnitude(a);

Would cause Magnitude() to be called 3 times, each returning a different value. A correct way to normalize a would be

#  real Magnitude(real[] v)
#  {
#	real sum = 0.0;
#	foreach(real r;v)
#	sum += r*r;
#	return sqrt(r);
#  }
#
#  real[3] a = {0.0, 1.0, 2.0};
#
#  real maga = Magnitude(a);
#
#  a[] /= maga;


August 12, 2004
Mikola Lysenko wrote:
> 
> #  real Magnitude(real[] v)
> #  {
> #	real sum = 0.0;
> #	foreach(real r;v)
> # 	sum += r*r;
> #	return sqrt(r);
> #  }

I suspect you meant to say:

#  return sqrt(sum);
#              ^^^

> #  real Magnitude(real[] v)
> #  {
> #	real sum = 0.0;
> #	foreach(real r;v)
> #	sum += r*r;
> #	return sqrt(r);
> #  }

Here too.

--Steve
August 12, 2004
In article <cfg9m7$2e71$1@digitaldaemon.com>, Stephen Waits says...
>#
>#  return sqrt(sum);
>#              ^^^

Whoops!  I also shouldn't have declared a[] as a static array.  Anyway, these are both hypothetical examples, since these features aren't implemented in the current version of D.



August 12, 2004
I see a few problems with that:

* The operation on an array (slicing) makes outbound, not inbound changes. Since the semantic change progresses outwards from the operator, not inwards, it is not clear where to draw the bounds. One could artificially make it work with one complete statement, or with just one operator, which would lead to totally different results. And there is no way to specify if one wants, say, multiple statements to be affected.
* It would overload a semantic meaning already reserved for slicing, i.e. transforming an array into an array. And what if you just want to slice?
* I consider that *very* hard to spot visually, considering that a subtle syntactic change radically trows over the meaning of the program, and text search on it is impossible. Consider how much grief the C cast syntax has caused!
* It legalizes many expressions that would not work otherwise. For example, if you were calling a function which does not accept an array, it would work, although it was not your intention. C has one of the most ambiguos and watered syntaxes around, almost any typing mistake ends up being legal but false code - a tradition which need not be continued in D where it is not needed.

Besides all that, we already have an unambiguos way to do what you intend:

foreach(float el; a) printf("%f ",el);

foreach stetement allows to extend itself over multiple statements, does not allow manipulation of the index (like one could do in for), although it does allow to retrieve the index optionally. I'm not sure now, but i think it was intended that processing order is not specified either. So it is terse, versatile, and allows for agressive optimizations.

-eye


Mikola Lysenko schrieb:

> Sorry about the repost, but my text became completely and unreadably mangled
> after I copied and pasted from my text editor.  Hopefully it will look better
> this time.
> 
> 
> 
> I really like the idea of array operations, since it seems like an elegant and
> intuitive shorthand for working with vectors.  I have a few (unreasonable)
> requests though. I'd like to see the idea of array operations extended to any
> expression involving arrays, for instance:
> 
> #  float[3] a = 0.0f;
> #  #  printf("a := { ");
> #  printf("%f ",a[]);
> #  printf("}\n");
> 
> Creates the output,
> 
> a := { 0.0000 }
> 
> However, it would be very nice if using the empty block braces or a slice
> automatically expanded the statement into a loop, so this code would expand to
> 
> #  float[3] a = 0.0f;
> #  #  printf("a := { ");
> #  for(int i=0; i<a.length; i++)
> #  printf(" %f",a[i]);
> #  printf("}\n");
> 
> And have the output,
> 
> a := { 0.0000 0.0000 0.0000 }
> 
> Also array operations on multidimensional arrays don't work.  Something like:
> 
> #  float[2][2] a = 1.0f, b = 2.0f, c;
> #  c[][] = a[][] + b[][];
> 
> Generates a compiler error.  However, if multi-arrays were unrolled in a logical
> left-to-right fashion, you would get the following equivalent listing:
> 
> #  for(int i=0; i<c.length; i++)
> #  for(int j=0; j<c[i].length; j++)
> #  c[i][j] = a[i][j] + b[i][j];
> 
> I can also foresee some trickiness with this automated looping.  For example,
> trying to normalize a vector quantity using this method is flawed:
> 
> #  real Magnitude(real[] v)
> #  {
> #	real sum = 0.0;
> #	foreach(real r;v)
> # 	sum += r*r;
> #	return sqrt(r);
> #  }
> #  #  real[3] a = { 1.0, 2.0, 3.0 };
> #  #  a[] /= Magnitude(a);
> 
> Would cause Magnitude() to be called 3 times, each returning a different value.
> A correct way to normalize a would be
> 
> #  real Magnitude(real[] v)
> #  {
> #	real sum = 0.0;
> #	foreach(real r;v)
> #	sum += r*r;
> #	return sqrt(r);
> #  }
> #
> #  real[3] a = {0.0, 1.0, 2.0};
> #
> #  real maga = Magnitude(a);
> #
> #  a[] /= maga;
> 
> 
August 14, 2004
First, I would like to see the specs for array operations as it is fixed to a point where it makes sense. The current wording in the specs mixes the concept of statements and expressions in a way that I have no idea how it is supposed to work at all.

My personal opinion is that the concept of array operations as it is presented in the specs is too simplistic.

Currently, it is not implemented at all. I would suggest to cut the section from the specs and think about it again together with the whole topic of multidimensional arrays after 1.0 is released.

In its current form, the concept is not well defined, and I doubt that there is any simple way to repair it.





Mikola Lysenko wrote:

> Sorry about the repost, but my text became completely and unreadably
> mangled
> after I copied and pasted from my text editor.  Hopefully it will look
> better this time.
> 
> 
> 
> I really like the idea of array operations, since it seems like an elegant
> and
> intuitive shorthand for working with vectors.  I have a few (unreasonable)
> requests though. I'd like to see the idea of array operations extended to
> any expression involving arrays, for instance:
> 
> #  float[3] a = 0.0f;
> #
> #  printf("a := { ");
> #  printf("%f ",a[]);
> #  printf("}\n");
> 
> Creates the output,
> 
> a := { 0.0000 }
> 
> However, it would be very nice if using the empty block braces or a slice automatically expanded the statement into a loop, so this code would expand to
> 
> #  float[3] a = 0.0f;
> #
> #  printf("a := { ");
> #  for(int i=0; i<a.length; i++)
> #  printf(" %f",a[i]);
> #  printf("}\n");
> 
> And have the output,
> 
> a := { 0.0000 0.0000 0.0000 }
> 
> Also array operations on multidimensional arrays don't work.  Something like:
> 
> #  float[2][2] a = 1.0f, b = 2.0f, c;
> #  c[][] = a[][] + b[][];
> 
> Generates a compiler error.  However, if multi-arrays were unrolled in a logical left-to-right fashion, you would get the following equivalent listing:
> 
> #  for(int i=0; i<c.length; i++)
> #  for(int j=0; j<c[i].length; j++)
> #  c[i][j] = a[i][j] + b[i][j];
> 
> I can also foresee some trickiness with this automated looping.  For example, trying to normalize a vector quantity using this method is flawed:
> 
> #  real Magnitude(real[] v)
> #  {
> #real sum = 0.0;
> #foreach(real r;v)
> # sum += r*r;
> #return sqrt(r);
> #  }
> #
> #  real[3] a = { 1.0, 2.0, 3.0 };
> #
> #  a[] /= Magnitude(a);
> 
> Would cause Magnitude() to be called 3 times, each returning a different value. A correct way to normalize a would be
> 
> #  real Magnitude(real[] v)
> #  {
> #real sum = 0.0;
> #foreach(real r;v)
> #sum += r*r;
> #return sqrt(r);
> #  }
> #
> #  real[3] a = {0.0, 1.0, 2.0};
> #
> #  real maga = Magnitude(a);
> #
> #  a[] /= maga;