First time here? Check out the FAQ!

When do I use brackets (parentheses) in Capytalk / Smalltalk?

+1 vote

I've been almost too embarassed to ask this question and it's really a general Smalltalk question rather than a Kyma one, but it's been bugging me for ages... and I think I finally understand it.

Whenever a Capytalk expression didn't do what I was expected I just kept adding brackets until it worked. This gave me a disastified feeling of not really understanding what I was doing. Although it seems this is a recognised approach, quoting Kyma X Revealed:

When in doubt, use parentheses to make your intentions clear

Googling "Smalltalk brackets" didn't immediately give me the answer. What I should have been googling was "Smalltalk Precedence". There's a brief description of Smalltalk Precedence in Kyma X Revealed on page 216, which I now understand having read this I found online:

Smalltalk Precedence  (see sections 7.6.4 and 7.6.5)

which is a slightly longer explanation and finally I think I understand it.

I've kind of answered my own question here but I thought this might be useful if anyone else out there was struggling with this the way I was.

asked Nov 24, 2016 in Capytalk & Smalltalk by alan-jackson (Virtuoso) (15,840 points)
edited Nov 24, 2016 by alan-jackson

1 Answer

+1 vote
Best answer

There are 3 different kinds of messages in Smalltalk (and Capytalk):

  • a message with a receiver only and no arguments (unary): !x abs
  • a message (composed of one or two non-alphabetic characters) with a receiver and a single argument (binary): 1 - !x
  • a message with a receiver and one or more arguments (keyword): !KeyDown bpm: !BPM dutyCycle: 0.1

The order of evaluation (without parentheses) for messages is first unary, then binary, and finally keyword.

This means that !KeyDown bpm: !BPM dutyCycle: 1 - !x abs means:

  • evaluate !x abs
  • evaluate 1 - (!x abs)
  • evaluate !KeyDown bpm: !BPM dutyCycle: (1 - (!x abs))

When using more than one keyword message in an expression you will always need to use parentheses:

(!KeyDown bpm: !BPM) triggerEvery: !Count

Without the parentheses, Smalltalk will be trying to send the message bpm:triggerEvery:, which is not defined.

If you are sending more than one unary (binary) message in a row, the order of evaluation is left to right. For example, !x abs negated is evaluated as (!x abs) negated and !KeyPitch + 24 / 48 is evaluated as (!KeyPitch + 24) / 48. This simple rule for binary expressions is different than the complex precedence rules you may have learned for arithmetic in other computer languages.

answered Nov 28, 2016 by ssc (Savant) (125,740 points)
selected Dec 1, 2016 by alan-jackson
Very clear explanation, thanks SSC.

I find that parentheses in Smalltalk and Capytalk is easy to visualise as the demarcation boundaries of an object, which is what every message is in Smalltalk in fact.