9

When looking at Smalltalk syntax definitions I noticed a few different notations for arrays:

#[] "ByteArray"
#() "Literal Array"
{}  "Array"
  • Why are there different array types? In other programming languages I know there's only one kind of array independent of the stored type.
  • When to choose which kind?
  • Why do literal array and array have a different notation but same class?
f4lco
  • 3,728
  • 5
  • 28
  • 53
  • Note that the `#[]` syntax is not supported in every Smalltalk dialect. – Tobias Jan 28 '13 at 10:37
  • Nor is the `{}` syntax supported in all Smalltalks. – Travis Griggs Jan 29 '13 at 21:21
  • Smalltalk is not the only language either. Python supports literal lists (e.g. `['one', 'two', 'three']`) as well as literal byte arrays (e.g. `b'\x60\x0D\xF0\x0D'`) – Travis Griggs Jan 29 '13 at 21:25
  • The `{ }` was created in Squeak Smalltalk, and is most dependable in Squeak and its derivatives, Pharo and Cuis. It is not available in, for example, Dolphin Smalltalk. – Euan M Nov 13 '15 at 00:39

2 Answers2

17

There's a bit of terminological confusion in Michael's answer, #() is a literal array whereas {} is not. A literal array is the one created by the compiler and can contain any other literal value (including other literal arrays) so the following is a valid literal array:

#(1 #blah nil ('hello' 3.14 true) $c [1 2 3])

On the other hand {} is merely a syntactic sugar for runtime array creation, so { 1+2. #a. anObject} is equivalent to:

(Array new: 3) at: 1 put: 1 + 2; at: 2 put: #a; at: 3 put: anObject; yourself
Leo
  • 37,640
  • 8
  • 75
  • 100
Martin Kobetic
  • 221
  • 1
  • 2
11

Here's a little walkthrough:

Firstly, we can find out the types resp. classes of the resulting objects:

  • #[] class results in ByteArray
  • #() class results in Array
  • {} class also results in Array

So apparently the latter two produce Arrays while the first produces a ByteArray. ByteArrays are what you would expect -- fixed sized arrays of bytes.

Now we'll have to figure out the difference between #() and {}. Try evaluating #(a b c), it results in #(#a #b #c); however when you try to evaluate {a b c}, it doesn't work (because a is not defined). The working version would be {#a. #b. #c}, which also results in #(#a #b #c).

The difference between #() and {} is, that the first takes a list of Symbol names separated by spaces. You're also allowed to omit the # signs. Using this notation you can only create Arrays that contain Symbols. The second version is the generic Array literal. It takes any expressions, separated by . (dots). You can even write things like {1+2. anyObject complexOperation}.

This could lead you to always using the {} notation. However, there are some things to keep in mind: The moment of object creation differs: While #() Arrays are created during compilation, {} Arrays are created during execution. Thus when you run code with an #() expression, it will also return the same Array, while {} only returns equal Arrays (as long as you are using equal contents). Also, AFAIK the {} is not necessarily portable because it's not part of the ST-80 standard.

codefrau
  • 4,583
  • 17
  • 17
Michael
  • 8,920
  • 3
  • 38
  • 56
  • In other words the last paragraph says that using `{}` carries a potential performance hit. – Frank Shearar Jan 27 '13 at 14:58
  • Yes. Also see Martin Kobetic's answer which corrects a few inaccuracies in mine. – Michael Jan 29 '13 at 09:07
  • 1
    in other words, a #() array is literal created at compile time , and never changes, while {} syntax creates a new Array instance at run time and fills its elements by evaluating code for each element.So it is actually a syntax sugar for: { 1. 2. 3. } <=> Array with: 1 with: 2 with: 3. – Igor Stasenko Feb 07 '13 at 16:10