www.digitalmars.com         C & C++   DMDScript  

digitalmars.D - Is [] mandatory for array operations?

reply Don <nospam nospam.com> writes:
According to my reading of the spec, array operations only require [] 
after the lvalue, not after any of the rvalues. So this should work:

int[3] x, y;
x[] = y * 2; // should work, but currently fails

But in DMD at present, array operations only work if you write [] after 
_every_ array.
x[] = y[] * 2; // works
.. except in the case of simple assignment.
x[] = y; // works, same as x[] = y[]; (I dislike this behaviour,but...).

Which is correct?
Personally I like the requirement for [], I think it makes the intention 
much clearer, and gives more potential for future enhancement (eg, 
things like dot(x[] + y[], z[]) could be made to work). Basically [] 
plays the role that superscript ~ plays for vectors in mathematics.
OTOH this approach makes things more complicated in some respects, and 
what the spec says does also make sense.
So both approaches are reasonable.

There are several compiler bugs relating to array operations, and almost 
all relate to this issue. I'd like to fix them, but I need to know which 
way it is supposed to work.
May 03 2010
next sibling parent reply Walter Bright <newshound1 digitalmars.com> writes:
Don wrote:
 There are several compiler bugs relating to array operations, and almost 
 all relate to this issue. I'd like to fix them, but I need to know which 
 way it is supposed to work.

The [] should be required. I worry that otherwise there will be ambiguous cases that will cause trouble.
May 04 2010
next sibling parent reply Don <nospam nospam.com> writes:
Walter Bright wrote:
 Don wrote:
 There are several compiler bugs relating to array operations, and 
 almost all relate to this issue. I'd like to fix them, but I need to 
 know which way it is supposed to work.

The [] should be required. I worry that otherwise there will be ambiguous cases that will cause trouble.

May 04 2010
parent reply Walter Bright <newshound1 digitalmars.com> writes:
Don wrote:
 Walter Bright wrote:
 Don wrote:
 There are several compiler bugs relating to array operations, and 
 almost all relate to this issue. I'd like to fix them, but I need to 
 know which way it is supposed to work.

The [] should be required. I worry that otherwise there will be ambiguous cases that will cause trouble.


Glad we agree. An example is the C hack where if foo is a function, then &foo as well as foo mean the address of the function. This little ambiguity, originally meant as a convenience, has caused much grief.
May 04 2010
next sibling parent reply Don <nospam nospam.com> writes:
Walter Bright wrote:
 Don wrote:
 Walter Bright wrote:
 Don wrote:
 There are several compiler bugs relating to array operations, and 
 almost all relate to this issue. I'd like to fix them, but I need to 
 know which way it is supposed to work.

The [] should be required. I worry that otherwise there will be ambiguous cases that will cause trouble.


Glad we agree. An example is the C hack where if foo is a function, then &foo as well as foo mean the address of the function. This little ambiguity, originally meant as a convenience, has caused much grief.

Two questions. (1) What happens with functions? For example: x[] = sin(y[]); OR x[] = sin(y[])[]; Seems to me that the [] is not necessary. But it does need to be present for properties. (2) The existing syntax a[] = b; is the same as a[] = b[]; I feel that this is like the C hack. And it's a bit wierd if a[] = b; works but a[] = b * 1; needs to be changed to a[] = b[] * 1;
May 04 2010
next sibling parent reply Kagamin <spam here.lot> writes:
Don Wrote:

 Two questions. (1) What happens with functions? For example:
 x[] = sin(y[]);
 OR
 x[] = sin(y[])[];
 

May 06 2010
parent reply bearophile <bearophileHUGS lycos.com> writes:
Kagamin:
Since sin's result is not an array,<

I am not sure, but I presume here Don was talking about a dispatch of the sin to all items of an array, so its result is another (new or mutated in place) array. Bye, bearophile
May 06 2010
next sibling parent reply Johan Granberg <lijat.meREM OVEgmail.com> writes:
Robert Jacques wrote:

 On Thu, 06 May 2010 14:40:17 -0400, bearophile <bearophileHUGS lycos.com>
 wrote:
 Kagamin:
 Since sin's result is not an array,<

I am not sure, but I presume here Don was talking about a dispatch of the sin to all items of an array, so its result is another (new or mutated in place) array. Bye, bearophile

That presumes a transform of the form: sin(y[]) => map!sin(y). However, this creates unnecessary temporaries which are one of the main things array ops is supposed to avoid. So this is a vote against sin(y[])[].

There is another use for array ops as well, that is to create a nice syntax for doing the same operation over all elements in an array. Matlab is doing this in a very nice way and it is far from all uses that requiers optimal speed. I personaly is very much in favour of allowing this transformations. Sometimes they make code much shorter to write.
 Also, if sin(y[]) returned a lazy/eager array then auto t = sin(y[]);
 should be valid, but auto t = x[] + y[] is not currently valid. So this is
 a vote against sin(y[])[].
 
 As a related note, what do people think of array ops for generic ranges
 (assuming they support length, etc)?

Sounds nice
May 06 2010
parent reply bearophile writes:
Johan Granberg:
 Matlab is doing
 this in a very nice way and it is far from all uses that requiers optimal
 speed. 

Some parts of the Chapel language are exceptionally well designed, and deserve to be stolen. For numerical computations it looks far better than Fortress. Bye, bearophile
May 06 2010
parent bearophile <bearophileHUGS lycos.com> writes:
Robert Jacques:
 Do you have some specific examples in mind?

I have tons of specific examples in mind :-) I have written some things here, and I'd like to write one more time about this: http://www.digitalmars.com/webnews/newsgroups.php?art_group=digitalmars.D&article_id=87311 http://www.digitalmars.com/webnews/newsgroups.php?art_group=digitalmars.D&article_id=109376 http://www.digitalmars.com/webnews/newsgroups.php?art_group=digitalmars.D&article_id=109432 Bye, bearophile
May 06 2010
prev sibling parent Don <nospam nospam.com> writes:
Robert Jacques wrote:
 On Thu, 06 May 2010 14:40:17 -0400, bearophile 
 <bearophileHUGS lycos.com> wrote:
 Kagamin:
 Since sin's result is not an array,<

I am not sure, but I presume here Don was talking about a dispatch of the sin to all items of an array, so its result is another (new or mutated in place) array. Bye, bearophile

That presumes a transform of the form: sin(y[]) => map!sin(y).

 this creates unnecessary temporaries 

Why do you say that? It's inside an array operation, so it's already inside a loop. a[] = c[] + sin(b[])[]; ===> for(int i=0; i< a.length; ++i) { a[i] = c[i] + sin(b[i]); } No temporaries. (One important possibility is that the compiler can synthesize array operations from pure functions, ie there is no defined function double[] sin(double[] x); ). This is simply a question of syntax. Does it need the [] to resolve syntactic ambiguity? I don't think it does, but I have some uncertainty because of the property case. which are one of the main things
 array ops is supposed to avoid. So this is a vote against sin(y[])[].
 
 Also, if sin(y[]) returned a lazy/eager array then auto t = sin(y[]); 
 should be valid, but auto t = x[] + y[] is not currently valid. So this 
 is a vote against sin(y[])[].

 
 As a related note, what do people think of array ops for generic ranges 
 (assuming they support length, etc)?

May 06 2010
prev sibling parent reply Jason House <jason.james.house gmail.com> writes:
Don Wrote:

 Walter Bright wrote:
 Don wrote:
 Walter Bright wrote:
 Don wrote:
 There are several compiler bugs relating to array operations, and 
 almost all relate to this issue. I'd like to fix them, but I need to 
 know which way it is supposed to work.

The [] should be required. I worry that otherwise there will be ambiguous cases that will cause trouble.


Glad we agree. An example is the C hack where if foo is a function, then &foo as well as foo mean the address of the function. This little ambiguity, originally meant as a convenience, has caused much grief.

Two questions. (1) What happens with functions? For example: x[] = sin(y[]); OR x[] = sin(y[])[]; Seems to me that the [] is not necessary. But it does need to be present for properties.

I strongly favor the first syntax since it matches how I'd write it in a for loop. i.e. I'd replace [] with [i]. If there was a sin variant that took array input, then I'd expect the line to be: x[] = sin(y)[] which would translate to creating a temporary to hold sin(y) array.
May 06 2010
parent reply Michel Fortin <michel.fortin michelf.com> writes:
On 2010-05-06 19:02:03 -0400, Jason House <jason.james.house gmail.com> said:

 Don Wrote:
 
  x[] = sin(y[]);

I strongly favor the first syntax since it matches how I'd write it in a for loop. i.e. I'd replace [] with [i].

This is the best way to see array operations I've read up to now: replace [] with [i], i being the current loop index. It's so simple to explain.
 If there was a sin variant that took array input, then I'd expect the 
 line to be:
   x[] = sin(y)[]
 
 which would translate to creating a temporary to hold sin(y) array.

Makes sense too. -- Michel Fortin michel.fortin michelf.com http://michelf.com/
May 06 2010
parent reply Michel Fortin <michel.fortin michelf.com> writes:
On 2010-05-06 21:48:09 -0400, "Robert Jacques" <sandford jhu.edu> said:

 On Thu, 06 May 2010 20:57:07 -0400, Michel Fortin  
 <michel.fortin michelf.com> wrote:
 
 On 2010-05-06 19:02:03 -0400, Jason House <jason.james.house gmail.com>  said:
 
 Don Wrote:
 
  x[] = sin(y[]);

a for loop. i.e. I'd replace [] with [i].

This is the best way to see array operations I've read up to now: replace [] with [i], i being the current loop index. It's so simple to explain.
 If there was a sin variant that took array input, then I'd expect the  
 line to be:
   x[] = sin(y)[]
  which would translate to creating a temporary to hold sin(y) array.

Makes sense too.

this: for(int i = 0; i < x.length; i++) { x[i] = sin(y)[i]; } makes sense?

Yes, if as stated by Jason there was a sin variant that took array input. That said, I'd expect the compiler to call sin(y) only once, so it'd be more like that: auto sinY = sin(y); for(int i = 0; i < x.length; i++) { x[i] = sinY[i]; } -- Michel Fortin michel.fortin michelf.com http://michelf.com/
May 06 2010
next sibling parent Michel Fortin <michel.fortin michelf.com> writes:
On 2010-05-06 22:46:42 -0400, Michel Fortin <michel.fortin michelf.com> said:

 That said, I'd expect the compiler to call sin(y) only once, so it'd be 
 more like that:
 
 	auto sinY = sin(y);
 	for(int i = 0; i < x.length; i++) {
 		x[i] = sinY[i];
 	}

And I'd expect that because in the expression "x[] = sin(y)[]" none of sin's argument are part of an array operation. Calling a function repeatedly should only happen when one of its arguments can change between iterations (and possibly only pure functions should be allowed to be called repeatedly through array ops). -- Michel Fortin michel.fortin michelf.com http://michelf.com/
May 06 2010
prev sibling parent reply Jason House <jason.james.house gmail.com> writes:
Robert Jacques Wrote:

 On Thu, 06 May 2010 22:46:42 -0400, Michel Fortin  
 <michel.fortin michelf.com> wrote:
 
 On 2010-05-06 21:48:09 -0400, "Robert Jacques" <sandford jhu.edu> said:

 On Thu, 06 May 2010 20:57:07 -0400, Michel Fortin   
 <michel.fortin michelf.com> wrote:

 On 2010-05-06 19:02:03 -0400, Jason House  
 <jason.james.house gmail.com>  said:

 Don Wrote:

  x[] = sin(y[]);

in a for loop. i.e. I'd replace [] with [i].

replace [] with [i], i being the current loop index. It's so simple to explain.
 If there was a sin variant that took array input, then I'd expect  
 the  line to be:
   x[] = sin(y)[]
  which would translate to creating a temporary to hold sin(y) array.


for(int i = 0; i < x.length; i++) { x[i] = sin(y)[i]; } makes sense?

Yes, if as stated by Jason there was a sin variant that took array input. That said, I'd expect the compiler to call sin(y) only once, so it'd be more like that: auto sinY = sin(y); for(int i = 0; i < x.length; i++) { x[i] = sinY[i]; }

Ah, thank you for the clarification. I mis-read the first post. Although, for sin(y)[] to work, the variant would have to return an array in addition to taking one. hmm... given real foo(real value) {...} and real[] foo(real[] value) {...} what should happen with the follow line of code: x[] = foo(y[]) + z[];

That can be interpreted in either of the following ways: foreach(i) x[i] = foo(y[i]) + z[i]; OR auto F = foo(y[]); foreach(i) x[i] = F + z[i]; The 2nd would be a compile error, so it must be the first.
May 06 2010
parent reply Michel Fortin <michel.fortin michelf.com> writes:
On 2010-05-07 01:34:39 -0400, "Robert Jacques" <sandford jhu.edu> said:

 On Fri, 07 May 2010 00:13:04 -0400, Jason House  
 <jason.james.house gmail.com> wrote:
 Robert Jacques Wrote:
 given
 real foo(real value) {...}
 and
 real[] foo(real[] value) {...}
 
 what should happen with the follow line of code:
 
 x[] = foo(y[]) + z[];

That can be interpreted in either of the following ways: foreach(i) x[i] = foo(y[i]) + z[i]; OR auto F = foo(y[]); foreach(i) x[i] = F + z[i]; The 2nd would be a compile error, so it must be the first.

Well, this adds a bunch of complexity, since a combinatorial number of statements have to be evaluated and a match picked. And then there's the ambiguous case: x[] = foo(y[]); Which is an example of x[] = y; vs x[] = y[]; problem.

True. The problem comes from the overloaded meaning of []: "slice" or "array op"? I'm not sure whether this is a problem or not. We already have overloaded functions which can be ambiguous. The compiler solves this with a compile-time error; perhaps it should be the same here. -- Michel Fortin michel.fortin michelf.com http://michelf.com/
May 07 2010
next sibling parent reply Michel Fortin <michel.fortin michelf.com> writes:
On 2010-05-07 09:52:46 -0400, "Robert Jacques" <sandford jhu.edu> said:

 On Fri, 07 May 2010 07:51:11 -0400, Michel Fortin  
 <michel.fortin michelf.com> wrote:
 
 On 2010-05-07 01:34:39 -0400, "Robert Jacques" <sandford jhu.edu> said:
 
  And then there's the ambiguous case:
 x[] = foo(y[]);
 Which is an example of x[] = y; vs x[] = y[]; problem.

True. The problem comes from the overloaded meaning of []: "slice" or "array op"? I'm not sure whether this is a problem or not. We already have overloaded functions which can be ambiguous. The compiler solves this with a compile-time error; perhaps it should be the same here.

True, but other overloaded function you can resolve by a) assigning to a temporary of the desired type or b) using the qualified name. With array ops I must using the [] operator and therefore must be ambiguous.

Or instead of generating an error, we could just give priority to array ops. Since they use smaller temporaries (if at all), it makes sense to prefer them whenever they work. Is there a case where you'd expect "x[] = foo(y[])" to give you a different result whether it was done using array ops or a temporary array? And if you really want a temporary array, just do this: auto tmp = foo(y[]); x[] = tmp; There is some elegance to that solution since it chooses the right solution for the problem at hand. If you assign the result to a temporary array as above, it's probably because you'll need it somewhere else and thus you really need to keep the temporary around. If you don't don't use a temporary variable, you'll automatically benefit from array ops. -- Michel Fortin michel.fortin michelf.com http://michelf.com/
May 07 2010
parent Kagamin <spam here.lot> writes:
Michel Fortin Wrote:

 There is some elegance to that solution since it chooses the right 
 solution for the problem at hand. If you assign the result to a 
 temporary array as above, it's probably because you'll need it 
 somewhere else and thus you really need to keep the temporary around. 
 If you don't don't use a temporary variable, you'll automatically 
 benefit from array ops.
 

May 07 2010
prev sibling parent Kagamin <spam here.lot> writes:
Robert Jacques Wrote:

 On Fri, 07 May 2010 09:52:46 -0400, Robert Jacques <sandford jhu.edu>  
 wrote:
 Given that y[] is really syntactic sugar y[0..$], one option would be to  
 bite the bullet an make [] a dedicated array op/vectorize operator. This  
 would pave the way for using array ops with user defined types (e.g.  
 matrices and ranges). However, the downside to this is that user types  
 would loose the x[] = y; and y[] operator overloads. Classes can use x[]  
 = y to mean copy assignment (since x=y is a ref assignment). Collections  
 may use y[] as sugar for a .all() method/property. Are there other use  
 cases?

On second thought, array ops work with any type of slice: a[0..2] = b[0..2] + c[]; so this is a no go.

So... a different syntax? a![0..2] = b![0..2] + c![]; or c[..]
May 07 2010
prev sibling parent reply Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> writes:
Walter Bright wrote:
 Don wrote:
 Walter Bright wrote:
 Don wrote:
 There are several compiler bugs relating to array operations, and 
 almost all relate to this issue. I'd like to fix them, but I need to 
 know which way it is supposed to work.

The [] should be required. I worry that otherwise there will be ambiguous cases that will cause trouble.


Glad we agree. An example is the C hack where if foo is a function, then &foo as well as foo mean the address of the function. This little ambiguity, originally meant as a convenience, has caused much grief.

In the same vein, probably it's time to bite the bullet and require property for parens-less function calls. Andrei
May 04 2010
next sibling parent Bernard Helyer <b.helyer gmail.com> writes:
On 05/05/10 08:19, Andrei Alexandrescu wrote:
 In the same vein, probably it's time to bite the bullet and require
  property for parens-less function calls.

 Andrei

Agreed. Is there any word on rewriting things like `fooInstance.prop += 3` for properties?
May 04 2010
prev sibling next sibling parent reply Pelle <pelle.mansson gmail.com> writes:
On 05/04/2010 10:19 PM, Andrei Alexandrescu wrote:
 In the same vein, probably it's time to bite the bullet and require
  property for parens-less function calls.

 Andrei

Please, no. :) Just require property for assignment-is-a-call code. //requires property foo.x = 3; //does not require property auto s = foo.size; Pretty please?
May 09 2010
parent reply bearophile <bearophileHUGS lycos.com> writes:
Pelle:
 Please, no. :)
 Just require  property for assignment-is-a-call code.

Special cases are baaaad. They are usually not special enough. Experience shows me that implicit operations or untidy semantics often leads to big troubles, even when you don't see such troubles at first. The obligatory usage of () makes the language a little less handy, but more tidy, and removes a source of possible troubles. There is already a property syntax that can be used on methods and free functions. Having another half-baked feature doesn't help the language. Bye, bearophile
May 09 2010
parent Pelle <pelle.mansson gmail.com> writes:
On 05/09/2010 04:21 PM, bearophile wrote:
 Pelle:
 Please, no. :)
 Just require  property for assignment-is-a-call code.

Special cases are baaaad. They are usually not special enough. Experience shows me that implicit operations or untidy semantics often leads to big troubles, even when you don't see such troubles at first. The obligatory usage of () makes the language a little less handy, but more tidy, and removes a source of possible troubles. There is already a property syntax that can be used on methods and free functions. Having another half-baked feature doesn't help the language. Bye, bearophile

Well, then I see no reason not to apply property to almost every function there is, if you can call it without arguments. Or, for array functions, as a property of an array. I mean, property should be for properties, and if we define that not to be something that can be read and written as a variable, I believe the definition of what a property actually is will bikeshed us into oblivion.
May 09 2010
prev sibling parent Bruno Medeiros <brunodomedeiros+spam com.gmail> writes:
On 04/05/2010 21:19, Andrei Alexandrescu wrote:
 Walter Bright wrote:
 Don wrote:
 Walter Bright wrote:
 Don wrote:
 There are several compiler bugs relating to array operations, and
 almost all relate to this issue. I'd like to fix them, but I need
 to know which way it is supposed to work.

The [] should be required. I worry that otherwise there will be ambiguous cases that will cause trouble.


Glad we agree. An example is the C hack where if foo is a function, then &foo as well as foo mean the address of the function. This little ambiguity, originally meant as a convenience, has caused much grief.

In the same vein, probably it's time to bite the bullet and require property for parens-less function calls. Andrei

Yes please. That ambiguity has bitten me in the past, in a case where the return value of the function was a function/delegate. Basicly if you change a variable(of delegate type) into a property, code that uses the variable as a function call will break. This is because the function call will only call the property getter, not the actual delegate. -- Bruno Medeiros - Software Engineer
May 13 2010
prev sibling next sibling parent "Robert Jacques" <sandford jhu.edu> writes:
On Thu, 06 May 2010 14:40:17 -0400, bearophile <bearophileHUGS lycos.com>  
wrote:
 Kagamin:
 Since sin's result is not an array,<

I am not sure, but I presume here Don was talking about a dispatch of the sin to all items of an array, so its result is another (new or mutated in place) array. Bye, bearophile

That presumes a transform of the form: sin(y[]) => map!sin(y). However, this creates unnecessary temporaries which are one of the main things array ops is supposed to avoid. So this is a vote against sin(y[])[]. Also, if sin(y[]) returned a lazy/eager array then auto t = sin(y[]); should be valid, but auto t = x[] + y[] is not currently valid. So this is a vote against sin(y[])[]. As a related note, what do people think of array ops for generic ranges (assuming they support length, etc)?
May 06 2010
prev sibling next sibling parent "Robert Jacques" <sandford jhu.edu> writes:
On Thu, 06 May 2010 16:48:30 -0400, Don <nospam nospam.com> wrote:

 Robert Jacques wrote:
 On Thu, 06 May 2010 14:40:17 -0400, bearophile  
 <bearophileHUGS lycos.com> wrote:
 Kagamin:
 Since sin's result is not an array,<

I am not sure, but I presume here Don was talking about a dispatch of the sin to all items of an array, so its result is another (new or mutated in place) array. Bye, bearophile


 this creates unnecessary temporaries

Why do you say that? It's inside an array operation, so it's already inside a loop. a[] = c[] + sin(b[])[]; ===> for(int i=0; i< a.length; ++i) { a[i] = c[i] + sin(b[i]); } No temporaries. (One important possibility is that the compiler can synthesize array operations from pure functions, ie there is no defined function double[] sin(double[] x); ). This is simply a question of syntax. Does it need the [] to resolve syntactic ambiguity? I don't think it does, but I have some uncertainty because of the property case.

bearophile was making an argument for the sin(b[])[] syntax based on sin(b[]) producing an array of some kind. If true, this would make sin(b[]) a valid syntactic construct outside of other array ops, therefore implying temporaries due to some intermediate wrapper struct. Like map!sin(y). On a similar note: z[0..2] = x[0..2] + y[0..2]; is valid so therefore a[0..2] = c[0..2] + sin(b[5..10])[1..3]; should be valid, and that looks like a very bad idea to me.
May 06 2010
prev sibling next sibling parent "Robert Jacques" <sandford jhu.edu> writes:
On Thu, 06 May 2010 16:54:48 -0400, bearophile <bearophileHUGS lycos.com>  
wrote:
 Johan Granberg:
 Matlab is doing
 this in a very nice way and it is far from all uses that requiers  
 optimal
 speed.

Some parts of the Chapel language are exceptionally well designed, and deserve to be stolen. For numerical computations it looks far better than Fortress. Bye, bearophile

Do you have some specific examples in mind?
May 06 2010
prev sibling next sibling parent "Robert Jacques" <sandford jhu.edu> writes:
On Thu, 06 May 2010 19:02:03 -0400, Jason House  
<jason.james.house gmail.com> wrote:

 Don Wrote:

 Walter Bright wrote:
 Don wrote:
 Walter Bright wrote:
 Don wrote:
 There are several compiler bugs relating to array operations, and
 almost all relate to this issue. I'd like to fix them, but I need  




 know which way it is supposed to work.

The [] should be required. I worry that otherwise there will be ambiguous cases that will cause trouble.


Glad we agree. An example is the C hack where if foo is a function,

 &foo as well as foo mean the address of the function. This little
 ambiguity, originally meant as a convenience, has caused much grief.

Two questions. (1) What happens with functions? For example: x[] = sin(y[]); OR x[] = sin(y[])[]; Seems to me that the [] is not necessary. But it does need to be present for properties.

I strongly favor the first syntax since it matches how I'd write it in a for loop. i.e. I'd replace [] with [i]. If there was a sin variant that took array input, then I'd expect the line to be: x[] = sin(y)[] which would translate to creating a temporary to hold sin(y) array.

Wouldn't that rule mean: for(int i = 0; i < x.length; i++) { x[i] = sin(y[i]); } i.e. x[] = sin(y[]) x[] = sin(y)[] would convert into for(int i = 0; i < x.length; i++) { x[i] = sin(y)[i]; } which doesn't make any sense.
May 06 2010
prev sibling next sibling parent "Robert Jacques" <sandford jhu.edu> writes:
On Thu, 06 May 2010 20:57:07 -0400, Michel Fortin  
<michel.fortin michelf.com> wrote:

 On 2010-05-06 19:02:03 -0400, Jason House <jason.james.house gmail.com>  
 said:

 Don Wrote:

  x[] = sin(y[]);

a for loop. i.e. I'd replace [] with [i].

This is the best way to see array operations I've read up to now: replace [] with [i], i being the current loop index. It's so simple to explain.
 If there was a sin variant that took array input, then I'd expect the  
 line to be:
   x[] = sin(y)[]
  which would translate to creating a temporary to hold sin(y) array.

Makes sense too.

this: for(int i = 0; i < x.length; i++) { x[i] = sin(y)[i]; } makes sense?
May 06 2010
prev sibling next sibling parent "Robert Jacques" <sandford jhu.edu> writes:
On Thu, 06 May 2010 22:46:42 -0400, Michel Fortin  
<michel.fortin michelf.com> wrote:

 On 2010-05-06 21:48:09 -0400, "Robert Jacques" <sandford jhu.edu> said:

 On Thu, 06 May 2010 20:57:07 -0400, Michel Fortin   
 <michel.fortin michelf.com> wrote:

 On 2010-05-06 19:02:03 -0400, Jason House  
 <jason.james.house gmail.com>  said:

 Don Wrote:

  x[] = sin(y[]);

in a for loop. i.e. I'd replace [] with [i].

replace [] with [i], i being the current loop index. It's so simple to explain.
 If there was a sin variant that took array input, then I'd expect  
 the  line to be:
   x[] = sin(y)[]
  which would translate to creating a temporary to hold sin(y) array.


for(int i = 0; i < x.length; i++) { x[i] = sin(y)[i]; } makes sense?

Yes, if as stated by Jason there was a sin variant that took array input. That said, I'd expect the compiler to call sin(y) only once, so it'd be more like that: auto sinY = sin(y); for(int i = 0; i < x.length; i++) { x[i] = sinY[i]; }

Ah, thank you for the clarification. I mis-read the first post. Although, for sin(y)[] to work, the variant would have to return an array in addition to taking one. hmm... given real foo(real value) {...} and real[] foo(real[] value) {...} what should happen with the follow line of code: x[] = foo(y[]) + z[];
May 06 2010
prev sibling next sibling parent "Robert Jacques" <sandford jhu.edu> writes:
On Fri, 07 May 2010 00:13:04 -0400, Jason House  
<jason.james.house gmail.com> wrote:
 Robert Jacques Wrote:
 given
 real foo(real value) {...}
 and
 real[] foo(real[] value) {...}

 what should happen with the follow line of code:

 x[] = foo(y[]) + z[];

That can be interpreted in either of the following ways: foreach(i) x[i] = foo(y[i]) + z[i]; OR auto F = foo(y[]); foreach(i) x[i] = F + z[i]; The 2nd would be a compile error, so it must be the first.

Well, this adds a bunch of complexity, since a combinatorial number of statements have to be evaluated and a match picked. And then there's the ambiguous case: x[] = foo(y[]); Which is an example of x[] = y; vs x[] = y[]; problem.
May 06 2010
prev sibling next sibling parent "Robert Jacques" <sandford jhu.edu> writes:
On Fri, 07 May 2010 07:51:11 -0400, Michel Fortin  
<michel.fortin michelf.com> wrote:

 On 2010-05-07 01:34:39 -0400, "Robert Jacques" <sandford jhu.edu> said:

 On Fri, 07 May 2010 00:13:04 -0400, Jason House   
 <jason.james.house gmail.com> wrote:
 Robert Jacques Wrote:
 given
 real foo(real value) {...}
 and
 real[] foo(real[] value) {...}
  what should happen with the follow line of code:
  x[] = foo(y[]) + z[];

foreach(i) x[i] = foo(y[i]) + z[i]; OR auto F = foo(y[]); foreach(i) x[i] = F + z[i]; The 2nd would be a compile error, so it must be the first.

of statements have to be evaluated and a match picked. And then there's the ambiguous case: x[] = foo(y[]); Which is an example of x[] = y; vs x[] = y[]; problem.

True. The problem comes from the overloaded meaning of []: "slice" or "array op"? I'm not sure whether this is a problem or not. We already have overloaded functions which can be ambiguous. The compiler solves this with a compile-time error; perhaps it should be the same here.

True, but other overloaded function you can resolve by a) assigning to a temporary of the desired type or b) using the qualified name. With array ops I must using the [] operator and therefore must be ambiguous. Given that y[] is really syntactic sugar y[0..$], one option would be to bite the bullet an make [] a dedicated array op/vectorize operator. This would pave the way for using array ops with user defined types (e.g. matrices and ranges). However, the downside to this is that user types would loose the x[] = y; and y[] operator overloads. Classes can use x[] = y to mean copy assignment (since x=y is a ref assignment). Collections may use y[] as sugar for a .all() method/property. Are there other use cases?
May 07 2010
prev sibling next sibling parent "Robert Jacques" <sandford jhu.edu> writes:
On Tue, 04 May 2010 16:19:09 -0400, Andrei Alexandrescu  
<SeeWebsiteForEmail erdani.org> wrote:

 Walter Bright wrote:
 Don wrote:
 Walter Bright wrote:
 Don wrote:
 There are several compiler bugs relating to array operations, and  
 almost all relate to this issue. I'd like to fix them, but I need to  
 know which way it is supposed to work.

The [] should be required. I worry that otherwise there will be ambiguous cases that will cause trouble.


then &foo as well as foo mean the address of the function. This little ambiguity, originally meant as a convenience, has caused much grief.

In the same vein, probably it's time to bite the bullet and require property for parens-less function calls. Andrei

Disagreed. I've really come to enjoy parens-less coding, though I know others don't like it. But today both camps can write in their preferred style and write libraries for each other. Either deciding on an opt-in ( property) or opt-out( !property) basis seems likely to A) kill the other programming style or B) lead to a bunch of synaptic load on the programmer as they try to remember which style each class uses.
May 07 2010
prev sibling next sibling parent "Steven Schveighoffer" <schveiguy yahoo.com> writes:
On Fri, 07 May 2010 10:08:22 -0400, Robert Jacques <sandford jhu.edu>  
wrote:

 On Tue, 04 May 2010 16:19:09 -0400, Andrei Alexandrescu  
 <SeeWebsiteForEmail erdani.org> wrote:

 Walter Bright wrote:
 Don wrote:
 Walter Bright wrote:
 Don wrote:
 There are several compiler bugs relating to array operations, and  
 almost all relate to this issue. I'd like to fix them, but I need  
 to know which way it is supposed to work.

The [] should be required. I worry that otherwise there will be ambiguous cases that will cause trouble.


then &foo as well as foo mean the address of the function. This little ambiguity, originally meant as a convenience, has caused much grief.

In the same vein, probably it's time to bite the bullet and require property for parens-less function calls. Andrei

Disagreed. I've really come to enjoy parens-less coding, though I know others don't like it. But today both camps can write in their preferred style and write libraries for each other. Either deciding on an opt-in ( property) or opt-out( !property) basis seems likely to A) kill the other programming style or B) lead to a bunch of synaptic load on the programmer as they try to remember which style each class uses.

As I've said before, I think a possible compromise to this is to allow paren-less function calls when the return type is void. These functions cannot be misinterpreted as properties. I won't go over the other points again :) -Steve
May 07 2010
prev sibling next sibling parent "Robert Jacques" <sandford jhu.edu> writes:
On Fri, 07 May 2010 09:52:46 -0400, Robert Jacques <sandford jhu.edu>  
wrote:
 Given that y[] is really syntactic sugar y[0..$], one option would be to  
 bite the bullet an make [] a dedicated array op/vectorize operator. This  
 would pave the way for using array ops with user defined types (e.g.  
 matrices and ranges). However, the downside to this is that user types  
 would loose the x[] = y; and y[] operator overloads. Classes can use x[]  
 = y to mean copy assignment (since x=y is a ref assignment). Collections  
 may use y[] as sugar for a .all() method/property. Are there other use  
 cases?

On second thought, array ops work with any type of slice: a[0..2] = b[0..2] + c[]; so this is a no go.
May 07 2010
prev sibling next sibling parent "Robert Jacques" <sandford jhu.edu> writes:
On Fri, 07 May 2010 11:11:47 -0400, Steven Schveighoffer  
<schveiguy yahoo.com> wrote:

 On Fri, 07 May 2010 10:08:22 -0400, Robert Jacques <sandford jhu.edu>  
 wrote:

 On Tue, 04 May 2010 16:19:09 -0400, Andrei Alexandrescu  
 <SeeWebsiteForEmail erdani.org> wrote:

 Walter Bright wrote:
 Don wrote:
 Walter Bright wrote:
 Don wrote:
 There are several compiler bugs relating to array operations, and  
 almost all relate to this issue. I'd like to fix them, but I need  
 to know which way it is supposed to work.

The [] should be required. I worry that otherwise there will be ambiguous cases that will cause trouble.


then &foo as well as foo mean the address of the function. This little ambiguity, originally meant as a convenience, has caused much grief.

In the same vein, probably it's time to bite the bullet and require property for parens-less function calls. Andrei

Disagreed. I've really come to enjoy parens-less coding, though I know others don't like it. But today both camps can write in their preferred style and write libraries for each other. Either deciding on an opt-in ( property) or opt-out( !property) basis seems likely to A) kill the other programming style or B) lead to a bunch of synaptic load on the programmer as they try to remember which style each class uses.

As I've said before, I think a possible compromise to this is to allow paren-less function calls when the return type is void. These functions cannot be misinterpreted as properties. I won't go over the other points again :) -Steve

One of the major uses of paren-less functions is chaining, which always return typeof(this), not void.
May 07 2010
prev sibling next sibling parent "Steven Schveighoffer" <schveiguy yahoo.com> writes:
On Fri, 07 May 2010 11:18:37 -0400, Robert Jacques <sandford jhu.edu>  
wrote:

 On Fri, 07 May 2010 11:11:47 -0400, Steven Schveighoffer  
 <schveiguy yahoo.com> wrote:
 As I've said before, I think a possible compromise to this is to allow  
 paren-less function calls when the return type is void.  These  
 functions cannot be misinterpreted as properties.

 I won't go over the other points again :)

 -Steve

One of the major uses of paren-less functions is chaining, which always return typeof(this), not void.

It's a compromise. It doesn't do everything you want, but it is good for some of it. -Steve
May 07 2010
prev sibling next sibling parent "Robert Jacques" <sandford jhu.edu> writes:
On Fri, 07 May 2010 11:44:18 -0400, Steven Schveighoffer  
<schveiguy yahoo.com> wrote:

 On Fri, 07 May 2010 11:18:37 -0400, Robert Jacques <sandford jhu.edu>  
 wrote:

 On Fri, 07 May 2010 11:11:47 -0400, Steven Schveighoffer  
 <schveiguy yahoo.com> wrote:
 As I've said before, I think a possible compromise to this is to allow  
 paren-less function calls when the return type is void.  These  
 functions cannot be misinterpreted as properties.

 I won't go over the other points again :)

 -Steve

One of the major uses of paren-less functions is chaining, which always return typeof(this), not void.

It's a compromise. It doesn't do everything you want, but it is good for some of it. -Steve

This reminds me of a graph I once saw long ago with 4 options: 1) Do what A wants and B is unhappy. 2) Do what B wants and A is unhappy. 3) Compromise and both A and B are unhappy. 4) Create a composite solution and both are happy. Of course, 4) is really hard. :)
May 07 2010
prev sibling parent "Robert Jacques" <sandford jhu.edu> writes:
On Fri, 07 May 2010 13:18:04 -0400, Kagamin <spam here.lot> wrote:

 Michel Fortin Wrote:

 There is some elegance to that solution since it chooses the right
 solution for the problem at hand. If you assign the result to a
 temporary array as above, it's probably because you'll need it
 somewhere else and thus you really need to keep the temporary around.
 If you don't don't use a temporary variable, you'll automatically
 benefit from array ops.


:) Actually, angle brackets are far worse, because it means the lexer and semantic analysis can't be separated.
May 07 2010
prev sibling parent Trass3r <un known.com> writes:
 int[3] x, y;
 x[] = y * 2; // should work, but currently fails

Don't know if this would cause any compiler problems but y could also be a scalar value. So requiring the [] would at least be unambiguous to the programmer. Hmm, maybe if you have two variables named very similarly and you mistype one. int[3] xx, x; int xy; x[] = xy * 2; // where xx * 2 was intended
May 04 2010