Live data from Hacker News

Arrays of Arrays (2009)

ericlippert.com

1–10 of 30 posts

Re: Arrays of Arrays (2009)

#3
Over a decade ago I was trying to get the C++ committee to support multidimensional arrays via overloading, so we could have 2D collections. In C++, you can overload "operator[]". But it can't take more than one argument. Why?

Because of the C "comma operator". In C, the comma operator evaluates both operands and discards the first result. It's an ancient hack used mostly with preprocessor defines.

In C and C++,

    foo(a,b)
is a call with two arguments. But

    foo[a,b]
invokes the comma operator and presents one value to "[]" You have to dig through the C++ specification to find this.

So I asked the question, could anyone find an example of the comma operator used in C or C++ inside square brackets in any production code. I couldn't. I got someone at IBM Almaden to search IBM's code archive and they couldn't. But there was the concern that somewhere, someone had used that misfeature for something.

So, no 2D array syntax for you.

Re: Arrays of Arrays (2009)

#5
post #3

Over a decade ago I was trying to get the C++ committee to support multidimensional arrays via overloading, so we could have 2D collections. In C++, you can overload "operator[]". But it can't take more than one argument. Why? Because of the C "comma operator". In C, the comma operator evaluates both operands and discards the first result. It's an ancient hack used mostly with preprocessor defines. In C and C++, foo(…

Imo foo[x][y] is better for many reasons:

- compiler can break it apart so foo[x] is evaluated once for many ys just like any other function

- you can make types that are unaware of their rank eg vector doesn’t know if it’s a 1D vector of int or a 2D vector of vectors

- “seamlessly” handles jagged arrays

Re: Arrays of Arrays (2009)

#6
post #5
post #3

Over a decade ago I was trying to get the C++ committee to support multidimensional arrays via overloading, so we could have 2D collections. In C++, you can overload "operator[]". But it can't take more than one argument. Why? Because of the C "comma operator". In C, the comma operator evaluates both operands and discards the first result. It's an ancient hack used mostly with preprocessor defines. In C and C++, foo(…

Imo foo[x][y] is better for many reasons: - compiler can break it apart so foo[x] is evaluated once for many ys just like any other function - you can make types that are unaware of their rank eg vector doesn’t know if it’s a 1D vector of int or a 2D vector of vectors - “seamlessly” handles jagged arrays

Which reminds me of an insightful observation that the array indexing operator [] and the function call operator () are basically doing the same thing: evaluating a function and returning a value.

So what you've just described is basically Currying, or partial function evaluation. It's a bit like defining "al(i)" as array lookup for an index 'i' instead of "[i]". Then the following are equivalent:

    something[i][j]
    something.al(i).al(j)
What people also want are:

    something[i,j]
    something.al(i,j)
In languages like Haskell, every function can always be evaluated argument-by-argument, with no special effort by the programmer. The compiler takes care of generating the code for the various intermediate call forms. In languages like C++, it would be a significant hassle to create all of the various partially-evaluated wrapper types.

Re: Arrays of Arrays (2009)

#7
This reasoning seems to me similar to how declaring a pointer in e.g. C works: many beginners write

    int* a, b;
And think that this constructs two pointers-to-integer. In fact, it constructs one pointer and one plain integer. A better (equivalent) way to write it is

    int *a, b;
You're not declaring variables of type

   int*
You're saying that b is an int and

    *a 
Is an int, where the asterisk means "the dereferenced a"!

Re: Arrays of Arrays (2009)

#8
post #3

Over a decade ago I was trying to get the C++ committee to support multidimensional arrays via overloading, so we could have 2D collections. In C++, you can overload "operator[]". But it can't take more than one argument. Why? Because of the C "comma operator". In C, the comma operator evaluates both operands and discards the first result. It's an ancient hack used mostly with preprocessor defines. In C and C++, foo(…

> Over a decade ago I was trying to get the C++ committee to support multidimensional arrays via overloading, so we could have 2D collections.

You might've asked operator[] to take multiple arguments separated by semicolon, so:

    foo[a;b]
which is at least unambiguous. Maybe it would have been less offensive.

> So I asked the question, could anyone find an example of the comma operator used in C or C++ inside square brackets in any production code.

If you're still referring to operator overloading, there's things like Boost.Assign and Boost.Phoenix, but if you're referring to use as a sequence operator, i.e. where a[b,c] could potentially be b,a[c] except for the different sequence point, it doesn't surprise me you had a hard time finding an example: I've only ever seen people like Arthur do that (people writing APL in C)

Re: Arrays of Arrays (2009)

#9
post #3

Over a decade ago I was trying to get the C++ committee to support multidimensional arrays via overloading, so we could have 2D collections. In C++, you can overload "operator[]". But it can't take more than one argument. Why? Because of the C "comma operator". In C, the comma operator evaluates both operands and discards the first result. It's an ancient hack used mostly with preprocessor defines. In C and C++, foo(…

With C++20, use of comma expressions as second argument of a subscript operator got deprecated.

Re: Arrays of Arrays (2009)

#10
post #5
post #3

Over a decade ago I was trying to get the C++ committee to support multidimensional arrays via overloading, so we could have 2D collections. In C++, you can overload "operator[]". But it can't take more than one argument. Why? Because of the C "comma operator". In C, the comma operator evaluates both operands and discards the first result. It's an ancient hack used mostly with preprocessor defines. In C and C++, foo(…

Imo foo[x][y] is better for many reasons: - compiler can break it apart so foo[x] is evaluated once for many ys just like any other function - you can make types that are unaware of their rank eg vector doesn’t know if it’s a 1D vector of int or a 2D vector of vectors - “seamlessly” handles jagged arrays

It's semantically the same and the compiler should know that. But I do agree [][] makes more sense. The jth index of the ith array.
Post reply on HN