5 ms·
FP means that every expression (= part that can be evaluated) is referential transparent. Nowadays the word "functional" is used different from the original mea
by valenterry 5y ago
FP means that every expression (= part that can be evaluated) is referential transparent. Nowadays the word "functional" is used different from the original meaning (which some now call "pure functional")
> Some FP is lazy, some isn't.
The definition of FP implies that laziness is irrelevant. A language can enforce a pure functional style without being lazy or not.
> Some is immutable, some isn't
That's wrong. And it is a good example of why FP is much clearer defined. Referential transparency implies immutability. So there is no pure FP code that uses mutability.
> Some claim it's a style in any language, others that it's a type of language.
It's neither. It is a property of a program. Some languages enforce this property, others make it impossible to write a full program in this style. But that's independent of the definition itself.
I hope that explanation sheds a bit of light into it.
- pflanze 5y ago> FP means that every expression (= part that can be evaluated) is referential transparent. Most real-world programming requires handling of side effects somewhere, so such programs have parts which are not referentially transparent. It's why I distinguished between "core" and "meat" in my other response. Functional programming languages offer features that help making a larger part of the program referentially transparent (and, optionally, to ensure that property in the types). > Nowadays the word "functional" is used different from the original meaning (which some now call "pure functional") I don't think the meaning changed, just the tools offered and the scope of the support they offer to achieve referential transparency (pure functions). Early Lisp offered expression oriented programming which was a step towards it, but used dynamic scoping which isn't really helping. Later on both Lisps and ML offered lexical scoping. Then the purely functional trend came up via Miranda and (Clean and) Haskell, the latter encoding purity in the type system. In the last decade mainstream programming languages added functional programming features but are falling short in encoding purity in the types (just as Lisp never did), which means that it's (easily) possible for the abstractions offered (both functions but also libraries built on iterators) to not be referentially transparent, manual care (and/or culture) is required instead. The tooling doesn't help enough to guarantee referential transparency. But the core idea, the target of the efforts, is the same. > Referential transparency implies immutability. 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. Building referentially transparent functions does not imply using immutable data structures or variable bindings inside.
- 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?
- slver 5y ago> > Some is immutable, some isn't > That's wrong. And it is a good example of why FP is much clearer defined. OCaml and F# are two examples of functional languages with freely supported mutable data types. So maybe what I said is "wrong" about your personal idea of what FP is. But it's clearly not "wrong" about the fact some people see immutability as optional for FP, which is the very point I'm making.
- ratww 5y ago> OCaml and F# are two examples of functional languages Both OCaml and F# are multi-paradigm languages that have FP features, but are not restricted to FP. The support for mutability comes from their imperative/OOP ancestors, not from FP.
- kaba0 5y agoSorry, it’s my pet peeve, but referential transparency doesn’t mean what many think it does — what you mean is simply side-effect freeness. See the top answer here: https://stackoverflow.com/questions/210835/what-is-referential-transparency https://stackoverflow.com/questions/210835/what-is-referenti...
- carapace 5y agoThat answer is so informative and yet it completely misses the point. The problem is even called out in the answer itself: > For example, our example "Edinburgh has been the capital of Scotland since 1999" signifies the fact that "capital of Scotland" depends on the time at which it is being considered. Such context-dependence is a reality, both in natural languages and programming languages. "Therein lies the rub." Such context-dependence doesn't have to be a reality in programming languages. "2 + 2 = 4" is an eternal verity, not subject to context-dependence. The whole point of FP (going back to Backus' Turing Award paper where he introduces and defines "FP") is to operate in the pure realm of [binary Boolean] logic.
- kaba0 5y agoI agree with you, but this property of FP languages is called pureness/not-having side effects, not referential transparency. The latter is (quoting pron’s older comment: https://elarib.com/item?id=22141647 https://elarib.com/item?id=22141647 ): “an expression e is referentially transparent if any sub-term in it can be replaced with any other having the same reference (aka denotation) without changing e's reference”. Perhaps I should have linked this comment over the stackoverflow answer, as it also mentions how eg. template haskell or LISPs are actually NOT necessarily referentially transparent due to macros. So while in Java replacing the constant 2 with a variable having value 2 is always equivalent (in reference, not necessarily effect!), the same may not be true with a given macro applied.
- carapace 5y agoFair enough. (I'm getting old, it hurts my head to imagine pure-but-not-referentially-transparent language; however, imagining referentially-transparent impure language doesn't.)