leanovate / gopter

GOlang Property TestER
MIT License
599 stars 40 forks source link

Is it dangerous to share references between states? #71

Open symbiont-sean-lyons opened 4 years ago

symbiont-sean-lyons commented 4 years ago

When transitioning a model using Command.NextState -> commands.State, is it dangerous to share pointers or reference types between model states?

For example,

type State struct {
  index map[string]string
}

func (writeFooBarCommand) NextState(s commands.State) commands.State {
  current := s.(State)
  next := current
  next.index["foo"] = "bar"
  return next
}

I believe that the existing model state and the new model state will share a reference to the underlying map, meaning manipulations via the old state instance or the new state instance will reflect in both objects. I currently make it a habit to deep copy my model states when transitioning, but my question is whether or not the deep copy is necessary.

untoldwind commented 4 years ago

In this specific case it should be no problem mutating the state as long as InitialStateGen always generates a new instance.

The main loop running a sequence of commands is done in this function: https://github.com/leanovate/gopter/blob/8de0d746533ed4ca265750b9bcf3ba01839df390/commands/actions.go#L41-L53 As you can see the previous state is just forgotten after the command has been applied, therefore it does not matter if it has been mutated or not.