www.digitalmars.com         C & C++   DMDScript  

digitalmars.D - Why not extend array operations to full Fortran90 power ?

reply "Joachim Wuttke <j.wuttke fz-juelich.de>" <j.wuttke fz-juelich.de> writes:
Compare

   (1)  Y[] = X[]*X[];
   (2)  Y[] = sin( X[] );

With gdc 4.4.6,
   (1) compiles and executes as I expected, whereas
   (2) is not allowed (fails at compile time).
Why?

The semantics of (2) is unambiguous,
and it works perfectly well in Fortran90.
Allowing (2) would make D really attractive
for formula-heavy mathematical work.

- Joachim
Nov 16 2011
next sibling parent Kagamin <spam here.lot> writes:
Joachim Wuttke <j.wuttke fz-juelich.de> Wrote:

 Compare
 
    (1)  Y[] = X[]*X[];
    (2)  Y[] = sin( X[] );
 
 With gdc 4.4.6,
    (1) compiles and executes as I expected, whereas
    (2) is not allowed (fails at compile time).
 Why?
 
 The semantics of (2) is unambiguous,
 and it works perfectly well in Fortran90.
 Allowing (2) would make D really attractive
 for formula-heavy mathematical work.
 
 - Joachim

Hmm... well, yeah http://d.puremagic.com/issues/show_bug.cgi?id=3395
Nov 16 2011
prev sibling next sibling parent Timon Gehr <timon.gehr gmx.ch> writes:
On 11/16/2011 08:08 PM, Joachim Wuttke <j.wuttke fz-juelich.de> wrote:
 Compare

 (1) Y[] = X[]*X[];
 (2) Y[] = sin( X[] );

 With gdc 4.4.6,
 (1) compiles and executes as I expected, whereas
 (2) is not allowed (fails at compile time).
 Why?

 The semantics of (2) is unambiguous,
 and it works perfectly well in Fortran90.
 Allowing (2) would make D really attractive
 for formula-heavy mathematical work.

 - Joachim

I like it, but there is a problem: (2) is already valid code if you have these two overloads: float sin(float x); float[] sin(float[] x); So with your rule it would be ambiguous.
Nov 16 2011
prev sibling next sibling parent reply Xinok <xinok live.com> writes:
On 11/16/2011 2:08 PM, Joachim Wuttke <j.wuttke fz-juelich.de> wrote:
 Compare

 (1) Y[] = X[]*X[];
 (2) Y[] = sin( X[] );

 With gdc 4.4.6,
 (1) compiles and executes as I expected, whereas
 (2) is not allowed (fails at compile time).
 Why?

 The semantics of (2) is unambiguous,
 and it works perfectly well in Fortran90.
 Allowing (2) would make D really attractive
 for formula-heavy mathematical work.

 - Joachim

In (2), this would require several calls to sin().
Nov 16 2011
next sibling parent Timon Gehr <timon.gehr gmx.ch> writes:
On 11/16/2011 10:48 PM, Simen Kjærås wrote:
 On Wed, 16 Nov 2011 22:31:31 +0100, Xinok <xinok live.com> wrote:

 On 11/16/2011 2:08 PM, Joachim Wuttke <j.wuttke fz-juelich.de> wrote:
 Compare

 (1) Y[] = X[]*X[];
 (2) Y[] = sin( X[] );

 With gdc 4.4.6,
 (1) compiles and executes as I expected, whereas
 (2) is not allowed (fails at compile time).
 Why?

 The semantics of (2) is unambiguous,
 and it works perfectly well in Fortran90.
 Allowing (2) would make D really attractive
 for formula-heavy mathematical work.

 - Joachim

loops. In (2), this would require several calls to sin().

Really? How would you do Y[] = X[] * X[] without a loop?

In the special case that the type of X and Y is eg. float[4], use SIMD :o). Joachim's example points out an performance limitation of the current array vector operations: if we have Y[] = sin( X[] ); Then there is currently no way to implement an overload for sin such that it can benefit from RVO. It should be able to write the sinuses directly to Y, but it cannot. That is merely syntax though. copy(map!sin(X), Y); // good enough for me.
Nov 16 2011
prev sibling parent Xinok <xinok live.com> writes:
On 11/16/2011 4:48 PM, Simen Kjærås wrote:
 On Wed, 16 Nov 2011 22:31:31 +0100, Xinok <xinok live.com> wrote:

 On 11/16/2011 2:08 PM, Joachim Wuttke <j.wuttke fz-juelich.de> wrote:
 Compare

 (1) Y[] = X[]*X[];
 (2) Y[] = sin( X[] );

 With gdc 4.4.6,
 (1) compiles and executes as I expected, whereas
 (2) is not allowed (fails at compile time).
 Why?

 The semantics of (2) is unambiguous,
 and it works perfectly well in Fortran90.
 Allowing (2) would make D really attractive
 for formula-heavy mathematical work.

 - Joachim

loops. In (2), this would require several calls to sin().

Really? How would you do Y[] = X[] * X[] without a loop?

That's not what I meant by it. Perhaps an example is in order: void main(){ int rand(){ rndGen.popFront(); return rndGen.front; } int[5] a; int[5] b = [1000, 2000, 3000, 4000, 5000]; a[] = b[] + (rand() % 1000); writeln(a); } This is the result: [1299, 2299, 3299, 4299, 5299] It adds the same random value to each element, meaning it only calls rand() once. D doesn't treat vector operations like loops.
Nov 16 2011
prev sibling next sibling parent =?utf-8?Q?Simen_Kj=C3=A6r=C3=A5s?= <simen.kjaras gmail.com> writes:
On Wed, 16 Nov 2011 22:31:31 +0100, Xinok <xinok live.com> wrote:

 On 11/16/2011 2:08 PM, Joachim Wuttke <j.wuttke fz-juelich.de> wrote:
 Compare

 (1) Y[] = X[]*X[];
 (2) Y[] = sin( X[] );

 With gdc 4.4.6,
 (1) compiles and executes as I expected, whereas
 (2) is not allowed (fails at compile time).
 Why?

 The semantics of (2) is unambiguous,
 and it works perfectly well in Fortran90.
 Allowing (2) would make D really attractive
 for formula-heavy mathematical work.

 - Joachim

In (2), this would require several calls to sin().

Really? How would you do Y[] = X[] * X[] without a loop?
Nov 16 2011
prev sibling next sibling parent "Robert Jacques" <sandford jhu.edu> writes:
On Wed, 16 Nov 2011 14:08:33 -0500, Joachim Wuttke <j.wuttke fz-juelich.de>
<j.wuttke fz-juelich.de> wrote:
 Compare

    (1)  Y[] = X[]*X[];
    (2)  Y[] = sin( X[] );

 With gdc 4.4.6,
    (1) compiles and executes as I expected, whereas
    (2) is not allowed (fails at compile time).
 Why?

 The semantics of (2) is unambiguous,
 and it works perfectly well in Fortran90.
 Allowing (2) would make D really attractive
 for formula-heavy mathematical work.

 - Joachim

Lack of developer man-hours. This has actually been discussed before and is on Don's bubble list, IIRC, but there are a lot of other bug to fix before it.
Nov 16 2011
prev sibling next sibling parent Steve Teale <steve.teale britseyeview.com> writes:
 The semantics of (2) is unambiguous,
 and it works perfectly well in Fortran90. Allowing (2) would make D
 really attractive for formula-heavy mathematical work.
 
 - Joachim

Heard that line before Walter? I still have the T shirt. Steve
Nov 17 2011
prev sibling parent reply Xinok <xinok live.com> writes:
On 11/16/2011 2:08 PM, Joachim Wuttke <j.wuttke fz-juelich.de> wrote:
    (1)  Y[] = X[]*X[];
    (2)  Y[] = sin( X[] );

I realized a problem with (2), it's actually not possible to rewrite it using existing constructs because foreach doesn't support multiple iterators. You can use std.range.zip: foreach(i; zip(Y, X)) i[0] = sin(i[1]); But it's not a core language feature. Before we could extend array operations to support the example above, I think D would need native support for multiple iterators.
Nov 17 2011
parent Timon Gehr <timon.gehr gmx.ch> writes:
On 11/17/2011 07:48 PM, Xinok wrote:
 On 11/16/2011 2:08 PM, Joachim Wuttke <j.wuttke fz-juelich.de> wrote:
 (1) Y[] = X[]*X[];
 (2) Y[] = sin( X[] );

I realized a problem with (2), it's actually not possible to rewrite it using existing constructs

Yes it is. D is Turing Complete!
 because foreach doesn't support multiple
 iterators. You can use std.range.zip:

 foreach(i; zip(Y, X)) i[0] = sin(i[1]);

 But it's not a core language feature.

zip is implemented in terms of core language features.
 Before we could extend array
 operations to support the example above, I think D would need native
 support for multiple iterators.

foreach supports indexed iteration: assert(Y.length == X.length); foreach(i,x; X) Y[i] = sin(x); But there are infinitely many ways to rewrite it.
Nov 17 2011