473,405 Members | 2,171 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,405 software developers and data experts.

Two Dimensional Array Template

http://groups.google.com/group/comp....092f0f6c9bf13a

I think that the operator[]() member function does not work correctly, does
anyone else know how to make a template for making two dimensional arrays from
std::vectors ??? I want to use normal Array[ROW][COL] Syntax.
Jan 1 '07
272 13832
Daniel T. wrote:
Gianni Mariani <gi*******@mariani.wswrote:
>Daniel T. wrote:
....
>>Regardless, if you can show an interface that can work for "native 2D
arrays", row-major, column-major and sparse arrays, then you will have
taught me something very cool. I'd love to see it.
<brain dump - be warned>
[snipped brain dump]

Now it is me who should have read the FAQ. :-) The procedure you
outlined is exactly what the FAQ recommends in item 13.12.
The idea behind that proxy technique is obvious once you dig closures :-)

http://en.wikipedia.org/wiki/Closure...ter_science%29

I like to think of closures as being what you get when you call
functions taking two or more arguments, but without passing all the
arguments they need, yet. Sort of like unfinished function invocations.
You end up with a function taking the remaining arguments, so that you
can finish invoking it later. Of course, in C++, you have to actually
define appropriate classes for this, rather than do it with normal
functions.

[Start C++ snippet.]

double foo (int, double);

class foo_closure_1 {
int a;

public:
explicit foo_closure_1 (int arg1): a(arg1) {}
double operator() (double arg2) const { return foo(a, arg2); }
};

class foo_closure_2 {
double a;

public:
explicit foo_closure_2 (double arg2): a(arg2) {}
double operator() (int arg1) const { return foo(arg1, a); }
};

foo_closure_1 foo (int arg1) { return foo_closure_1(arg1); }
foo_closure_2 foo (double arg2) { return foo_closure_2(arg2); }

double bar () {
foo_closure_1 foo1 = foo(42);
foo_closure_2 foo2 = foo(37.361);
return foo1(foo2(8));
}

[End C++ snippet.]

:-D

Back to two-dimensional arrays and proxies, there's a few things I'd
like to add:-

* We don't have to choose between [][] and (,); we can have both. If
we have both, it'll work with code that expects a [][] interface and
code that expects a (,) interface.

* We can have both row() and col() member functions as well, returning
corresponding row_reference and col_reference proxies. So, as well as
being able to access whole rows, we can also access whole columns,
regardless of how the array is actually implemented internally. (We
could have things like transpose proxies, as well.)

* We can have row and column iterators.

* When we need to apply a generic algorithm to a row or column, and
that algorithm's interface is for one-dimensional array-like things, we
can use the appropriate row or column proxy to present that algorithm
with an appropriate interface to the data.

* Having row() and col(), and the like, as part of the interface,
rather than just having (,), saves others from having to write their own
wrappers when they need to do this proxy type stuff.

* If we do a sufficiently good job of it, we'll be able to use it on
many occasions when two-dimensional arrays are needed, instead of
reimplementing them all the time. So it really doesn't matter that this
proxy stuff takes a bit more work to implement, because it's potentially
a lot more work saved in the long run!

:-)

Simon

--
What happens if I mention Leader Kibo in my .signature?
Jan 3 '07 #51

This one is going to Marshall Cline as well, the maintainer of the FAQ
as well as to the news-group.

Daniel T. wrote:
"Peter Olcott" <No****@SeeScreen.comwrote:
> http://groups.google.com/group/comp....092f0f6c9bf13a

I think that the operator[]() member function does not work
correctly, does anyone else know how to make a template for making
two dimensional arrays from std::vectors ?

http://www.parashift.com/c++-faq-lit...html#faq-13.10
>I want to use normal Array[ROW][COL] Syntax.

Why?
It's time to change the FAQ 13.10/13.11/13.12

Let's look at it in more detail:

13.10 provides no reasoning for the advice "Use operator() rather than
operator[]." and leaves all the heavy lifting of reasoning to 13.11.

............ FAQ13.11 says: ............

P1 Here's what this FAQ is really all about: Some people build a Matrix
class that has an operator[] that returns a reference to an Array object
(or perhaps to a raw array, shudder), and that Array object has an
operator[] that returns an element of the Matrix (e.g., a reference to a
double). Thus they access elements of the matrix using syntax like
m[i][j] rather than syntax like m(i,j).

P2 The array-of-array solution obviously works, but it is less flexible
than the operator() approach. Specifically, there are easy performance
tuning tricks that can be done with the operator() approach that are
more difficult in the [][] approach, and therefore the [][] approach is
more likely to lead to bad performance, at least in some cases.

P3 For example, the easiest way to implement the [][] approach is to use
a physical layout of the matrix as a dense matrix that is stored in
row-major form (or is it column-major; I can't ever remember). In
contrast, the operator() approach totally hides the physical layout of
the matrix, and that can lead to better performance in some cases.

P4 Put it this way: the operator() approach is never worse than, and
sometimes better than, the [][] approach.

* The operator() approach is never worse because it is easy to
implement the dense, row-major physical layout using the operator()
approach, so when that configuration happens to be the optimal layout
from a performance standpoint, the operator() approach is just as easy
as the [][] approach (perhaps the operator() approach is a tiny bit
easier, but I won't quibble over minor nits).

* The operator() approach is sometimes better because whenever the
optimal layout for a given application happens to be something other
than dense, row-major, the implementation is often significantly easier
using the operator() approach compared to the [][] approach.

P5 As an example of when a physical layout makes a significant
difference, a recent project happened to access the matrix elements in
columns (that is, the algorithm accesses all the elements in one column,
then the elements in another, etc.), and if the physical layout is
row-major, the accesses can "stride the cache". For example, if the rows
happen to be almost as big as the processor's cache size, the machine
can end up with a "cache miss" for almost every element access. In this
particular project, we got a 20% improvement in performance by changing
the mapping from the logical layout (row,column) to the physical layout
(column,row).

P6 Of course there are many examples of this sort of thing from
numerical methods, and sparse matrices are a whole other dimension on
this issue. Since it is, in general, easier to implement a sparse matrix
or swap row/column ordering using the operator() approach, the
operator() approach loses nothing and may gain something — it has no
down-side and a potential up-side.

Use the operator() approach.
........... end 13.11 FAQ ..........

Let's see if we can make any sense of this given what has been discussed
many times:

P1 - no advice given

P2 - claims that
a) [][] is less flexible than (,)
b) [][] is lower performance because of a)

P3 - discusses one possible implementation of [][] and claims that (,)
can use performance tricks and so is better that [][].

P4 - states that (,) is never worse than [][] because:
a) it is easier to implement different layouts in (,) than [][]
b) layouts other than dense row-major are not available for [][]

P5 - explains example of changing matrix layouts, says nothing about
[][] vs (,) specifically.

P6 - claims again that (,) is more flexible than [][].
As you can see, the FAQ bases all the claims on the false assumption
that by using [][], you cannot implement optimizations using (,). As
has been shown many times before and again elsewhere in this thread and
also in FAQ 13.12, [][] can be used to call an (,) functor with no
performance penalty and hence can enjoy the same performance tuning and
tweaks as (,). Then the question remains, why employ the (,) syntax at
all since the only claim made in the 13.11FAQ is absolutely false?

Clearly, multi-dimensional array, matricies or whaterver your favorite
name is for these things has been traditionally the [][] flavour. There
is also clearly a non trivial amount of code and expertise using the
[][] type syntax and there is clearly no confusion about what X[a][b]
means when written in code.

Also, properly written function templates will easily work with native
array-of-array (in much the same way as STL containers work with the []
syntax) as well as special matrix classes. Hence that body of template
functions for matrix manipulations will work with new and old code.
Exactly the same way that std::sort works with containers as well as raw
arrays of objects.

Let's enumerate the reasons for [][].

1. [][] syntax is well understood by C++ programmers for manipulating
multi-dimensional properties. No surprises here !
2. X[a][b] will never be confused like X(a,b) as a function call to
function X.
3. Legacy code can make use of modern templates using the [][] syntax
while converting legacy code to (,) would need major code surgery.
4. array2D[a] is syntactic sugar for a row reference and can be used to
optimize accesses.

The 13.11 FAQ states NO justifiable reasons to use (,) at all since it
is all based on the premise that (,) is "more flexible" than [][] which
has been debunked by the FAQ itself as well as others. The only reason
even close to having merit is that (,) does not expose any internal
working, the question is, how much merit do you give this one since the
row reference proxy need not expose anything anyway.

It's time to change 13.10 to recommend the use of the [][] syntax since
in my opinion which is shared by others, there is no good reason to use (,).

OK - while we are at it, the code in the matrix class in 13.10 should
not throw "BadIndex", it should assert. Indexing beyond the bounds of
an array is a fatal error and the program should be aborted.

Any talk of the (,) syntax in the future FAQ should be as a history
lesson, not as a recommendation.
Jan 3 '07 #52
"Gianni Mariani" <gi*******@mariani.wswrote:
Let's see if we disagree on any of these statements:

a) in C and in C++ matricies have been traditionally supported using
[][] (array of array) syntax. Hence there is a non-trivial body of
code and knowledge that is using [][] as opposed to (,).
I disagree. [][] is used extensively in C, but in C++ I believe that
most code involving matrices uses some sort of matrix class.
b) Because of proxy classes, [][] is exactly equivalent in
functionality to (,) or perhaps even a superset.
Here I agree. Which is why I said it is purely a matter of syntax for
you. You are so married to the [][] that you just can't let it go even
though implementing a class that can support it is more complex than
implementing a class that supports (,)
c) Many standard matrix operations will be coded in templates
(multiples, inverses etc).

d) Many of these "matrix" templates can be used to operate on legacy
C and C++ code as well as newer code using proxy (or non proxy array
classes like the OP code) using [][].
As I and others have mentioned before, if you have a bunch of legacy
code that you need to support then that is sufficient justification to
use the [][] syntax.

That is not sufficient justification to continue using it in an
environment where legacy code need not be supported. A perfect example
is the use of std::vector. It is acceptable and understood that legacy
code will use [] to access elements in a vector, but new code really
should use iterators.
Having shown what a proxy class might look like, you will see that
all the arguments in the FAQ (yes - all of them) supporting (,) have
no supportable rationale at all.
I disagree. The fact that you used proxy classes to convert [][] into
(,) shows that all of the arguments in the FAQ are right on the mark.
Hence the reason you chose to use (,) "under the covers".
Perhaps it's one of the most short-sighted sections of the entire
FAQ.
Again I disagree. The most short-sighted section is the one talking
about using declarations. :-)
No generality at all is lost using [][] over (,) while the visa
versa statement is NOT true. (,) loses in 2 very significant ways.

1) new functions on older code
2) new learning curve for no real gain
Number (1) above has already been accepted and specifically mentioned in
the FAQ. Number (2) is just plain silly. The learning curve on proper
proxy creation is sharper than the learning curve involved in changing
syntax.
You say "needlessly" complicated ? The complexity is in ONE place
and makes most other code easier to read. This is a Good(TM)
tradeoff.
I disagree. The complexity exists in more than one place--it must exist
in every class that implements a multi-dimensional array--and most other
code is no easier to read--a programmer that can't grep the (,) syntax
instantly, doesn't understand function calls.
Needlessly changing a body of code using [][] to (,) is far more
complex. It's also not exactly a complex concept.
Again, your only argument that holds any water involves legacy code and
the FAQ has already excepted that case.
Jan 3 '07 #53
Daniel T. wrote:
"Gianni Mariani" <gi*******@mariani.wswrote:
>Let's see if we disagree on any of these statements:

a) in C and in C++ matricies have been traditionally supported using
[][] (array of array) syntax. Hence there is a non-trivial body of
code and knowledge that is using [][] as opposed to (,).

I disagree. [][] is used extensively in C, but in C++ I believe that
most code involving matrices uses some sort of matrix class.
I have never seen production code use (,) for array indexing.
>
.... much snipped.
>
>Having shown what a proxy class might look like, you will see that
all the arguments in the FAQ (yes - all of them) supporting (,) have
no supportable rationale at all.

I disagree. The fact that you used proxy classes to convert [][] into
(,) shows that all of the arguments in the FAQ are right on the mark.
Hence the reason you chose to use (,) "under the covers".
You misunderstand my intention for writing that class. I made that proxy
class to make a point that anything you can do with (,) you can do with
[][]. That was it's only purpose.

....
>No generality at all is lost using [][] over (,) while the visa
versa statement is NOT true. (,) loses in 2 very significant ways.

1) new functions on older code
2) new learning curve for no real gain

Number (1) above has already been accepted and specifically mentioned in
the FAQ. Number (2) is just plain silly. The learning curve on proper
proxy creation is sharper than the learning curve involved in changing
syntax.
I think you severely underestimate the familiarity programmers have with
[][] and the foreign nature of (,).
>
>You say "needlessly" complicated ? The complexity is in ONE place
and makes most other code easier to read. This is a Good(TM)
tradeoff.

I disagree. The complexity exists in more than one place--it must exist
in every class that implements a multi-dimensional array--and most other
code is no easier to read--a programmer that can't grep the (,) syntax
instantly, doesn't understand function calls.
The (,) syntax is usually called a "functor", not a "subscript"
operator. It is clearly the intention of the language designers that
[][] be used to access arrays and (,) used to call a functor. It
appears strange to me why you would ever want to use a functor when a
subscript operator is clearly intended for it's purpose.
>
>Needlessly changing a body of code using [][] to (,) is far more
complex. It's also not exactly a complex concept.

Again, your only argument that holds any water involves legacy code and
the FAQ has already excepted that case.
Why would I ever want to build a body of code that would exclude the
largest set of customers ? Legacy code using [][] syntax is here for a
very very long time. There really should be a very solid reason to
deviate. All the reasons given so far to use (,) in preference to [][]
hold no water IMHO.
Jan 3 '07 #54
Gianni Mariani <gi*******@mariani.wswrote:

[from the faq]
Here's what this FAQ is really all about: Some people build a
Matrix class that has an operator[] that returns a reference to
an Array object (or perhaps to a raw array, shudder), and that
Array object has an operator[] that returns an element of the
Matrix (e.g., a reference to a double). Thus they access
elements of the matrix using syntax like m[i][j] rather than
syntax like m(i,j).
The above is what I think we have both lost sight of. Peter initially
posted code that did exactly what the above paragraph talks about and I
agreed with the FAQ about the inappropriateness of it. When I asked you
to present an appropriate example that uses the [][] syntax, you
proceeded to present one that is specifically marked as acceptable by
the FAQ.

It is important to note that the FAQ is not comparing two syntaxes, but
two implementations. On the one hand having an op[] that returns a
reference to an array object or a raw array (something I think we can
both agree is a bad idea,) on the other hand not doing so.
Jan 3 '07 #55
Gianni Mariani <gi*******@mariani.wswrote:
This one is going to Marshall Cline as well, the maintainer of the FAQ
as well as to the news-group.
He is not the maintainer of this newsgroup. This is not a moderated
forum. By all means though, send it to him. I have found him very
accessible in the past.
Jan 3 '07 #56
On Thu, 04 Jan 2007 01:41:25 +1100, Gianni Mariani wrote:
Daniel T. wrote:
>"Gianni Mariani" <gi*******@mariani.wswrote:
>>Let's see if we disagree on any of these statements:

a) in C and in C++ matricies have been traditionally supported using
[][] (array of array) syntax. Hence there is a non-trivial body of
code and knowledge that is using [][] as opposed to (,).

I disagree. [][] is used extensively in C, but in C++ I believe that
most code involving matrices uses some sort of matrix class.

I have never seen production code use (,) for array indexing.
I have written much production code using (,) for array indexing (you
won't see it however, as it is closed-source and owned by the various
companies I worked for :/).

[snip]
I think you severely underestimate the familiarity programmers have with
[][] and the foreign nature of (,).
Not so sure about that... one class of programmers for whom (,) will be
second nature are scientific/mathematical (and in particular
[ex-]Fortran) programmers. In mathematics an array/matrix is not
generally perceived as a "vector-of-vectors" (except when it is...) and
the (,) notation sits fine with me (okay, so I *am* an ex-Fortran
programmer :))

Personally I'm comfortable with either notation and concur with Daniel T.
that the only legitimate reason - albeit possibly a significant one - for
using the [][] syntax is legacy code support. So notwithstanding your
demonstration that the two approaches may be made functionally equivalent
via proxy classes, I'll go with the simpler implementation and (to me)
marginally preferable syntax of (,).

[snip]
>I disagree. The complexity exists in more than one place--it must exist
in every class that implements a multi-dimensional array--and most
other code is no easier to read--a programmer that can't grep the (,)
syntax instantly, doesn't understand function calls.

The (,) syntax is usually called a "functor", not a "subscript"
operator.
He didn't say "subscript operator", he said "function calls"... and a
"functor" operator is of course a function, as is a "subscript
operator". If, as a C++ programmer round brackets don't scream "function"
to you, you're surely in trouble... whatever other conceptual baggage
(functor, subscript operator,...) you care to attach to a particular
function comes after that fact.
It is clearly the intention of the language designers that
[][] be used to access arrays
Which language? C? ;)

[snip]

--
Lionel B
Jan 3 '07 #57

Gianni Mariani wrote:
The (,) syntax is usually called a "functor", not a "subscript"
operator. It is clearly the intention of the language designers that
[][] be used to access arrays and (,) used to call a functor. It
appears strange to me why you would ever want to use a functor when a
subscript operator is clearly intended for it's purpose.
Well, if you want to go there...basing arguments of design on what the
language designers intended...then forcing [][] on a class has no place
in any code since if the language designers had intended a class to
override [][] they would have provided the means to do so.
>
Needlessly changing a body of code using [][] to (,) is far more
complex. It's also not exactly a complex concept.
Again, your only argument that holds any water involves legacy code and
the FAQ has already excepted that case.

Why would I ever want to build a body of code that would exclude the
largest set of customers ? Legacy code using [][] syntax is here for a
very very long time.
Only so long as it is not changed. I work on legacy code every
day...some of the nastiest stuff ever written at times. It is rather
easy work, though boring, to change function call signatures and go
from [] to f(). I know this because I do it every day. So unless you
are selling a library that has a bunch of legacy code based on it you
don't need to worry about it...and as you showed, you can always
implement the deprecated interface for those that do if you are in such
a situation or if you don't want to change everything immediately.

No, when dealing with legacy code the issue of syntax is a minor one.

There really should be a very solid reason to
deviate. All the reasons given so far to use (,) in preference to [][]
hold no water IMHO.
(,) is easier to implement and lowers the complication of the code.
There is no need for a special row proxy when you change from the row
major form or to provide safety. It is also miles better than the most
common implementation of [][] though not a whole deal greater than the
best...it's just less complex and therefore the better alternative. IE
keep it as simple as you can but no simpler.

More to the point. You shouldn't be implementing a "2d array". You
should be looking for a better abstraction. Once you have that better
abstraction there is no need, nor desire, to advertize that it is a 2d
array. I think the fact that there is no 2d array in the standard, nor
does there seem to be one comming in the forseable future, is quite
telling.

Your insistance on implementing a basic function as a complex set of
operator overloads reminds me of the subscript operator implemented in
some of the legacy code I work on. Implemented [] for a list that
returns the object with the serial id supplied...it's of course linear.
Then base mass "legacy" code on it in a bunch of for loops. Took me
about 4 hours to pull that member out and change all the [] calls to
functional equivilants. Time well spent IMHO...bad design is bad
design and we shouldn't stick to it just in the name of "legacy" unless
we absolutely have to.

At any rate, like I said...unless you are in the situation of dealing
with legacy code there is no need to worry about it. So why go to all
the trouble of forcing the [][] issue? When you are in the situation
of worrying about legacy code it's a mater of economics...I will grant
that there are probably times when forcing [][] will be the less costly
alternative but it is quite easy to implement as f(,) and then wrap
[][] on top and call it deprecated...in fact it's the easiest and
safest way to implement [][] anyway.

Jan 3 '07 #58
Gianni Mariani wrote:
>
It's time to change the FAQ 13.10/13.11/13.12
I'm inclined to agree that it could do with a rewrite, but I'm not in
favour of going to the opposite extreme of being opposed to using (,).

For 13.10, I think a better answer would be that there are various ways
of doing it:-

* Using operator(), so that all the subscripts can be given in one go.
This, of course, is already illustrated in that FAQ.

* Using operator[], but having it return a proxy as described in a
subsequent FAQ.

* Using member functions, such as row() and col(), to make it explicit
(and therefore clear what's being done). This should also be explained
in a subsequent FAQ.

It should also be emphasized that these aren't mutually exclusive
alternatives, and can all be provided in the same interface. It should,
of course, also be emphasized that the interface should not expose the
implementation.

I'd do away with 13.11, as it is misleading (for reasons disclosed in
this thread). Instead, I'd have 13.12 as the answer to the question,
"Okay, but how do I do it with operator[], then?" I think 13.12 could
do with a bit of rewriting anyway. It could also point out that the
proxy technique can also be used to allow whole columns, as well as
whole rows, to be accessed. That could also serve as a good example of
one of the advantages of keeping the interface independent of
implementation details.

Anyway, those are my quick thoughts on the matter.

Simon

--
What happens if I mention Leader Kibo in my .signature?
Jan 3 '07 #59

Gianni Mariani wrote:
3. Legacy code can make use of modern templates using the [][] syntax
while converting legacy code to (,) would need major code surgery.
I'd call it rather minor surgery. Any time there is a call to [][]
change to (,)...it's easy.
4. array2D[a] is syntactic sugar for a row reference and can be used to
optimize accesses.
Syntatic sugar yes....optimize accesses? How? Frankly it's no
different at all....assuming the compiler is able to do some basic, and
some less basic, optimizations.

Jan 3 '07 #60
Gianni Mariani wrote:
Let's see if we disagree on any of these statements:

a) in C and in C++ matricies have been traditionally supported using
[][] (array of array) syntax. Hence there is a non-trivial body of
code and knowledge that is using [][] as opposed to (,).
No. In C, matrices have been traditionally supported using something
other than [][] -- at least for 'serious' numerical linear algebra
applications. Take a look at CLAPACK, the C interface for BLAS, or any
C implementation for sparse matrices.

- Kevin Hall

Jan 3 '07 #61

Lionel B wrote:
On Thu, 04 Jan 2007 01:41:25 +1100, Gianni Mariani wrote:
Daniel T. wrote:
"Gianni Mariani" <gi*******@mariani.wswrote:

Let's see if we disagree on any of these statements:

a) in C and in C++ matricies have been traditionally supported using
[][] (array of array) syntax. Hence there is a non-trivial body of
code and knowledge that is using [][] as opposed to (,).

I disagree. [][] is used extensively in C, but in C++ I believe that
most code involving matrices uses some sort of matrix class.
I have never seen production code use (,) for array indexing.

I have written much production code using (,) for array indexing (you
won't see it however, as it is closed-source and owned by the various
companies I worked for :/).

[snip]
I think you severely underestimate the familiarity programmers have with
[][] and the foreign nature of (,).

Not so sure about that... one class of programmers for whom (,) will be
second nature are scientific/mathematical (and in particular
[ex-]Fortran) programmers. In mathematics an array/matrix is not
generally perceived as a "vector-of-vectors" (except when it is...) and
the (,) notation sits fine with me (okay, so I *am* an ex-Fortran
programmer :))
It's not just Fortran that has a good syntax for multidimensional
arrays. S (the language of S-Plus and R), Matlab, Python/Numpy, and
Visual Basic also use commas to delimit the dimensions of an array,
even when they use [] rather than () to enclose the subscripts.

a[i][j][k] is awkward compared to a[i,j,k] or a(i,j,k) IMO.

Jan 3 '07 #62
Lionel B wrote:
On Thu, 04 Jan 2007 01:41:25 +1100, Gianni Mariani wrote:
....
>I think you severely underestimate the familiarity programmers have with
[][] and the foreign nature of (,).

Not so sure about that... one class of programmers for whom (,) will be
second nature are scientific/mathematical (and in particular
[ex-]Fortran) programmers. In mathematics an array/matrix is not
generally perceived as a "vector-of-vectors" (except when it is...) and
the (,) notation sits fine with me (okay, so I *am* an ex-Fortran
programmer :))

Personally I'm comfortable with either notation and concur with Daniel T.
that the only legitimate reason - albeit possibly a significant one - for
using the [][] syntax is legacy code support. So notwithstanding your
demonstration that the two approaches may be made functionally equivalent
via proxy classes, I'll go with the simpler implementation and (to me)
marginally preferable syntax of (,).

[snip]
.... snip

CLEARLY this argument is a question about syntax preference as you
demonstrated in the last two paragraphs by yourself, this is not a
technical argument about the C++ standard. IMHO, this news-group is not
the place to be making it an agenda on preferences. In other words,
sure, knock yourself out, use (,) for yourself, however keep the fallous
arguments that (,) has significant technical superiority over [][] out
of the discussion.
>
>It is clearly the intention of the language designers that
[][] be used to access arrays

Which language? C? ;)
C++ actually. As I mentioned, operator() is termed a functor and
operator[] is termed a subscript operator.

The FAQ is about the C++ standard and titled:

"[13.10] How do I create a subscript operator for a Matrix class?"

Clearly it does nothing of the kind since "subscript operator" is a C++
term for operator[]. In goes onto expressing an unsubstantiated syntax
preference and then making clearly false statements about the
superiority of (,) over [][].
>
.... snip
Jan 3 '07 #63
Noah Roberts wrote:
Gianni Mariani wrote:
>The (,) syntax is usually called a "functor", not a "subscript"
operator. It is clearly the intention of the language designers that
[][] be used to access arrays and (,) used to call a functor. It
appears strange to me why you would ever want to use a functor when a
subscript operator is clearly intended for it's purpose.

Well, if you want to go there...basing arguments of design on what the
language designers intended...then forcing [][] on a class has no place
in any code since if the language designers had intended a class to
override [][] they would have provided the means to do so.
The language designers have provided a means to override [][], it has
been demonstrated earlier in this thread and is described in 13.12 of
the FAQ.
>>>Needlessly changing a body of code using [][] to (,) is far more
complex. It's also not exactly a complex concept.
Again, your only argument that holds any water involves legacy code and
the FAQ has already excepted that case.
Why would I ever want to build a body of code that would exclude the
largest set of customers ? Legacy code using [][] syntax is here for a
very very long time.

Only so long as it is not changed. I work on legacy code every
day...some of the nastiest stuff ever written at times. It is rather
easy work, though boring, to change function call signatures and go
from [] to f(). I know this because I do it every day. So unless you
are selling a library that has a bunch of legacy code based on it you
don't need to worry about it...and as you showed, you can always
implement the deprecated interface for those that do if you are in such
a situation or if you don't want to change everything immediately.
We're loosing sight of the argument here. Sure, knock yourself out,
change your code to use (,) vs [][]. I certainly would be far more
cautious of changing code like that.

The use of (,) over [][] is simply a preference. The C++ standard never
mentions (,) as a subscript operator. This news group is about the C++
standard. As a preference, it should remain at most a suggestion, and
not run into a fallous diatribe over the merits of (,) over [][]. That
is the argument we have here.
>
No, when dealing with legacy code the issue of syntax is a minor one.
That is again an opinion. I personally approach wholesale changes like
that you describe with more caution. If I can make the change in the
library (in one place), then I would need a really good reason to start
changing large bodies of code. Simple syntactic preference is not a
good reason IMHO.
>
There really should be a very solid reason to
>deviate. All the reasons given so far to use (,) in preference to [][]
hold no water IMHO.

(,) is easier to implement and lowers the complication of the code.
This one is clearly debunked. It takes 20 lines of code which is IMHO a
very low threshold.
There is no need for a special row proxy when you change from the row
major form or to provide safety. It is also miles better than the most
common implementation of [][] though not a whole deal greater than the
best...it's just less complex and therefore the better alternative. IE
keep it as simple as you can but no simpler.
Again the simplicity argument is in the eye of the beholder. I can't
argue about what you feel but I can say I have a vastly different
opinion of the merits of simplicity and where and when it should be
applied. This line of argument ends in the "Mariani complexity
proposition".

The Mariani simplicity/complexity proposition: There exists a minimum
complexity when modeling multiple interactive systems.

Lemma 1. When modelling interactions between multiple systems, there
exists a minimum level of complexity of the interfaces where the
overall complexity of the entire system is also minimal.

In other words, if you make your interfaces too simple, your overall
solution is more complex.

This again would lead to a conclusion about personal preferences.
>
More to the point. You shouldn't be implementing a "2d array". You
should be looking for a better abstraction. Once you have that better
abstraction there is no need, nor desire, to advertize that it is a 2d
array. I think the fact that there is no 2d array in the standard, nor
does there seem to be one comming in the forseable future, is quite
telling.
Sure, go for it. Regardless, there is a huge body of code that says
differently. Again this boils down to syntactic preference, not a
technical argument of the deficiencies of [][].
>
Your insistance on implementing a basic function as a complex set of
operator overloads reminds me of the subscript operator implemented in
some of the legacy code I work on. Implemented [] for a list that
returns the object with the serial id supplied...it's of course linear.
Then base mass "legacy" code on it in a bunch of for loops. Took me
about 4 hours to pull that member out and change all the [] calls to
functional equivilants. Time well spent IMHO...bad design is bad
design and we shouldn't stick to it just in the name of "legacy" unless
we absolutely have to.
If I was your supervisor I would have asked you to revert your change
unless you had a very good technical reason. All you have stated was a
technical preference.
>
At any rate, like I said...unless you are in the situation of dealing
with legacy code there is no need to worry about it. So why go to all
the trouble of forcing the [][] issue?
I think I am clearly on the side of C++ in that [][] has been used far
more than (,) and is the default syntax. You need to make an argument to
change it from [][] which is substantiated by more than just personal
preferences.
... snip
Jan 3 '07 #64
Kevin Hall wrote:
Gianni Mariani wrote:
>Let's see if we disagree on any of these statements:

a) in C and in C++ matricies have been traditionally supported using
[][] (array of array) syntax. Hence there is a non-trivial body of
code and knowledge that is using [][] as opposed to (,).

No. In C, matrices have been traditionally supported using something
other than [][] -- at least for 'serious' numerical linear algebra
applications. Take a look at CLAPACK, the C interface for BLAS, or any
C implementation for sparse matrices.
I have seen *alot* of gl and OpenGL code that uses [][].
Jan 3 '07 #65

Gianni Mariani wrote:
Noah Roberts wrote:
Gianni Mariani wrote:
The (,) syntax is usually called a "functor", not a "subscript"
operator. It is clearly the intention of the language designers that
[][] be used to access arrays and (,) used to call a functor. It
appears strange to me why you would ever want to use a functor when a
subscript operator is clearly intended for it's purpose.
Well, if you want to go there...basing arguments of design on what the
language designers intended...then forcing [][] on a class has no place
in any code since if the language designers had intended a class to
override [][] they would have provided the means to do so.

The language designers have provided a means to override [][], it has
been demonstrated earlier in this thread and is described in 13.12 of
the FAQ.
No, that is a way to override [] in two classes and use function
chaining to *mimic* an [][] operator.
The use of (,) over [][] is simply a preference. The C++ standard never
mentions (,) as a subscript operator. This news group is about the C++
standard. As a preference, it should remain at most a suggestion, and
not run into a fallous diatribe over the merits of (,) over [][]. That
is the argument we have here.
Nor does the standard mention multi-dimensional arrays or [][]. So, if
we have to stick to the *standard* to get an opinion about which way to
go we have to say that there is just no such thing and leave it at
that.

However, the standard DOES provide tools to implement functional calls
and to override a single subscript operator.
>

No, when dealing with legacy code the issue of syntax is a minor one.

That is again an opinion. I personally approach wholesale changes like
that you describe with more caution. If I can make the change in the
library (in one place), then I would need a really good reason to start
changing large bodies of code. Simple syntactic preference is not a
good reason IMHO.
If there is suddenly a need for a 2d array abstraction then there is
obviously a need for a change.
>

There really should be a very solid reason to
deviate. All the reasons given so far to use (,) in preference to [][]
hold no water IMHO.
(,) is easier to implement and lowers the complication of the code.

This one is clearly debunked. It takes 20 lines of code which is IMHO a
very low threshold.
Even one line of unnecissary complication is unnecissary complication.
More to the point. You shouldn't be implementing a "2d array". You
should be looking for a better abstraction. Once you have that better
abstraction there is no need, nor desire, to advertize that it is a 2d
array. I think the fact that there is no 2d array in the standard, nor
does there seem to be one comming in the forseable future, is quite
telling.

Sure, go for it. Regardless, there is a huge body of code that says
differently.
Not where I'm sitting. I don't care what everyone else's huge body of
code has in it. Frankly, if the whole damn world used [][] for their
matrix abstractions, which it doesn't, it wouldn't have any bearing on
what I choose to use in mine. Nor should you let what someone else is
doing keep you from doing something better unless interaction is a
necessity. I certainly have no need to interact with the whole world
on matrix abstractions.

Your insistance on implementing a basic function as a complex set of
operator overloads reminds me of the subscript operator implemented in
some of the legacy code I work on. Implemented [] for a list that
returns the object with the serial id supplied...it's of course linear.
Then base mass "legacy" code on it in a bunch of for loops. Took me
about 4 hours to pull that member out and change all the [] calls to
functional equivilants. Time well spent IMHO...bad design is bad
design and we shouldn't stick to it just in the name of "legacy" unless
we absolutely have to.

If I was your supervisor I would have asked you to revert your change
unless you had a very good technical reason. All you have stated was a
technical preference.
How about not being able to use any other container for a "technical"
preference?

You seem overly concerned with change. I would suggest reading some
books on refactoring and possibly "Working effectively with legacy
code." Such syntatical changes are quite easy to do while being 100%
certain no behavioral change occured.

Let's just leave it as it's a damn good thing you're not my supervisor.
I hate working under micro-managers.
>

At any rate, like I said...unless you are in the situation of dealing
with legacy code there is no need to worry about it. So why go to all
the trouble of forcing the [][] issue?

I think I am clearly on the side of C++ in that [][] has been used far
more than (,) and is the default syntax. You need to make an argument to
change it from [][] which is substantiated by more than just personal
preferences.
All you keep saying...and you keep saying it as if it will make it
true...is that your side is stronger and therefor should be the
default. You have yet to show it in any way.

Your "legacy code" argument assumes so many illegitamate details that
are likely not even true in most cases. You not only have to have this
huge code base that uses C style arrays instead of a true abstraction
but it has to be outside your own control or so rigid that it can't
handle the addition of a true abstraction to the mix. Granted...there
are situations in which that is true but they are quite rare.

Jan 3 '07 #66
Noah Roberts wrote:
Gianni Mariani wrote:
>3. Legacy code can make use of modern templates using the [][] syntax
while converting legacy code to (,) would need major code surgery.

I'd call it rather minor surgery. Any time there is a call to [][]
change to (,)...it's easy.
Making this kind of surgery for a personal preference of (,) over [][]
is IMHO not a good enough reason.
>
>4. array2D[a] is syntactic sugar for a row reference and can be used to
optimize accesses.

Syntatic sugar yes....optimize accesses? How? Frankly it's no
different at all....assuming the compiler is able to do some basic, and
some less basic, optimizations.
operator[] returns a row reference which can be used multiple times and
computation (e.g. looking up a row in a sparse matrix etc) can be
eliminated if it is used multiple times. These kinds of operations may
or may not be optimizable, but there certainly is scope where it can.
Jan 3 '07 #67
Gianni Mariani <gi*******@mariani.wswrote:
Having shown what a proxy class might look like, you will see
that all the arguments in the FAQ (yes - all of them) supporting
(,) have no supportable rationale at all.
I disagree. The fact that you used proxy classes to convert [][]
into (,) shows that all of the arguments in the FAQ are right on
the mark. Hence the reason you chose to use (,) "under the covers".

You misunderstand my intention for writing that class. I made that
proxy class to make a point that anything you can do with (,) you
can do with [][]. That was it's only purpose.
What you successfully demonstrated, regardless of your intention, was
that in order for a class that uses [][] syntax to be as flexable as a
class that uses (,), the former must convert the [][] into (,).

Remember, I asked you to produce a class that could be implemented using
any of row major, column major, and sparse arrays. What you produced was
identical to the solution presented in the FAQ, so I'm not sure what
your beef is at this point, other than the legacy code issue.
Jan 3 '07 #68
Daniel T. wrote:
What you successfully demonstrated, regardless of your intention, was
that in order for a class that uses [][] syntax to be as flexable as a
class that uses (,), the former must convert the [][] into (,).
Logic fallacy. He demonstrated that exists at least one implementation that
does, not that all implementations must do.

--
Salu2
Jan 3 '07 #69

Daniel T. wrote:
Gianni Mariani <gi*******@mariani.wswrote:
Having shown what a proxy class might look like, you will see
that all the arguments in the FAQ (yes - all of them) supporting
(,) have no supportable rationale at all.
>
I disagree. The fact that you used proxy classes to convert [][]
into (,) shows that all of the arguments in the FAQ are right on
the mark. Hence the reason you chose to use (,) "under the covers".
You misunderstand my intention for writing that class. I made that
proxy class to make a point that anything you can do with (,) you
can do with [][]. That was it's only purpose.

What you successfully demonstrated, regardless of your intention, was
that in order for a class that uses [][] syntax to be as flexable as a
class that uses (,), the former must convert the [][] into (,).
Well no, you could also implement it with a complex maze of highly
coupled classes so that the proxy can interact directly with the
internal memory of the main array class. Of course this means you are
writing a different proxy for each implementation instead of one that
can work with any...hense the word "coupled"...but at least you don't
have to have a function interface.

Jan 3 '07 #70
Noah Roberts wrote:
Gianni Mariani wrote:
....
No, that is a way to override [] in two classes and use function
chaining to *mimic* an [][] operator.
And the distinction matters in what sense ?
>
>The use of (,) over [][] is simply a preference. The C++ standard never
mentions (,) as a subscript operator. This news group is about the C++
standard. As a preference, it should remain at most a suggestion, and
not run into a fallous diatribe over the merits of (,) over [][]. That
is the argument we have here.

Nor does the standard mention multi-dimensional arrays or [][]. So, if
we have to stick to the *standard* to get an opinion about which way to
go we have to say that there is just no such thing and leave it at
that.

However, the standard DOES provide tools to implement functional calls
and to override a single subscript operator.
Let's see:

double matrix[4][4];

Are you saying that the code requires some kind of extra "implementation" ?

That's clearly a language supported abstraction for a matrix IMHO.
....
>
Even one line of unnecissary complication is unnecissary complication.
Who said it was unnecessary ?
>
>>More to the point. You shouldn't be implementing a "2d array". You
should be looking for a better abstraction. Once you have that better
abstraction there is no need, nor desire, to advertize that it is a 2d
array. I think the fact that there is no 2d array in the standard, nor
does there seem to be one comming in the forseable future, is quite
telling.
Sure, go for it. Regardless, there is a huge body of code that says
differently.

Not where I'm sitting. I don't care what everyone else's huge body of
code has in it. Frankly, if the whole damn world used [][] for their
matrix abstractions, which it doesn't, it wouldn't have any bearing on
what I choose to use in mine. Nor should you let what someone else is
doing keep you from doing something better unless interaction is a
necessity. I certainly have no need to interact with the whole world
on matrix abstractions.
Just a sec, you make an assertion that there are "better abstractions"
and I make the point that there is a body of code that says differently
then you say you only care about your code. The point I'm making is
that the [][] abstraction is adequate and anything else is a personal
preference and your last paragraph seems to make my point. So are we
violently agreeing here or am I missing somthing ?
>
>>Your insistance on implementing a basic function as a complex set of
operator overloads reminds me of the subscript operator implemented in
some of the legacy code I work on. Implemented [] for a list that
returns the object with the serial id supplied...it's of course linear.
Then base mass "legacy" code on it in a bunch of for loops. Took me
about 4 hours to pull that member out and change all the [] calls to
functional equivilants. Time well spent IMHO...bad design is bad
design and we shouldn't stick to it just in the name of "legacy" unless
we absolutely have to.
If I was your supervisor I would have asked you to revert your change
unless you had a very good technical reason. All you have stated was a
technical preference.

How about not being able to use any other container for a "technical"
preference?

You seem overly concerned with change. I would suggest reading some
books on refactoring and possibly "Working effectively with legacy
code." Such syntatical changes are quite easy to do while being 100%
certain no behavioral change occured.

Let's just leave it as it's a damn good thing you're not my supervisor.
I hate working under micro-managers.
Let me see.

Programmer says: I wanna change the entire code base to use (,).
Supervisor: Why do you want to do that ?
Programmer: Because it's far better ?
Supervisor: Oh, really ! OK, what's so much better ?
Programmer: Because It's a better abstraction.
Supervisor: Sure, sounds great, why is it a better abstraction ?
Programmer: Ummm, because ...... um, it's a personal preference.
Supervisor: Go look at the bug/feature list and find some real bugs to
fix and get back to me.

Anything wrong here ?
>>At any rate, like I said...unless you are in the situation of dealing
with legacy code there is no need to worry about it. So why go to all
the trouble of forcing the [][] issue?
I think I am clearly on the side of C++ in that [][] has been used far
more than (,) and is the default syntax. You need to make an argument to
change it from [][] which is substantiated by more than just personal
preferences.

All you keep saying...and you keep saying it as if it will make it
true...is that your side is stronger and therefor should be the
default. You have yet to show it in any way.
I have:

double matrix[4][4];

....
Jan 3 '07 #71
Gianni Mariani wrote:
>
C++ actually. As I mentioned, operator() is termed a functor and
operator[] is termed a subscript operator.
I've never heard operator() called a functor before (apart from in this
thread). Objects of classes that have operator() as a member, yes, I've
heard /them/ called functors, but not operator() itself. Isn't
operator() usually called the function call operator, or something like
that? A functor is a function object, and operator() ain't a function
object, or an object at all.

As for operator[] being called the subscripting operator, yes, that's
familiar. I'm not sure it expresses an intention for subscripting to
always be done with operator[], though. (Actually, I rather doubt it.)
But I do get the impression that there is a preference for operator[]
to only be used for subscripting and subscripting-like operations (for
the normal reasons of avoiding surprises). I suspect (rather strongly)
that it's called the 'subscripting operator' for historical reasons
(just as C-style subscripting of C-style arrays is in C++ for historical
reasons).

Simon

--
What happens if I mention Leader Kibo in my .signature?
Jan 3 '07 #72

Gianni Mariani wrote:
Noah Roberts wrote:
Gianni Mariani wrote:
3. Legacy code can make use of modern templates using the [][] syntax
while converting legacy code to (,) would need major code surgery.
I'd call it rather minor surgery. Any time there is a call to [][]
change to (,)...it's easy.

Making this kind of surgery for a personal preference of (,) over [][]
is IMHO not a good enough reason.
Well, remaining simple in face of change is IMHO.

If you are suddenly in nead of such an abstraction but are running into
this "legacy code" issue then you are faced with what is known as
"rigidity". Rigidity IS a reason for surgery. It may not be reason
enough given the particulars of any given situation but it is
definately A reason. Seing as the surgery required is rather straight
forward, minimal, and safe the reason NOT to do it would then have to
be that much stronger.

There are situations in which change should be avoided because of
strong reasons against it. Preference of [][] over (,) is IMHO not a
good enough reason.

I also find it rather informative that you have held onto this ONE
requirement of "dealing with a huge legacy code base" as the only
reason to use [][] instead of (,). Of course, I've already given you
this many, many times. IF you have a huge code base that is so rigid
that you can't place an abstraction between it and your memory
layout..better to use [][] than force the (,) issue. So, if I find
myself in such a situation then as always I will weigh the issues and
decide if I should hack or go clean and simple. I do things I disagree
with all the time because of "legacy code" issues when under the crunch
or the change to clean is so astronomical as to be avoided.

Short of any other reason though, and you've yet to bring forth
anything of import besides the legacy issue, I lean toward the simpler
and cleaner approach.
As for your row optimization...if such an optimization is required and
shows up in a profile then it will be dealt with. There are many ways
to go about it. That is again a rather particular situation and
requirement that isn't faced most of the time and as such no reason to
add complexity to the code unless met.

As with all rules, the prefer () over [][] has its rarer counterpoints.

Jan 3 '07 #73
Daniel T. wrote:
Gianni Mariani <gi*******@mariani.wswrote:
....
>
What you successfully demonstrated, regardless of your intention, was
that in order for a class that uses [][] syntax to be as flexable as a
class that uses (,), the former must convert the [][] into (,).
I didn't demonstrate that you "must" do anything. How could you
possibly come to that conclusion ?

What I did demonstrate is that the technical arguments made for the use
of (,) over [][] are false and that using (,) over [][] is a simple
personal preference and there are good, not compelling but good reasons
to stick to [][].
Jan 3 '07 #74
Simon G Best wrote:
I suspect (rather strongly) that it's called the 'subscripting operator'
for historical reasons
And + is called addition operator for historical reasons also, it just have
a longer history. Same for any other operator.

--
Salu2
Jan 3 '07 #75
Gianni Mariani wrote:
>
Making this kind of surgery for a personal preference of (,) over [][]
is IMHO not a good enough reason.
Could you please stop saying "IMHO"? The H is silent.

Simon

--
What happens if I mention Leader Kibo in my .signature?
Jan 3 '07 #76
Noah Roberts wrote:
There are situations in which change should be avoided because of
strong reasons against it. Preference of [][] over (,) is IMHO not a
good enough reason.
There are many situations in which change should be avoided because there
are no reasons to change. In that type of situations, usually those that
wants to change must find some reason, not just to say that there are no
compelling reasons to not to change.

--
Salu2
Jan 3 '07 #77

Gianni Mariani wrote:
double matrix[4][4];
That is what is known as primitive obsession. It is a smell often
causing rigidity. If an there is a requirement that this can no longer
meet then there is already a reason to change things.

The point is that you don't go into legacy code and change things willy
nilly. The abstraction is obviously now necissary because you're
creating it. If you used the above before and now need a real class
then there must be something governing that requirement. The fact that
this previous representation is no longer adiquate is what guides you
into reevaluating the code base that uses it.

So there it is...you HAVE a reason for change. The question is how
much do you change. Usually when making a change you want to make sure
your code is respondent to like changes in the future.

So if we go to your script methodology it might go something more like
this:

Programmer: I need a 2d array abstraction and I want it to look like a
C array of arrays.
Program lead: Why?
Programmer: I don't know. To be more OO.
Program lead: I mean what requirement are you trying to meet that you
want this abstraction?
Programmer: I just thought it would be cool.

Or maybe it went like:

Programmer: I need to represent some new matrices in column major form
now but all our matrix op code assumes C arrays of arrays which are row
major.
Program lead: hmm....we might have to reevaluate the assumptions we
make in our code and possibly provide some better abstractions.

And from there the discussion can go in many different directions.
Deciding to create a basic 2d array class that looks and acts just like
what you have already is but one of the possibilities and in my opinion
not one of the greatest alternatives.

Jan 3 '07 #78

Julián Albo wrote:
Noah Roberts wrote:
There are situations in which change should be avoided because of
strong reasons against it. Preference of [][] over (,) is IMHO not a
good enough reason.

There are many situations in which change should be avoided because there
are no reasons to change. In that type of situations, usually those that
wants to change must find some reason, not just to say that there are no
compelling reasons to not to change.
A new abstraction is required because it is being created. The reason
for change exists. The question is if you want to continue
compatability with an abstraction that obviously isn't enough anymore
or do you want to do some minor editing and try for something a bit
better? The answer to this question will be governed by the
requirements placed on the team, the directions it wishes to head, and
the software in question.

Jan 3 '07 #79
Noah Roberts wrote:
>There are many situations in which change should be avoided because there
are no reasons to change. In that type of situations, usually those that
wants to change must find some reason, not just to say that there are no
compelling reasons to not to change.
A new abstraction is required because it is being created. The reason
for change exists. The question is if you want to continue
compatability with an abstraction that obviously isn't enough anymore
or do you want to do some minor editing and try for something a bit
better?
I don't think that the sintax change in question is a switch to another type
of abstraction. And the "a bit better" part is not a fact, is precisely
what you are supposedly trying to demonstrate.

--
Salu2
Jan 3 '07 #80
Noah Roberts wrote:
Gianni Mariani wrote:
>double matrix[4][4];

That is what is known as primitive obsession. It is a smell often
causing rigidity. If an there is a requirement that this can no longer
meet then there is already a reason to change things.
Don't confuse rigidity with pragmatism.
>
The point is that you don't go into legacy code and change things willy
nilly. The abstraction is obviously now necissary because you're
creating it. If you used the above before and now need a real class
then there must be something governing that requirement. The fact that
this previous representation is no longer adiquate is what guides you
into reevaluating the code base that uses it.

So there it is...you HAVE a reason for change. The question is how
much do you change. Usually when making a change you want to make sure
your code is respondent to like changes in the future.
You still have not explained why array of array syntax is any less
expressive than matrix(,). They not only seem interchangeable in a
programming sense, but also in a theoretical sense. Metaphorically
speaking, instead of taking the horse to the straw, take the straw to
the horse.

So even from a notation/object design perspective [][] is just as
expressive as (,). In some ways, I may be those with the obsession with
(,) over [][] that express rigidity.

....
>
And from there the discussion can go in many different directions.
Deciding to create a basic 2d array class that looks and acts just like
what you have already is but one of the possibilities and in my opinion
not one of the greatest alternatives.
Ah, if you go into a new design, you need design goals. Designs that
require significant deviation from prior practice (requiring learning
curve and wholesale code modifications) with the only motivation being
"personal preference" go down on the ordered list of design solutions or
get eliminated outright because of no practical gain.
Jan 3 '07 #81
Simon G Best wrote:
Gianni Mariani wrote:
>>
Making this kind of surgery for a personal preference of (,) over [][]
is IMHO not a good enough reason.

Could you please stop saying "IMHO"? The H is silent.
I am not rigid, I will change... :-)

Jan 3 '07 #82
Gianni Mariani <gi*******@mariani.wswrote:
Daniel T. wrote:
...

What you successfully demonstrated, regardless of your intention, was
that in order for a class that uses [][] syntax to be as flexable as a
class that uses (,), the former must convert the [][] into (,).

I didn't demonstrate that you "must" do anything. How could you
possibly come to that conclusion ?

What I did demonstrate is that the technical arguments made for the use
of (,) over [][] are false and that using (,) over [][] is a simple
personal preference and there are good, not compelling but good reasons
to stick to [][].
[from the faq]
Here's what this FAQ is really all about: Some people build a
Matrix class that has an operator[] that returns a reference to
an Array object (or perhaps to a raw array, shudder), and that
Array object has an operator[] that returns an element of the
Matrix (e.g., a reference to a double). Thus they access
elements of the matrix using syntax like m[i][j] rather than
syntax like m(i,j).
The above is what I think we have both lost sight of. Peter initially
posted code that did exactly what the above paragraph talks about and I
agreed with the FAQ about the inappropriateness of it. When I asked you
to present an appropriate example that uses the [][] syntax, you
proceeded to present one that is specifically marked as acceptable by
the FAQ.

It is important to note that the FAQ is not comparing two syntaxes, but
two implementations. On the one hand having an op[] that returns a
reference to an array object or a raw array (something I think we can
both agree is a bad idea,) on the other hand not doing so.
Jan 3 '07 #83

Julián Albo wrote:
Noah Roberts wrote:
There are many situations in which change should be avoided because there
are no reasons to change. In that type of situations, usually those that
wants to change must find some reason, not just to say that there are no
compelling reasons to not to change.
A new abstraction is required because it is being created. The reason
for change exists. The question is if you want to continue
compatability with an abstraction that obviously isn't enough anymore
or do you want to do some minor editing and try for something a bit
better?

I don't think that the sintax change in question is a switch to another type
of abstraction. And the "a bit better" part is not a fact, is precisely
what you are supposedly trying to demonstrate.
I'm not talking about the syntax change being a switch to another type
of abstraction. I'm talking about the need for the new abstraction
being created. What is the reason behind needing this 2d array
"class"?

The problem is that "legacy code" as an issue has been brought up in a
vaccuum. We start by saying we want a 2d array class and then someone
says we have to be aware of "legacy code" and thus are required to do
things a certain way. Legacy code doesn't exist nor change in a
vaccuum. If we where to add a 2d array class to legacy code then there
must have been a reason for it. Chances are high that a "2d array
class" would _never_ be added to legacy code in such a manner as has
been posited here. The requirement governing the change is more likely
to be leaning toward a better abstraction.

In other words, a "2d array class" doesn't do enough to warrant its
existance. A matrix abstraction should be at a higher level. If an
array of arrays is no longer adiquate to the task it should be dropped
as an interface. Does this mean that other points won't add up so that
you won't? No...it does mean though that the sytax issue in your
legacy code is not as important as it is being made out to be and
changing from raw arrays to a class is already a rather significant
change. Unless your reason for this change is very basic, localized,
and simple it is going to have wide reaching effects on the code base
already. If it's time for a change then let change happen.

Jan 3 '07 #84
Daniel T. wrote:
Gianni Mariani <gi*******@mariani.wswrote:
....
>
It is important to note that the FAQ is not comparing two syntaxes, but
two implementations. On the one hand having an op[] that returns a
reference to an array object or a raw array (something I think we can
both agree is a bad idea,) on the other hand not doing so.
The FAQ does state many false claims in support of the position of using
(,) over [][]. Read 13.11 more carefully.

Jan 3 '07 #85
Daniel T. wrote:
The above is what I think we have both lost sight of. Peter initially
posted code that did exactly what the above paragraph talks about and I
agreed with the FAQ about the inappropriateness of it.
This clearly shows that this point in the FAQ leads to confusion.

--
Salu2
Jan 3 '07 #86
Noah Roberts wrote:
In other words, a "2d array class" doesn't do enough to warrant its
existance. A matrix abstraction should be at a higher level. If an
array of arrays is no longer adiquate to the task it should be dropped
as an interface.
Don't see the correlation, the implementation and the interface are not
coupled. The use of ( , ) is no more or less abstract than [ ] [ ] just by
the fact that it looks this way to you. This line of argumentation has no
other content than personal preferences about syntax.

--
Salu2
Jan 4 '07 #87

Julián Albo wrote:
The use of ( , ) is no more or less abstract than [ ] [ ] just by
the fact that it looks this way to you.
Since [][] is a chaining of function calls, and not a single call, it
requires an additional object which (,) does not. [][] requires this
extra object while (,) simply does not preclude it. Since it requires
less and imposes no more it is the more abstract solution.

I'll leave it at that and ignore that you completely missed the point.

Jan 4 '07 #88

Gianni Mariani wrote:
You still have not explained why array of array syntax is any less
expressive than matrix(,). They not only seem interchangeable in a
programming sense, but also in a theoretical sense. Metaphorically
speaking, instead of taking the horse to the straw, take the straw to
the horse.
Actually, since [][] is shown to be the more complex answer, no matter
how much or little, it is on you to show that (,) is less expressive.
I never said [][] was less expressive. What I said is that you can't
make [][] as expressive as (,) without additional complexity. Actually
I never said that, but it is what can be implied from what I did say.

I have no idea what horses and straw have to do with it.
>
So even from a notation/object design perspective [][] is just as
expressive as (,). In some ways, I may be those with the obsession with
(,) over [][] that express rigidity.
I can't parse that.

Jan 4 '07 #89

Noah Roberts wrote:
....
I can't parse that.
It may be you that is rigid rather than the others you accuse of
rigidity.

Jan 4 '07 #90
Noah Roberts wrote:
Since [][] is a chaining of function calls, and not a single call, it
requires an additional object which (,) does not. [][] requires this
extra object while (,) simply does not preclude it. Since it requires
less and imposes no more it is the more abstract solution.
This is a detail of the implementation that has no relation with the level
of abstraction.

--
Salu2
Jan 4 '07 #91
Noah Roberts wrote:
Gianni Mariani wrote:
>You still have not explained why array of array syntax is any less
expressive than matrix(,). They not only seem interchangeable in a
programming sense, but also in a theoretical sense. Metaphorically
speaking, instead of taking the horse to the straw, take the straw to
the horse.

Actually, since [][] is shown to be the more complex answer, no matter
how much or little, it is on you to show that (,) is less expressive.
I never said [][] was less expressive. What I said is that you can't
make [][] as expressive as (,) without additional complexity. Actually
I never said that, but it is what can be implied from what I did say.

I have no idea what horses and straw have to do with it.
??????????????????????
Jan 4 '07 #92

Noah Roberts wrote:
Julián Albo wrote:
The use of ( , ) is no more or less abstract than [ ] [ ] just by
the fact that it looks this way to you.

Since [][] is a chaining of function calls, and not a single call, it
requires an additional object which (,) does not. [][] requires this
extra object while (,) simply does not preclude it. Since it requires
less and imposes no more it is the more abstract solution.

I'll leave it at that and ignore that you completely missed the point.
You might be missing the point as well. Who cares about extra objects
? That is the C++ paradigm, there is a very low threshold to creating
new classes. The cost of doing so is either negligible or in this case
zero. Getting hung up about trivial implementation detail does not
produce the best results.

Jan 4 '07 #93

Gianni Mariani wrote:
Noah Roberts wrote:
...
I can't parse that.

It may be you that is rigid rather than the others you accuse of
rigidity.
I never accused anyone of anything.

Critical thinking not your strong suit I see. Oh well...bye then.

Jan 4 '07 #94

Julián Albo wrote:
Noah Roberts wrote:
Since [][] is a chaining of function calls, and not a single call, it
requires an additional object which (,) does not. [][] requires this
extra object while (,) simply does not preclude it. Since it requires
less and imposes no more it is the more abstract solution.

This is a detail of the implementation that has no relation with the level
of abstraction.
The extra object is exposed in the interface. If it has no relation to
the abstraction it has no business in the interface and again (,) is
the better alternative.

Jan 4 '07 #95
Noah Roberts wrote:
>
Julián Albo wrote:
>Noah Roberts wrote:
Since [][] is a chaining of function calls, and not a single call, it
requires an additional object which (,) does not. [][] requires this
extra object while (,) simply does not preclude it. Since it requires
less and imposes no more it is the more abstract solution.

This is a detail of the implementation that has no relation with the
level of abstraction.

The extra object is exposed in the interface. If it has no relation to
the abstraction it has no business in the interface and again (,) is
the better alternative.
But of course row proxies have a relation to the matrix abstraction. What
makes a matrix a 2-dimensional array is that it has rows and columns. Any
interface that does not provide a way of addressing these important
sum-matrices as some type of vector is very low-level.

The matrix class I use has row and column proxies. You can get a row by the
row() method and a column by the column() method. It happens that
operator[] returns a row proxy. The main advantage of the proxy classes is
not that they allow [][] notation but lies in the way they enrich the
interface. For instance, I can say

swap( A.row(i), A.row(j) );

to do a row swap. An elementary row operation can be written as

A.row(i) += factor * A.row(j);

which is much more readable than

row_op( A, i, j, factor );

and it also chains better:

A.row(i) += f*A.row(j) + g*A.row(k);
Best

Kai-Uwe Bux
Jan 4 '07 #96
Gianni Mariani wrote:
Kevin Hall wrote:
Gianni Mariani wrote:
Let's see if we disagree on any of these statements:

a) in C and in C++ matricies have been traditionally supported using
[][] (array of array) syntax. Hence there is a non-trivial body of
code and knowledge that is using [][] as opposed to (,).
No. In C, matrices have been traditionally supported using something
other than [][] -- at least for 'serious' numerical linear algebra
applications. Take a look at CLAPACK, the C interface for BLAS, or any
C implementation for sparse matrices.

I have seen *alot* of gl and OpenGL code that uses [][].
The OpenGL C code that I'm familliar with more often deals with
coordinates of point to define shapes, and here it uses uses (,).
Here's some code from a search on Google:

http://www.eecs.tulane.edu/Terry/Ope...les/Polygons.c
http://www.eecs.tulane.edu/Terry/Ope...L%20Primitives
http://gpwiki.org/index.php/OpenGL:C...e_GLSL_example

But there are OpenGL matrix operations too (of which I am not very
familiar). But even here, the tutorials I see don't use two sets of
brackets -- they only use one:

http://www.opengl.org/resources/faq/...formations.htm (see
9.130)
http://lists.apple.com/archives/mac-.../msg00036.html (the
4x4 matrix 'm' is specified as a 16-element array)

This link is especially interesting:

http://72.14.253.104/search?q=cache:...s&ct=clnk&cd=8

A snippet says:
"Warning about declaring matrices in C
matrix m[4][4] can be accesses as m[ i ] [ j ], but this accesses
the ith column and the jth row of the OpenGL transformation matrix

Because C convention is opposite the OpenGL convention, m[16]
is recommended declaration"

Sure, you can cast an array of arrays of floats to a pointer to float,
but that requires a cast and isn't really what is specified in the
OpenGL interface. Does it work? Well sort of -- opposite to the C
convention. Is it an example that demonstrates the syntactical
superiority of [][] over (,)? Not really. A quick Google search shows
much more code and many more libraries that use the (,) syntax over
[][] for C and C++.

As mentioned, already, for things like sparse matrices in C, it's
impossible to use [][] (it's only possible in C++ and that with proxy
classes and operator overloading). But there are lots and lots of
scientific libraries for both C and C++ that use (,). There's probably
very good reason for it -- like those pointed out in the C++ FAQ Lite.

- Kevin

Jan 4 '07 #97
Z.*****@gmail.com wrote:
Gianni Mariani wrote:
>Kevin Hall wrote:
>>Gianni Mariani wrote:
Let's see if we disagree on any of these statements:

a) in C and in C++ matricies have been traditionally supported using
[][] (array of array) syntax. Hence there is a non-trivial body of
code and knowledge that is using [][] as opposed to (,).
No. In C, matrices have been traditionally supported using something
other than [][] -- at least for 'serious' numerical linear algebra
applications. Take a look at CLAPACK, the C interface for BLAS, or any
C implementation for sparse matrices.
I have seen *alot* of gl and OpenGL code that uses [][].

The OpenGL C code that I'm familliar with more often deals with
coordinates of point to define shapes, and here it uses uses (,).
Here's some code from a search on Google:

http://www.eecs.tulane.edu/Terry/Ope...les/Polygons.c
http://www.eecs.tulane.edu/Terry/Ope...L%20Primitives
http://gpwiki.org/index.php/OpenGL:C...e_GLSL_example
None of those example show any matrix manipulation, also they don't show
any use of 1D vectors other than ones created by passing discrete values
as function parameters. Nice try, wrong examples.

This one is shows examples of using matix
http://www.google.com/codesearch?hl=.../glpuzzle.c#a0

here is another...
http://www.google.com/codesearch?hl=.../matrix44.h#a0

....
>
http://72.14.253.104/search?q=cache:...s&ct=clnk&cd=8

A snippet says:
"Warning about declaring matrices in C
matrix m[4][4] can be accesses as m[ i ] [ j ], but this accesses
the ith column and the jth row of the OpenGL transformation matrix

Because C convention is opposite the OpenGL convention, m[16]
is recommended declaration"
Yes - openGL matrices are transposed depending on how you look at it.
>
Sure, you can cast an array of arrays of floats to a pointer to float,
but that requires a cast and isn't really what is specified in the
OpenGL interface. Does it work?
Yup.

....
>
As mentioned, already, for things like sparse matrices in C, it's
impossible to use [][] (it's only possible in C++ and that with proxy
classes and operator overloading). But there are lots and lots of
scientific libraries for both C and C++ that use (,). There's probably
very good reason for it -- like those pointed out in the C++ FAQ Lite.
a) This is comp.lang.c++ where C++ is topical, if it's impossible in C
it really does not matter as far as this discussion is concerned. (,)
is just as impossible as [][] is in C anyway.

b) most of the opengl code I have seen uses float matrix[4][4]

c) if you read the FAQ, it is sparse on reason and the reasons mentioned
in FAQ 13.11 are debunked in FAQ 13.12. There are no technical reasons
to use (,) over [][].

Sure, if you like (,), knock yourself out but don't spread
misinformation about technical superiority of (,) over [][] because
there simply isn't any. The only cogent arguments of any weight go in
favour of [][] instead of (,).

Jan 4 '07 #98
Gianni Mariani wrote:
Simon G Best wrote:
>>
Could you please stop saying "IMHO"? The H is silent.

I am not rigid, I will change... :-)
Thanks :-)

Simon

--
What happens if I mention Leader Kibo in my .signature?
Jan 4 '07 #99
Noah Roberts wrote:
>
I'm not talking about the syntax change being a switch to another type
of abstraction. I'm talking about the need for the new abstraction
being created. What is the reason behind needing this 2d array
"class"?
How about two-dimensional digital images? (I think that's what the
original poster has in mind. It's certainly something that I need
two-dimensional arrays for.)

There are all sorts of uses for two-dimensional arrays, as matrices
themselves demonstrate. And there are all sorts of useful things we can
do with and do to two-dimensional arrays. (Of course, we could
generalize to N-dimensional arrays, and it might be preferable to do
two-dimensional arrays as N-dimensional arrays where N happens to be
two. But anyway.)
The problem is that "legacy code" as an issue has been brought up in a
vaccuum. We start by saying we want a 2d array class and then someone
says we have to be aware of "legacy code" and thus are required to do
things a certain way. Legacy code doesn't exist nor change in a
vaccuum. If we where to add a 2d array class to legacy code then there
must have been a reason for it. Chances are high that a "2d array
class" would _never_ be added to legacy code in such a manner as has
been posited here. The requirement governing the change is more likely
to be leaning toward a better abstraction.
It wouldn't necessarily be a matter of adding a two-dimensional array
class /to/ old code. It could be that we want to reuse old code with
our new code. Our new code might need a new implementation of
two-dimensional arrays, but we might still want to apply some of that
old code to our new arrays. If that old code assumes [][]-style
interfaces, then there's really no great loss in including such an
interface in our new array class - especially as it doesn't preclude
using a (,)-style interface as well!

As I understand it, one of the strengths of C++ was supposed to be that
old code could be applied to new stuff without having to be changed (as
long as the old code was written appropriately for such reuse). Runtime
polymorphism and templates are both ways of allowing old code to use new
code. If we're taking advantage of such reusability, we may well find
ourselves wanting to apply that old code to our new arrays.

Of course, we /could/ edit the old code, to have it use the interface we
think it ought to use. But what about other code that uses, or is used
by, that old code? Should we really be editing modules B, C and D just
because we think module A ought to use the interface we want for our new
module E? I don't think so.

And, of course, our new code may eventually be old code that someone
else wants to reuse in the future. For all we know, they might want to
use it with other old code that operates on one-dimensional arrays,
using []-style subscripting. They might want to treat our
two-dimensional arrays as one-dimensional arrays of rows. They might
want to treat individual rows as one-dimensional arrays. If we haven't
provided suitable []-style interfaces, it's not going to be quite so
simple (but they can always wrap our two-dimensional array in a suitable
wrapper class with the right interface).

Simon

--
What happens if I mention Leader Kibo in my .signature?
Jan 4 '07 #100

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

2
by: ip4ram | last post by:
I used to work with C and have a set of libraries which allocate multi-dimensional arrays(2 and 3) with single malloc call. data_type **myarray =...
60
by: Peter Olcott | last post by:
I need to know how to get the solution mentioned below to work. The solution is from gbayles Jan 29 2001, 12:50 pm, link is provided below: >...
6
by: hyena | last post by:
Hi, I have a problem regarding passin 2 dimensional array into a function. I have a to pass into function f(), f is called many times and the size of a will change for each call. I am not...
4
by: Gernot Frisch | last post by:
Hi, I need a class, that has a 4 dimensional array (can be 3 dimensional, too) with such an operator: T operator()(int x1, int x2=0, int x3=0, int x4=0); that can be used as:
7
by: nw | last post by:
Hi, We've been having a discussion at work and I'm wondering if anyone here would care to offer an opinion or alternative solution. Aparently in the C programming HPC community it is common to...
0
by: Charles Arthur | last post by:
How do i turn on java script on a villaon, callus and itel keypad mobile phone
0
by: emmanuelkatto | last post by:
Hi All, I am Emmanuel katto from Uganda. I want to ask what challenges you've faced while migrating a website to cloud. Please let me know. Thanks! Emmanuel
1
by: Sonnysonu | last post by:
This is the data of csv file 1 2 3 1 2 3 1 2 3 1 2 3 2 3 2 3 3 the lengths should be different i have to store the data by column-wise with in the specific length. suppose the i have to...
0
by: Hystou | last post by:
There are some requirements for setting up RAID: 1. The motherboard and BIOS support RAID configuration. 2. The motherboard has 2 or more available SATA protocol SSD/HDD slots (including MSATA, M.2...
0
marktang
by: marktang | last post by:
ONU (Optical Network Unit) is one of the key components for providing high-speed Internet services. Its primary function is to act as an endpoint device located at the user's premises. However,...
0
Oralloy
by: Oralloy | last post by:
Hello folks, I am unable to find appropriate documentation on the type promotion of bit-fields when using the generalised comparison operator "<=>". The problem is that using the GNU compilers,...
0
by: Hystou | last post by:
Overview: Windows 11 and 10 have less user interface control over operating system update behaviour than previous versions of Windows. In Windows 11 and 10, there is no way to turn off the Windows...
0
tracyyun
by: tracyyun | last post by:
Dear forum friends, With the development of smart home technology, a variety of wireless communication protocols have appeared on the market, such as Zigbee, Z-Wave, Wi-Fi, Bluetooth, etc. Each...
0
agi2029
by: agi2029 | last post by:
Let's talk about the concept of autonomous AI software engineers and no-code agents. These AIs are designed to manage the entire lifecycle of a software development project—planning, coding, testing,...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.