www.digitalmars.com         C & C++   DMDScript  

digitalmars.D - About Array Operations

reply Mikola Lysenko <Mikola_member pathlink.com> writes:
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;
Aug 11 2004
parent reply Mikola Lysenko <Mikola_member pathlink.com> writes:
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;
Aug 12 2004
next sibling parent reply Stephen Waits <steve waits.net> writes:
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
Aug 12 2004
parent Mikola Lysenko <Mikola_member pathlink.com> writes:
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.
Aug 12 2004
prev sibling next sibling parent Ilya Minkov <minkov cs.tum.edu> writes:
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;
 
 

Aug 12 2004
prev sibling parent Norbert Nemec <Norbert Nemec-online.de> writes:
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;

Aug 14 2004