<p>A lot of languages use square brackets for array indexing, and round brackets (also known as parentheses) for function calls. For example, in C:</p>
<pre><code>int array[10];
void foo(int x);

int x = array[3]; // array indexing
foo(42);          // function call
</code></pre>
<p>However, there is almost never a case where you could use round brackets after an array or square brackets after a function, for example:</p>
<pre><code>int x = array(3); // compile error
foo[42];          // compile error
</code></pre>
<p>Even in languages where you can overload both the array indexing and function call operators, it seems very rare to ever do that. So then it seems like this difference in syntax is unnecessary. And indeed, in some languages parentheses are used for both, like in most dialects of BASIC.</p>
<p>Why have square brackets historically been used for array indexing? What are the pros and cons of using a different notation than the one used for function calls?</p>

<syntax><language-design>
Why do many languages use square brackets for array indexing?
CC BY-SA 4.0
2023-09-23T14:15:09.067Z
And even from the abstract mathematical point of view, arrays are just functions with a peculiar domain, so ... 
Then again, the square bracket characters were available on keyboards, so why not use them for some special purpose, like we do with almost every (ASCII) symbol? After all, parens are already used for multiple purposes: grouping and function calls. (But if you really love parentheses, try LISP)
Hagen von Eitzen
CC BY-SA 4.0
2023-09-23T14:32:38.457Z
I think technically LISP doesn't have arrays... but it compensates for that with too many parentheses ;). Most BASIC dialects also use parentheses instead of square brackets for array indexing.
G. Sliepen
CC BY-SA 4.0
2023-09-23T15:46:53.320Z
Python allows overriding both round-brackets postfix (the `__call__` method) and square-brackets postfix (the `__getitem__` and `__setitem__` methods). It would be very unusual for a Python class to override both without giving them different behaviour.
kaya3
CC BY-SA 4.0
2023-09-23T20:00:29.707Z
"However, it seems extremely rare in languages where you can overload operators to have overloaded both the square bracket operator and the round bracket operator, and even if they do, it is even rarer that these would then do different things." - I don't understand the claim. C++ and Python both allow both overloads; overloading `[]` is normally used for an operation that is in some sense analogous to indexing; overloading `()` is normally used for an operation that is in some sense analogous to calling; and a type that provided both would ordinarily definitely not make them the same.
Karl Knechtel
CC BY-SA 4.0
2023-09-23T20:02:15.410Z
Related if not duplicate cross-site: https://softwareengineering.stackexchange.com/questions/368256
Karl Knechtel
CC BY-SA 4.0
2023-09-23T20:53:55.493Z
@KarlKnechtel That's exactly my point: it almost makes no sense to do both, so it seems superfluous to have both `[]` and `()`.
G. Sliepen
CC BY-SA 4.0
2023-09-23T21:02:52.613Z
You mean, there should only be one syntax *simply because practical types wouldn't need to support both operations*? I don't think that's a compelling reason at all. Semantics matter. As elegant as LISP is, programmers find it practical and useful to model certain types as storage and certain other types as procedural.
Karl Knechtel
CC BY-SA 4.0
2023-09-23T21:21:38.030Z
@KarlKnechtel No, there should be only one syntax because indexing is just a special case of evaluating a function.
xigoi
CC BY-SA 4.0
2023-09-23T21:31:55.540Z
@xigoi I don't think most people see it that way. It's a rather abstract mental model; and it would seem to apply as well to other operators, anyway.
Karl Knechtel
CC BY-SA 4.0
2023-09-23T21:33:44.173Z
The edited question seems quite different to the original and it's unclear that any of the existing answers are still applicable to it. Is what you're looking for the history of this syntax, instances of languages that treat arrays as functions/overload the call syntax, explanations for why they should(n't) be separated, for why this *particular* syntax is used, for which alternatives have been or could be used? It'd be good to align the title with the version you're aiming at (though possibly asking a *new* question with that and leaving the existing answers be would be better if different).
Michael Homer
CC BY-SA 4.0
2023-09-25T17:48:44.133Z
@G.Sliepen The original Lisp didn't have arrays, but dialects at least since MacLisp did. And in MacLisp array access used function-call syntax -- the array variable was put in the function position of an expression: `(somearray 1 2)`. Common Lisp replaced this with an explicit `AREF` function: `(aref somearray 1 2)`
Barmar
CC BY-SA 4.0
2023-09-25T18:59:04.847Z
*"there should be only one syntax because indexing is just a special case of evaluating a function"* ─ every expression is a special case of evaluating a function. This logic leads to very uniform syntaxes like `+(x, y)` or `(+ x y)`, but a syntax being more uniform does not tend to make it more understandable.
kaya3
CC BY-SA 4.0
2023-09-25T19:28:07.883Z
“What are the pros and cons of …” is generally not an on-topic question; questions about language design choices need to provide objective criteria for measuring answers. This question is also asking two separate and not-really-related questions now, so it needs more focus to be answerable. It has also changed the question out underneath existing answers in the edit; please don’t do that. The bounty now seems to be about the part of the question that is definitively not on-topic per the [help/on-topic]. I can remove the bounty if you want. The question should likely be reverted and/or closed.
Michael Homer
CC BY-SA 4.0
2023-09-25T21:04:09.800Z
The fact that we have many such open pros-cons questions is a historical artifact and should not be emulated in newer posts
Seggan
CC BY-SA 4.0
2023-09-25T22:22:59.437Z
I'm fine with whatever the moderators decide. I did change the question though because the comments told me it was not clear enough. I'm not sure how to rephrase it in a better way; for designing a new language it would be nice to know all the pros and cons of a certain choice, and knowing the reason why past languages made certain decisions also contributes to that.
G. Sliepen
CC BY-SA 4.0
2023-09-27T11:06:37.853Z
The question appears to make the assumption "a compiler would be able to work even if the same symbol was used for array indexing and function calling, therefore we don't need different symbols". But programming languages need to be easily used both by compilers ***and*** humans. Using different symbols for different operations actually makes the language easier to program in, read, debug and maintain. If I accidentally confuse two variables, I want the compiler to immediately tell me the symbols are wrong, rather than silently interpret the symbols differently than what I had in mind.
Stef
CC BY-SA 4.0
2023-09-27T16:38:09.830Z
@Stef There could perhaps be situations where having the same syntax result in parsing ambiguities (like [most vexing parse](https://en.wikipedia.org/wiki/Most_vexing_parse), or the closing angle bracket issue with nested templates in C++), or maybe prevent some other grammar features. But I'm looking for concrete examples.
G. Sliepen
CC BY-SA 4.0
2024-04-04T13:41:50.830Z
"Why do languages use [...]"? Because C did it.
CoffeeTableEspresso
CC BY-SA 4.0
2024-04-04T13:42:01.400Z
"Why did C do it?" Because C was based on the earlier B language, which didn't really have types (meaning it had to be clear from operations only what you were doing). This is also the reason for many other design choices in C, such as `'...'` for characters and having both `.` and `->`.
CoffeeTableEspresso
<h3>Historic usage</h3>
<p>The use of square brackets as array indexing goes back at least to the <a href="https://www.thinkage.ca/gcos/expl/b/manu/manu.html#Section3_3" rel="nofollow noreferrer">B language</a> (circa 1969).</p>
<p>Here, vector syntax is used to replace <em>a lot</em> of typing and constant forwarding, as B's vectors are akin to C's arrays. They are basically convenient syntax over pointer syntax. For example:</p>
<pre class="lang-c prettyprint-override"><code>vec[10] = 2;
</code></pre>
<p>Is the same as:</p>
<pre class="lang-c prettyprint-override"><code>(&amp;vec)[10] = 2;
</code></pre>
<p>That still uses bracket, and without, it is syntax for</p>
<pre class="lang-c prettyprint-override"><code>(&amp;(vec+sizeof(vec)*10) = 2;
</code></pre>
<p>And <code>sizeof(vec)</code> is really a constant defined by compiler:</p>
<pre class="lang-c prettyprint-override"><code>(&amp;(vec+VEC_STRIDE*10) = 2;
</code></pre>
<p>From <code>a[b]</code> to <code>(&amp;(a+K*b))</code> or <code>(&amp;(a+sizeof(a)*b))</code>, there is a lot of typing and semantic machinery to express.</p>
<p>Note that the last expression already has (a lot of) parenthesis, so another grouping was chosen to represent, replace and express this concise syntax.</p>
<h3>Using parentheses as array access</h3>
<p>To use parentheses as array indexing syntax would make parenthesis pairs a context sensitive token. Consider:</p>
<pre class="lang-c prettyprint-override"><code>a(b)(c);
</code></pre>
<p>This is:</p>
<ul>
<li>an array called <code>a</code>, indexed by <code>b</code>, that returns an array, then indexed by <code>c</code>;</li>
<li>an array called <code>a</code>, indexed by <code>b</code>, that returns an function pointer, then invoked with <code>c</code>;</li>
<li>an function called <code>a</code>, invoked with <code>b</code>, that returns an array, then indexed by <code>c</code>;</li>
<li>an function called <code>a</code>, invoked with <code>b</code>, that returns an function pointer, then invoked with by <code>c</code>;</li>
</ul>
<p>That is, using the <em>first</em> parenthesis pair after an array as array indexing syntax.</p>
<p>This special casing for arrays may be orthogonal enough to make a regular parsing, but I suspect this will put a lot of pressure on semantic assignment of tokens to cause some performance impact.</p>
<p>This is not prohibitive, however, since other languages already have to examine parenthesis pairs in a lot of contexts.</p>
<p>The problem is that <a href="https://softwareengineering.stackexchange.com/a/368353/346580">humans also will be impacted</a>, as array indexing and function calling now use the same syntax, as illustrated in the above example.</p>

CC BY-SA 4.0
2023-09-23T14:46:40.433Z
2023-09-26T16:20:50.383Z
2023-09-26T16:20:50.383Z
André L F S Bacci
CC BY-SA 4.0
2023-09-23T21:19:37.157Z
I was thinking about parentheses for array indexing in this way: `vec(10) = 2; vec(2) = vec(1); vec(10)(p);` This would still allow arrays to have builtin members.
G. Sliepen
CC BY-SA 4.0
2023-09-25T10:16:42.963Z
Is `From a[b] to (&(a+sizeof(a)*n)` meant to be `From a[b] to (&(a+sizeof(a)*b)` ? I tried editing the answer but it wouldn't allow me to make an edit of `1` character.
Tom Tsagkatos
<p><a href="https://en.wikipedia.org/wiki/ALGOL_58" rel="nofollow noreferrer">ALGOL 58</a> used square brackets for array declarations and accesses (see e.g. <a href="https://datatron.blogspot.com/2018/07/algol-58-international-algebraic.html" rel="nofollow noreferrer">here</a>), so this goes at least as far back as 1958 in programming language syntax.</p>
<p>According to <a href="https://softwareengineering.stackexchange.com/a/368353">this answer</a> to a similar question on Software Engineering SE, earlier languages including FORTRAN did not use square brackets, because they were designed for use on IBM keyboards which didn't have them; but once square brackets became available it would have been a no-brainer to use them for <em>something</em>, since overloading the meaning of parentheses for too many different things would have made code harder to understand.</p>
<p>The question proposes that using function-call syntax for array accesses would be simpler. But this line of argument taken to its logical conclusion would lead to <em>all</em> expressions being written as function calls; why have <code>x + y</code> as a special syntax for adding numbers, when you can use function call syntax like <code>add(x, y)</code>? Well, there are some languages with such uniform syntax (particularly Lisp), but most of us like being able to more clearly tell apart different kinds of expressions.</p>
<p>Particularly for array accesses, having a different syntax makes sense because an array access is also an <a href="https://en.wikipedia.org/wiki/Value_(computer_science)#lrvalue" rel="nofollow noreferrer">l-value</a>, i.e. it is allowed to occur on the left side of an assignment like <code>a[i] = x</code>; and ALGOL 58 didn't have <em>that</em> many kinds of expressions, so there was plenty of syntax space to go around, and it's not obvious what else square brackets might have been used for if not array accesses.</p>
<p>That said, I suspect this notation predates programming language syntax. In mathematical notation it's common to use subscripts (e.g. <span class="math-container">$a_1, a_2, a_3, \ldots$</span>) for sequence members, and indeed sometimes the postfix &quot;square brackets&quot; operator for array access is referred to as a &quot;subscript&quot;. But in some media it is not possible to print actual subscripts, so an alternative would be needed. I'm not able to find an example where square brackets were used for this purpose before 1958, but I'd be surprised if there were no examples.</p>

CC BY-SA 4.0
2023-09-23T16:57:55.213Z
2024-06-11T00:20:23.017Z
2024-06-11T00:20:23.017Z
kaya3
# Why do many languages use square brackets for array indexing?
Posted by: username_0 on 2023-09-23
A lot of languages use square brackets for array indexing, and round brackets (also known as parentheses) for function calls. For example, in C:
int array[10];
void foo(int x);

int x = array[3]; // array indexing
foo(42);          // function call

However, there is almost never a case where you could use round brackets after an array or square brackets after a function, for example:
int x = array(3); // compile error
foo[42];          // compile error

Even in languages where you can overload both the array indexing and function call operators, it seems very rare to ever do that. So then it seems like this difference in syntax is unnecessary. And indeed, in some languages parentheses are used for both, like in most dialects of BASIC.
Why have square brackets historically been used for array indexing? What are the pros and cons of using a different notation than the one used for function calls?
**Tags:** syntax language-design
> **Comments:**
> **username_1**: And even from the abstract mathematical point of view, arrays are just functions with a peculiar domain, so ... 
Then again, the square bracket characters were available on keyboards, so why not use them for some special purpose, like we do with almost every (ASCII) symbol? After all, parens are already used for multiple purposes: grouping and function calls. (But if you really love parentheses, try LISP)  
> **username_0**: I think technically LISP doesn't have arrays... but it compensates for that with too many parentheses ;). Most BASIC dialects also use parentheses instead of square brackets for array indexing.  
> **username_2**: Python allows overriding both round-brackets postfix (the `__call__` method) and square-brackets postfix (the `__getitem__` and `__setitem__` methods). It would be very unusual for a Python class to override both without giving them different behaviour.  
> **username_3**: "However, it seems extremely rare in languages where you can overload operators to have overloaded both the square bracket operator and the round bracket operator, and even if they do, it is even rarer that these would then do different things." - I don't understand the claim. C++ and Python both allow both overloads; overloading `[]` is normally used for an operation that is in some sense analogous to indexing; overloading `()` is normally used for an operation that is in some sense analogous to calling; and a type that provided both would ordinarily definitely not make them the same.  
> **username_3**: Related if not duplicate cross-site: https://softwareengineering.stackexchange.com/questions/368256  
> **username_0**: @KarlKnechtel That's exactly my point: it almost makes no sense to do both, so it seems superfluous to have both `[]` and `()`.  
> **username_3**: You mean, there should only be one syntax *simply because practical types wouldn't need to support both operations*? I don't think that's a compelling reason at all. Semantics matter. As elegant as LISP is, programmers find it practical and useful to model certain types as storage and certain other types as procedural.  
> **username_4**: @KarlKnechtel No, there should be only one syntax because indexing is just a special case of evaluating a function.  
> **username_3**: @xigoi I don't think most people see it that way. It's a rather abstract mental model; and it would seem to apply as well to other operators, anyway.  
> **username_5**: The edited question seems quite different to the original and it's unclear that any of the existing answers are still applicable to it. Is what you're looking for the history of this syntax, instances of languages that treat arrays as functions/overload the call syntax, explanations for why they should(n't) be separated, for why this *particular* syntax is used, for which alternatives have been or could be used? It'd be good to align the title with the version you're aiming at (though possibly asking a *new* question with that and leaving the existing answers be would be better if different).  
> **username_6**: @G.Sliepen The original Lisp didn't have arrays, but dialects at least since MacLisp did. And in MacLisp array access used function-call syntax -- the array variable was put in the function position of an expression: `(somearray 1 2)`. Common Lisp replaced this with an explicit `AREF` function: `(aref somearray 1 2)`  
> **username_2**: *"there should be only one syntax because indexing is just a special case of evaluating a function"* ─ every expression is a special case of evaluating a function. This logic leads to very uniform syntaxes like `+(x, y)` or `(+ x y)`, but a syntax being more uniform does not tend to make it more understandable.  
> **username_5**: “What are the pros and cons of …” is generally not an on-topic question; questions about language design choices need to provide objective criteria for measuring answers. This question is also asking two separate and not-really-related questions now, so it needs more focus to be answerable. It has also changed the question out underneath existing answers in the edit; please don’t do that. The bounty now seems to be about the part of the question that is definitively not on-topic per the [help/on-topic]. I can remove the bounty if you want. The question should likely be reverted and/or closed.  
> **username_7**: The fact that we have many such open pros-cons questions is a historical artifact and should not be emulated in newer posts  
> **username_0**: I'm fine with whatever the moderators decide. I did change the question though because the comments told me it was not clear enough. I'm not sure how to rephrase it in a better way; for designing a new language it would be nice to know all the pros and cons of a certain choice, and knowing the reason why past languages made certain decisions also contributes to that.  
> **username_8**: The question appears to make the assumption "a compiler would be able to work even if the same symbol was used for array indexing and function calling, therefore we don't need different symbols". But programming languages need to be easily used both by compilers ***and*** humans. Using different symbols for different operations actually makes the language easier to program in, read, debug and maintain. If I accidentally confuse two variables, I want the compiler to immediately tell me the symbols are wrong, rather than silently interpret the symbols differently than what I had in mind.  
> **username_0**: @Stef There could perhaps be situations where having the same syntax result in parsing ambiguities (like [most vexing parse](https://en.wikipedia.org/wiki/Most_vexing_parse), or the closing angle bracket issue with nested templates in C++), or maybe prevent some other grammar features. But I'm looking for concrete examples.  
> **username_9**: "Why do languages use [...]"? Because C did it.  
> **username_9**: "Why did C do it?" Because C was based on the earlier B language, which didn't really have types (meaning it had to be clear from operations only what you were doing). This is also the reason for many other design choices in C, such as `'...'` for characters and having both `.` and `->`.  
---
## 2 answers
### Answer by username_2 on 2023-09-23. Score: 17
[ALGOL 58](https://en.wikipedia.org/wiki/ALGOL_58) used square brackets for array declarations and accesses (see e.g. [here](https://datatron.blogspot.com/2018/07/algol-58-international-algebraic.html)), so this goes at least as far back as 1958 in programming language syntax.

According to [this answer](https://softwareengineering.stackexchange.com/a/368353) to a similar question on Software Engineering SE, earlier languages including FORTRAN did not use square brackets, because they were designed for use on IBM keyboards which didn't have them; but once square brackets became available it would have been a no-brainer to use them for *something*, since overloading the meaning of parentheses for too many different things would have made code harder to understand.

The question proposes that using function-call syntax for array accesses would be simpler. But this line of argument taken to its logical conclusion would lead to *all* expressions being written as function calls; why have `x + y` as a special syntax for adding numbers, when you can use function call syntax like `add(x, y)`? Well, there are some languages with such uniform syntax (particularly Lisp), but most of us like being able to more clearly tell apart different kinds of expressions.

Particularly for array accesses, having a different syntax makes sense because an array access is also an [l-value](https://en.wikipedia.org/wiki/Value_(computer_science)#lrvalue), i.e. it is allowed to occur on the left side of an assignment like `a[i] = x`; and ALGOL 58 didn't have *that* many kinds of expressions, so there was plenty of syntax space to go around, and it's not obvious what else square brackets might have been used for if not array accesses.

That said, I suspect this notation predates programming language syntax. In mathematical notation it's common to use subscripts (e.g. $a\_1, a\_2, a\_3, \ldots$) for sequence members, and indeed sometimes the postfix "square brackets" operator for array access is referred to as a "subscript". But in some media it is not possible to print actual subscripts, so an alternative would be needed. I'm not able to find an example where square brackets were used for this purpose before 1958, but I'd be surprised if there were no examples.
---
### Answer by username_10 on 2023-09-23. Score: 2
Historic usage
The use of square brackets as array indexing goes back at least to the B language (circa 1969).
Here, vector syntax is used to replace a lot of typing and constant forwarding, as B's vectors are akin to C's arrays. They are basically convenient syntax over pointer syntax. For example:
vec[10] = 2;

Is the same as:
(&vec)[10] = 2;

That still uses bracket, and without, it is syntax for
(&(vec+sizeof(vec)*10) = 2;

And sizeof(vec) is really a constant defined by compiler:
(&(vec+VEC_STRIDE*10) = 2;

From a[b] to (&(a+K*b)) or (&(a+sizeof(a)*b)), there is a lot of typing and semantic machinery to express.
Note that the last expression already has (a lot of) parenthesis, so another grouping was chosen to represent, replace and express this concise syntax.
Using parentheses as array access
To use parentheses as array indexing syntax would make parenthesis pairs a context sensitive token. Consider:
a(b)(c);

This is:

an array called a, indexed by b, that returns an array, then indexed by c;
an array called a, indexed by b, that returns an function pointer, then invoked with c;
an function called a, invoked with b, that returns an array, then indexed by c;
an function called a, invoked with b, that returns an function pointer, then invoked with by c;

That is, using the first parenthesis pair after an array as array indexing syntax.
This special casing for arrays may be orthogonal enough to make a regular parsing, but I suspect this will put a lot of pressure on semantic assignment of tokens to cause some performance impact.
This is not prohibitive, however, since other languages already have to examine parenthesis pairs in a lot of contexts.
The problem is that humans also will be impacted, as array indexing and function calling now use the same syntax, as illustrated in the above example.
> **Comments:**
> **username_0** (2023-09-23): I was thinking about parentheses for array indexing in this way: `vec(10) = 2; vec(2) = vec(1); vec(10)(p);` This would still allow arrays to have builtin members.  
> **username_11** (2023-09-25): Is `From a[b] to (&(a+sizeof(a)*n)` meant to be `From a[b] to (&(a+sizeof(a)*b)` ? I tried editing the answer but it wouldn't allow me to make an edit of `1` character.  
---
