December 11, 2019

The Protocol of Symbol

 

Symbol is a subclass of String and is an abstract class with, like String, two concrete subclasses ByteSymbol and TwoByteSymbol. Again the storage set aside for ASCII or 'exotic' characters dictates the class of the symbol object and once a symbol is written LearningWorks handles this for us.

Here are a few rules about creating symbols.

A symbol is created by either preceding a literal string with a # as in

#'Into the Mystic'

or, if no spaces are present and the first character is non-alphanumeric. Here are some examples to illustrate the correct, and incorrect, syntax for Smalltalk symbols.

#CousinDupree            "correct syntax"
#Cousin Dupree#          "incorrect syntax"
200Motels                "incorrect syntax"
#200 Motels              "incorrect syntax"
#'200Motels'             "correct syntax"
#'200 Motels'            "correct syntax"
#RevolutionNo.9          "correct syntax"
#RevolutionNo. 9         "incorrect syntax"

Symbols are unique. Smalltalk uses the Symbol class to store, in a table, all the symbols that are created. If you write one that isn't stored, Smalltalk will, after checking this table, add the new symbol. To answer with this table, simply evaluate

Symbol table

In my Learning Works, evaluating

Symbol table size

returned 1777, with each of these elements referencing an instant of a class WeakArray. These arrays contained references to symbols and in one I found #baconArray. Smalltalk had added this to the table when I created the variable fom an earlier exercise.

To confirm a symbol's uniqueness, use the == message selector

#baconArray == #baconArray     "answers true"

Compare this with

'baconArray' == 'baconArray'    "answers false"

Interestingly

#baconArray == #      baconArray     "answers true"

spacing between # and the first character is ignored.

Symbols are used as keys in dictionaries. Finding a symbol is quicker than searching for a string. The includesKey: method in Dictionary results in each key being sent the message =. If the key is a symbol, the = method being implemented is:

= anObject
   "Answer whether the receiver and the argument are the same object
    (have the same object pointer)."
   ^self == anObject

The test becomes one of identity rather than equality. This test for object identity is implemented as a system primitive. The memory address of the receiver and the argument are compared and it is this process that guarantees speed. This contrasts with a key written as a string. = as implemented in String requires a longer process of checking.

= aString
   "Answer whether the argument is a string, and is not a symbol, and
    the receiver's size is the same as aString's size, and each of the
    receiver's elements equal the corresponding element of aString"
   | size |
   aString isString ifFalse: [^false].
   aString isSymbol ifTrue: [^false].
   (size := self size) = aString size ifFalse: [^false].
   1 to: size do: [:index | (self at: index) = (aString at: index)
                               ifFalse: [^false]].
    ^true

Symbols are fixed size so you cannot use a message such as add:
A symbol cannot be changed, therefore Symbol does not implement at:put:
You can use the concatenate copying message , (just a comma) whereby a string is returned. For example:

#The,#_,#Beach,#_,#Boys     "answers 'The_Beach_Boys'"

Other selectors in the protocol should be familiar

#BrianWilson at: 1          "answers $B "16r0042" a Character object"
#'Fun,Fun,Fun' size         "answers 11"

You can't write #Fun,Fun,Fun because Smalltalk reads the expression and sees the symbol #Fun receiving a concatenate selector , followed by an undeclared variable Fun. This will result in an error.

#'Surf''sUp' indexOf: $'             "answers 5"
#Fagen_and_Becker isEmpty            "answers false"
#Blue includes: $u                   "answers true"
#aja asUppercase                     "answers 'AJA'"
#AJA asLowercase                     "answers 'aja'"
#'6345789' asString                  "answers '6345789'"
'6345789' asSymbol                   "answers #6345789 2

Symbol also implements the enumerating messages that we have met

do:
detect:ifNone:
keysAndValuesDo:

Next page » OrderedCollection

Previous page « The protocol of String

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

Up to top of page