Naming Smalltalk method parameters
Tags: naming, smalltalk, programming, style
Published: 2024-02-06 15:30:38

## Introduction

I like to name things. A lot. And I appreciate unambiguity like a compiler. In some of my previous jobs, both as an employee and as a contractor, I was responsible for naming (and renaming) a good part of the codebase wherever possible.

I've wanted to write about naming classes and methods for a long time. Remembering some rules and recommendations from [Kent Beck's _Smalltalk Best Practice Patterns_](https://www.goodreads.com/book/show/781561.Smalltalk_Best_Practice_Patterns) (which are as valid as when they were published almost three decades ago) and some rules and conventions of my own I've been following since I started programming in Smalltalk at the beginning of this century.

But what finally moved me to write about this was reading [_Naming Things: The Hardest Problem in Software Engineering_](https://www.amazon.com/Naming-Things-Hardest-Software-Engineering-ebook/dp/B0BT15GFZG), because I thought that I hadn't seen much, if anything, written about this topic lately in the context of Smalltalk.

## Parameter Naming Rule 0: anObject
In Smalltalk it is very common to name method parameters by using the most general expected class in the name of the parameter, in the form of _indefinite article + class name_, i.e. `aString` or `aDictionary`, the error-prone `aStringOrNil` or the _catch-all_ `anObject`. 

This is a community convention almost as old as the language itself that is characteristic of Smalltalk codebases and there's nothing wrong with it. It's useful and describes the class of the expected argument, given Smalltalk's late binding.

Some examples of selectors with that convention are `printOn: aStream`, `at: anObject ifAbsent: aBlock`, `isKindOf: aClass`, where the paramenter name tells you what object you should pass as an argument when sending a message.

## Parameter Naming Rule 1: Only name parameters after existing classes

There is a common practice that breaks the rule described in the introduction: naming a parameter after a class that doesn't exist.

E.g.`accessor: aSelector`, where there is no `Selector` class.

My rule here, which I think I read somewhere over ten years ago, is to avoid doing that, using one of the alternatives:

- Use the right class name: `accessor: aSymbol`
- Use the semantic name, without article nor class name: `accessor: selector`

## Parameter Naming Rule 2: Clearly distinguish between multiple parameters of the same class

Sometimes a method has two or more parameters of the same class, which can look like `from: anOrigin to: anExtent` or `copyFrom: aSource to: aTarget`, `start: objectA end: objectB`.

All these examples have one or more issues, the obvious now is violating the PNR1, but also not having any semantic meaning. These could be rewritten as follows:

- `from: originPoint to: extentPoint` or `from: origin to: extent`
- `copyFrom: source to: target` or, if applicable, `copyFrom: sourceRepository to: targetRepository`
- `start: startObject end: endObject`

## Naming dynamics

> _“What you must learn is that these rules are no different than the rules of a computer system. Some of them can be bent. Others can be broken.”_ - Morpheus, The Matrix

There are often times when naming a parameter without following PNR0 will cause a clash between the parameter name and some instance variable name (e.g. `from: origin to: extent` will likely clash with the `origin` and `extent` instVar names). In such cases, you will have to get creative and add a prefix or suffix to the parameter name if necessary.

## Follow up

I have some other rules and conventions I'd like to share with the development community. Including adding new ones to those originally published in this article. Stay tuned.