Well, using a state monad such as Haskell&#x27;s IO monad is usually considered functional style, but the state is hidden. Moreover, any body of code in which state is passed around in explicit arguments can be transformed into code in continuation-passing style (or monadic style) in which the state is hidden -- and it&#x27;s hard to argue that the code in continuation-passing style is not functional code.<p>Whether or not the state is hidden is not one of the distinguishing features of functional programming.<p>Referential transparency and being able to declare certain &quot;values&quot; to be immutable even though there are some mutable values around are. For example, if some code is referentially transparent, putting it into continuation-passing style preserves the referential transparency.<p>BTW, some say that being able to specify the result that you want rather than needing to specify <i>how</i> those results are computed -- which is sometimes called &quot;declarative programming&quot; -- is what makes functional programming powerful, but I disagree: it is being referentially-transparent (or more precisely, more referentially-transparent that imperative code) and giving the programmer the ability to credibly assert that this or that data structure is immutable, combined with language and library support for working with immutable data structures.<p>Another distinguishing feature of functional programming: being able to rely on (or hope for) certain compiler optimizations not available in imperative languages. (It is because of this feature that Scheme is considered by some to be a functional language.) Referential transparency might be necessary to make these optimizations tractable.