Both viewpoints are correct.
There's definitely some concept of evolving "state" within the program as a whole, but you never mutate state within a named variable.
Taken to the extreme in a language like Haskell, you end up working with "State Monads" and "IO Monads" where you pass around a value to every function that has any form of side effect (such as printing to the console). The function then clones this state and returns an updated version. This global state often contains nothing more than a monotonically incrementing integer.
In this way, you can preserve the idea of pure functions even across operations such as printing log output and writing to files.
Scala programs rarely take things to this extreme, but if you really want to maintain functional purity like this then scalaz is the way to go. Unlike Haskell, neither scalac nor the JVM is designed to optimise this style of program, so you'll take a small performance hit. On the other hand, there are advantages in terms of composability and the ease of reasoning about your code.