www.digitalmars.com         C & C++   DMDScript  

D - Multidimensional arrays; reference operator; longs

reply "Ivan Frohne" <frohne gci.net> writes:
How about   instead of & for references?  Credit
Allen Holub with that idea.

One of the better features of C# is its multidimensional
arrays.  You can have ragged or rectangular arrays,
and use Fortran notation for the rectangular ones (there's
another overload for ()s).

Are longs 64 bits?

--Ivan Frohne
Aug 13 2001
next sibling parent reply "Walter" <walter digitalmars.com> writes:
"Ivan Frohne" <frohne gci.net> wrote in message
news:9l9aop$pt8$1 digitaldaemon.com...
 How about   instead of & for references?  Credit
 Allen Holub with that idea.

What's his rationale?
 One of the better features of C# is its multidimensional
 arrays.  You can have ragged or rectangular arrays,
 and use Fortran notation for the rectangular ones (there's
 another overload for ()s).

This works in D! see: www.digitalmars.com/d/float.html
 Are longs 64 bits?

Yes.
Aug 13 2001
parent reply "Ivan Frohne" <frohne gci.net> writes:
"Walter" <walter digitalmars.com> wrote in message
news:9l9guq$t7p$1 digitaldaemon.com...
 "Ivan Frohne" <frohne gci.net> wrote in message
 news:9l9aop$pt8$1 digitaldaemon.com...
 How about   instead of & for references?  Credit
 Allen Holub with that idea.

What's his rationale?

Here's a quote from "C + C++: Programming with objects in C and C++," McGraw-Hill, 1992, by Holub, p. 100: "Using the & to mean 'reference' is, to my mind, a syntactic mistake on the part of the language designers. The & usually means 'address of' and using [it] for 'reference to' just adds confusion. A new operator ( is a good candidate) should have been introduced to mean 'reference to'." --Ivan Frohne
Aug 13 2001
parent reply "Walter" <walter digitalmars.com> writes:
I think the rationale was that ' ' wasn't available in international
character sets. Be that as it may, I'm seriously considering dropping
explicit reference types entirely. Reference types will be implicit for
arrays, classes, out and inout function parameters. I don't think anyone
will miss them!

-Walter


Ivan Frohne wrote in message <9l9vq1$150t$1 digitaldaemon.com>...
"Walter" <walter digitalmars.com> wrote in message
news:9l9guq$t7p$1 digitaldaemon.com...
 "Ivan Frohne" <frohne gci.net> wrote in message
 news:9l9aop$pt8$1 digitaldaemon.com...
 How about   instead of & for references?  Credit
 Allen Holub with that idea.

What's his rationale?

Here's a quote from "C + C++: Programming with objects in C and C++," McGraw-Hill, 1992, by Holub, p. 100: "Using the & to mean 'reference' is, to my mind, a syntactic mistake on the part of the language designers. The & usually means 'address of' and using [it] for 'reference to' just adds confusion. A new operator ( is a good candidate) should have been introduced to mean 'reference to'." --Ivan Frohne

Aug 13 2001
next sibling parent "Sheldon Simms" <sheldon semanticedge.com> writes:
Im Artikel <9la3tb$178j$2 digitaldaemon.com> schrieb "Walter"
<walter digitalmars.com>:

 I think the rationale was that ' ' wasn't available in international
 character sets. Be that as it may, I'm seriously considering dropping
 explicit reference types entirely. Reference types will be implicit for
 arrays, classes, out and inout function parameters. I don't think anyone
 will miss them!

I agree. I don't miss them in Java and since class types and dynamic arrays are references already, who needs them? -- Sheldon Simms / sheldon semanticedge.com
Aug 16 2001
prev sibling parent reply "Sean L. Palmer" <spalmer iname.com> writes:
I use references all the time to save typing.  For instance:  (C++ code)

#include <vector>
#include <iostream>

struct mystruct
{
  int foo;
};

{
  std::vector<mystruct> myvector;
  for (std::vector<mystruct>::iterator i = myvector.begin(); i !=
myvector.end(); ++i)
  {
     mystruct& ms = (*i);
     std::cout << ms.foo;
  }
}

Now just imagine a more complex function that uses ms many times... the
savings in typing and increased readability quickly add up.

If you provide some kind of "with" statement ala pascal it would solve much
of the need for references, otherwise I'd suggest keeping them, they're very
convenient.  If I had to choose between Pascal's "with" clause and
references I'd definitely choose to keep references.  They'd be unnecessary
in parameter lists since a const reference may be auto-generated by "in"
parameters, and non-const reference auto-generated by "inout" parameters.
I'm not 100% sure how exactly "out" parameters would work since they imply
ignorance of the current state of the object, yet that object has to be
passed in, so may have already been initialized etc.

What are the results of doing something like this in D?:  (Admittedly this
is a contrived example.)

class A
{
private:
  Resource r;
public:
  this() { r=AllocResource(); }
  ~this() { DeallocResource(r); }
}

void GimmeAnA(out A a)
{
  a = new A;
}

{
  A aresult;
  GimmeAnA(a);
}

Does aresult get constructed, then an assignment happen from the result of
GimmeAnA, or since it's an out parameter does the compiler ignore any
previous value in aresult and construct it directly inside GimmeAnA?  What
if aresult were used before the call to GimmeAnA?

Sean

"Walter" <walter digitalmars.com> wrote in message
news:9la3tb$178j$2 digitaldaemon.com...
 I think the rationale was that ' ' wasn't available in international
 character sets. Be that as it may, I'm seriously considering dropping
 explicit reference types entirely. Reference types will be implicit for
 arrays, classes, out and inout function parameters. I don't think anyone
 will miss them!

 -Walter

Oct 28 2001
next sibling parent "Walter" <walter digitalmars.com> writes:
You will rarely need to use a pointer in D. All instances of class objects
are on the heap, so all the programmer sees are implicit references to them.

And D does support the with statement!

"Sean L. Palmer" <spalmer iname.com> wrote in message
news:9ri1vc$1jin$1 digitaldaemon.com...
 I use references all the time to save typing.  For instance:  (C++ code)

 #include <vector>
 #include <iostream>

 struct mystruct
 {
   int foo;
 };

 {
   std::vector<mystruct> myvector;
   for (std::vector<mystruct>::iterator i = myvector.begin(); i !=
 myvector.end(); ++i)
   {
      mystruct& ms = (*i);
      std::cout << ms.foo;
   }
 }

 Now just imagine a more complex function that uses ms many times... the
 savings in typing and increased readability quickly add up.

 If you provide some kind of "with" statement ala pascal it would solve

 of the need for references, otherwise I'd suggest keeping them, they're

 convenient.  If I had to choose between Pascal's "with" clause and
 references I'd definitely choose to keep references.  They'd be

 in parameter lists since a const reference may be auto-generated by "in"
 parameters, and non-const reference auto-generated by "inout" parameters.
 I'm not 100% sure how exactly "out" parameters would work since they imply
 ignorance of the current state of the object, yet that object has to be
 passed in, so may have already been initialized etc.

 What are the results of doing something like this in D?:  (Admittedly this
 is a contrived example.)

 class A
 {
 private:
   Resource r;
 public:
   this() { r=AllocResource(); }
   ~this() { DeallocResource(r); }
 }

 void GimmeAnA(out A a)
 {
   a = new A;
 }

 {
   A aresult;
   GimmeAnA(a);
 }

 Does aresult get constructed, then an assignment happen from the result of
 GimmeAnA, or since it's an out parameter does the compiler ignore any
 previous value in aresult and construct it directly inside GimmeAnA?  What
 if aresult were used before the call to GimmeAnA?

 Sean

 "Walter" <walter digitalmars.com> wrote in message
 news:9la3tb$178j$2 digitaldaemon.com...
 I think the rationale was that ' ' wasn't available in international
 character sets. Be that as it may, I'm seriously considering dropping
 explicit reference types entirely. Reference types will be implicit for
 arrays, classes, out and inout function parameters. I don't think anyone
 will miss them!

 -Walter


Oct 28 2001
prev sibling parent reply Russell Borogove <kaleja estarcion.com> writes:
"Sean L. Palmer" wrote:
 
 I use references all the time to save typing.  For instance:  (C++ code)
 
 [...]

   for (std::vector<mystruct>::iterator i = myvector.begin(); i !=
 myvector.end(); ++i)
   {
      mystruct& ms = (*i);
      std::cout << ms.foo;
   }
 }
 
 Now just imagine a more complex function that uses ms many times... the
 savings in typing and increased readability quickly add up.

Hm, this is getting towards matters of personal style, but I disagree with this for a number of reasons. - Saving yourself typing frequently means reduced readability for the other programmers who have to deal with your code. Rather than "ms" or "i" I'd prefer to see "element" or (if it's, say, a vector of wombats) "wombat" as the name of the iterator. If you have carpal tunnel syndrome, I could cut you some slack, I guess, but on the whole, I find long identifiers to be more readable in the long run. - In your example, you've traded away "i->foo" to get "ms.foo", which is no savings to length or readability no matter how many times you make the substitution :) - If you're intending to do a lot more to ms in the loop, then it may be that you should factor that series of operations into a member function of mystruct, so the loop body becomes: i->DoWhatWombatsDo(); // or ms.DoWhatWombatsDo(); - Last but not least, STL provides the "for_each()" mechanism to clean up exactly this idiom. I myself am guilty of not having learned to use it yet. -RB
Oct 29 2001
next sibling parent a <a b.c> writes:
Russell Borogove wrote:
 Hm, this is getting towards matters of personal style, but I disagree
 with this for a number of reasons.

I'll agree with the personal style part.
 - Saving yourself typing frequently means reduced readability for
 the other programmers who have to deal with your code. Rather than
 "ms" or "i" I'd prefer to see "element" or (if it's, say, a vector of
 wombats) "wombat" as the name of the iterator. If you have carpal
 tunnel syndrome, I could cut you some slack, I guess, but on the
 whole, I find long identifiers to be more readable in the long run.

I agree in cases where the identifier is really of meaning. I consider index 'i' to be a safe and well know convention for some cases. Kind of like x, y and z for coordinates. I've also seen cases where overly verbose code subverted readability by turning a statement that could have been expressed clearly in one line into a five line paragraph that was a riddle to even the most experienced eyes. In any case, I don't have carpal and I hope to avoid it for a very long time.
 - In your example, you've traded away "i->foo" to get "ms.foo", which
 is no savings to length or readability no matter how many times you
 make the substitution :)

I suspect it was a toy example. I personally would use such a thing in cases such as physicalObject& current = (Engine->PhysicsModel->currentArea()-> objects.next()); // do we hit if(Engine->PhysicsModel->collide(player, current)){ // important stuff } // do we see it if(Engine->PhysicsModel->observe(player, current)){ // cool stuff } // does it see us if(Engine->PhysicsModel->observe(current, player)){ // bad things } // etc etc etc
 - If you're intending to do a lot more to ms in the loop, then it
 may be that you should factor that series of operations into a member
 function of mystruct, so the loop body becomes:
 
   i->DoWhatWombatsDo();  // or ms.DoWhatWombatsDo();

There are cases where that defies Modularity.
 - Last but not least, STL provides the "for_each()" mechanism to
 clean up exactly this idiom. I myself am guilty of not having learned
 to use it yet.

I personality detest for_each() and the idiom in general. It a kludge. If C++ supported some form of closure than I might not mind. Far too often I found myself creating a named function and polluting my namespaces with like functions who implementation were truly too simplistic to deserve a name. Functors are a poor excuse for a closure.
Oct 29 2001
prev sibling parent "Sean L. Palmer" <spalmer iname.com> writes:
"Russell Borogove" <kaleja estarcion.com> wrote in message
news:3BDDAE52.301C7D72 estarcion.com...
 "Sean L. Palmer" wrote:
 I use references all the time to save typing.  For instance:  (C++ code)

 [...]

   for (std::vector<mystruct>::iterator i = myvector.begin(); i !=
 myvector.end(); ++i)
   {
      mystruct& ms = (*i);
      std::cout << ms.foo;
   }
 }

 Now just imagine a more complex function that uses ms many times... the
 savings in typing and increased readability quickly add up.

Hm, this is getting towards matters of personal style, but I disagree with this for a number of reasons. - Saving yourself typing frequently means reduced readability for the other programmers who have to deal with your code. Rather than "ms" or "i" I'd prefer to see "element" or (if it's, say, a vector of wombats) "wombat" as the name of the iterator. If you have carpal tunnel syndrome, I could cut you some slack, I guess, but on the whole, I find long identifiers to be more readable in the long run.

It is a matter of personal style. I do this because it makes it easier to change the container type later without having to change all references inside the block using an item in the container. I prefer locals with short names... it's easy enough to glance up a few lines to find the declaration of ms. I do prefer descriptive names on members and functions. Readability of code does not increase proportionally to the length of the identifiers used... It's good up to a point, then starts to get worse because simple operations need code that goes off the edge of the screen. Brevity can be good too, to a point. My identifiers tend to be between 6 and 20 characters. I can tolerate long function names better than long variable names. I think this all ends up being a matter personal taste and has nothing to do with the design of the D language.
 - In your example, you've traded away "i->foo" to get "ms.foo", which
 is no savings to length or readability no matter how many times you
 make the substitution :)

ms.foo is much better than (*i).foo, which I end up having to use because some compilers' STL still don't support the operator -> on iterators. ;) It's easy to extrapolate to a situation where to get ms, you have to do some serious work, such as mystruct& ms = (*i)->member.grabentries(index1)[index2].second; I'm sure you'd agree that having twenty instances of (*i)->member.grabentries(index1)[index2].second in your function would decrease readability and maintainability.
 - If you're intending to do a lot more to ms in the loop, then it
 may be that you should factor that series of operations into a member
 function of mystruct, so the loop body becomes:

   i->DoWhatWombatsDo();  // or ms.DoWhatWombatsDo();

 - Last but not least, STL provides the "for_each()" mechanism to
 clean up exactly this idiom. I myself am guilty of not having learned
 to use it yet.

Without being able to declare classes inside a function, for_each clutters the code by requiring that the code that operates on each item be separated lexically from the code doing the for_each. Not that I'm against for_each, I like it... I guess I'm just as guilty as you, maybe more so because I know how to use it and yet still find myself typing iterating loops alot. ;) I suppose the with clause will help alot with this sort of thing. What I don't like about Pascal's with clause is that it basically injects the object's contents directly into the current scope... I'd rather be able to give the result a new name of my choosing, to avoid ambiguity, like so: with ((*i)->member.grabentries(index1)[index2].second) as ms { ms.DoSomething(); ms.DoSomethingElse(); ++ms.foo; cout << ms.foo; } Sean
Nov 03 2001
prev sibling parent reply Yu Qian Zhou <yqz comlab.ox.ac.uk> writes:
I like the following quotes from the D spec:

  Experienced FORTRAN numerics programmers know that multidimensional 
  "rectangular" arrays for things like matrix operations are much 
  faster than trying to access them via pointers to pointers resulting 
  from "array of pointers to array" semantics. 

I just wonder why rectangular arrays must be static as in Fortran?  
Can we also have *dynamic* rectangular arrays in D as well (of course 
we need some new syntax here):

    int    matrix[2,3];			// static  rectangular array
    int[,] matrix = new int[2,3];	// dynamic rectangular array

If the implementation for this dynamic rectangular array can also give 
better performance than the "pointers to pointers" approach, I think 
people writing numeric applications would be interested in it.

YuQian
Sep 04 2001
parent "Walter" <walter digitalmars.com> writes:
Dynamic rectangular arrays are possible, just not implemented in D. You can
fake them with a single dimensioned dynamic array, however.

Yu Qian Zhou wrote in message ...
I like the following quotes from the D spec:

  Experienced FORTRAN numerics programmers know that multidimensional
  "rectangular" arrays for things like matrix operations are much
  faster than trying to access them via pointers to pointers resulting
  from "array of pointers to array" semantics.

I just wonder why rectangular arrays must be static as in Fortran?
Can we also have *dynamic* rectangular arrays in D as well (of course
we need some new syntax here):

    int    matrix[2,3]; // static  rectangular array
    int[,] matrix = new int[2,3]; // dynamic rectangular array

If the implementation for this dynamic rectangular array can also give
better performance than the "pointers to pointers" approach, I think
people writing numeric applications would be interested in it.

YuQian

Sep 04 2001