I try to have as many pure functions as possible, but if I can't, I at least try to make the side effects as explicit as possible.

Here is an example (in Go)

type State struct {
    count int

func (s *State) IncreaseCount() *State {
    s.count += 1
    return s

func main() {
    s := new(State)
    s = s.IncreaseCount()

Since s is a pointer, s.IncreaseCount() would be sufficient. I find s = s.IncreaseCount() makes it more obvious that s has changed.

But is this a good practise? Or it just makes the code more complicated than it could be?

As a side note, removing the pointer would actually make IncreaseCount a pure function:

func (s State) IncreaseCount() State {
    s.count += 1
    return s

but imagine State is a big complicated struct and we cannot afford copying it.


1 Answer 1


A statement like

   s = s.IncreaseCount()

can have the opposite effect of what you are trying to accomplish: it can give the reader the impression IncreaseCount does not mutate s by itself and instead returns a new object exactly because of this. Hence the assignment looks like it would be required. This makes the next dev (or yourself in 6 months) think

  s2 = s.IncreaseCount()

leaves s unchanged.



is much clearer to me for two reasons:

  • the name of the method is quite clear

  • since there is no return value, the method must have some side effect, otherwise it would be superfluous

See also my former answer here to the question Is modifying an object passed by reference a bad practice?

  • 1
    Oh, boy, +1 for this answer. The first thing I imagined after reading this question was debugging why s changed when I thought that s2 was the only thing that changed. Nothing can burn out a programmer faster than rooting out gremlins like that. Commented Nov 15, 2022 at 21:09

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.