4 ms·
> Most real-world programming requires handling of side effects somewhere, so such programs have parts which are not referentially transparent. That's not corr
by valenterry 5y ago
> Most real-world programming requires handling of side effects somewhere, so such programs have parts which are not referentially transparent.
That's not correct though. Look at Haskell (or even stricter Idris). This is real world application code that can do whatever Java, C++, ... can do, but it is pure functional and hence doesn't contain any non referentially transparent parts. Just because an application is written in a pure functional style does not mean that it cannot e.g. write into a database when it is executed.
Of course many languages don't even allow to use a fully pure functional style. In that case, a more or less big functional "core" is the closest one can come to a pure FP style.
> I didn't go into immutability in my other response because you can use mutation inside pure functions, as long as the effect doesn't leave the function.
Sure you can do that and sometimes it is even the best practical solution. And the function might even be referential transparent - but your whole application is now not pure functional anymore, because a part of it is not referential transparent anymore.
Hence: if an application has to satisfy the criteria of being "pure functional" then every expression must be referential transparent and hence no mutation can be used.
- pflanze 5y agoIt's funny that you defend your view using Haskell, as I was replying with Haskell in mind. If you use the state monad, you encode local side effects. Then you use runState in a function that has a non-monadic type--a pure function. Feel free to argue that the state monad is only having pure expressions because it can be represented using only pure functions and partial evaluation. For all practical purposes it is used to write code that exerts (local) side effects into the state maintained by the state monad. You can a function in say, OCaml, that fills an array via mutation using only function arguments to deduct the contents, and then returns that array. That function is pure (it exerts no side effects outside and is not exposed to side effects from the outside, its result value only depends on the function argument values). Yet how is that not using mutation, non-referentially transparent parts inside? You can write the same function with a mutable vector in Haskell (Data.Vector.Mutable, using the ST monad). How is it not exactly the same code as the one in OCaml except for the types that guarantee the purity? Yes, it may be using pure expressions underneath to guide the type system to enable the proof of purity. But does that change what I said? Both to the programmer and (after optimization) to the machine the code is using mutation. You can model mutation using only pure functions. That may be useful in some ways, but you can also take a C program, represent every memory address as an entry in a tree of immutable nodes, the outside world as an abstract entity with versions, and recreate it with only pure expressions. That may be what is useful in some contexts for developing proofs or to implement type systems, but is this relevant for a programmer interested in writing more functional programs? Why not just say that using ST is using local mutation (that the type system can guarantee will not leak outside) and be done with it?
- deleted 5y ago[deleted]
- tome 5y agoEquivocation about purity, referential transparency, mutability, side effects etc. is not very interesting. The operative point is that, in Haskell, firstly x = expression y = expression ... is the same as x = expression y = x ... and that, secondly x = expression ... is the same as ... when x does not appear in ... . Those are the important properties of Haskell (with regard to this discussion). Whether this advances the discussion is another matter ...
- slver 5y agoI'm not deep into Haskell, but isn't the interpreter monad pattern effectively a language within the language that acts in a very conventional procedural way for interacting with IO and other external concerns? I just wonder... does Haskell really need syntactic segregation for this, and how is that better than any language which can declare/enforce pure functions/modules without the entire language being like that by default.
- tome 5y agoWell, give it a go! Or alternatively, look for languages that have been successful in enforcing any kind of purity and that also permit unrestricted use of higher order functions.
- slver 5y agoIt's very hard to make Haskell look attractive to me, I deal with open systems (i.e. systems which interact with many other heterogenous systems which evolve in time), and Haskell is optimized for precisely the opposite case (a walled garden built out of elaborate types for verifying correctness). Haskell is the weird introvert guy in an extrovert world.
- 5y ago