6 ms·
Not really. Try to interact with DB in FP. Yes, there is a referential transparency ... when combining functions which call DB (e.g. using monads). As a result
by vc8f6vVV 4y ago
Not really. Try to interact with DB in FP. Yes, there is a referential transparency ... when combining functions which call DB (e.g. using monads). As a result you get a composite function, which is the same every time you run that composition. Who cares really? When you execute that composite function though you will potentially get different results and your "referential transparency" goes out the window. Of course one can write a "pure" FP program without effects, but any side effect reduces referential transparency to combining functions, is it really easier to reason about computations this way? Nope, it is not.
Basically how FP sells:
def a
1
end
def b
2
end
def c
a + b
end
You see? c = 3! Now try to apply this logic to (real world with effects):
def a
(conn: DBConn) => { .... some complex code ... }
end
def b
(conn: DBConn) => { .. another complex code ... }
end
def c
(conn: DBConn) => a(conn) + b(conn)
end
So c = ? Still transparent?
- ARandomerDude 4y agoDB operations are not what is being described in the conversation about referential transparency. We’re talking about something that starts with things like reduce vs. a for loop with mutable variables to accumulate values. Once the language forces you to think in terms of stateful operations to perform even basic tasks, the reflexive tendency is to use mutable state to perform any task. At that point, nobody really knows what a functional does because you have to understand the entire system to know what the output of a function will be.
- vc8f6vVV 4y agoBut we do have loops in the real world, don't we? So in a true FP we are talking about recursion as an alternative to for loops. Can you easily reduce recursive function? If you can, I can as well "reduce" for loop. Otherwise we are talking about a paradigm without recursions and side effects.
- ARandomerDude 4y agohttps://clojuredocs.org/clojure.core/reduce https://clojuredocs.org/clojure.core/reduce
- vore 4y agoNo, but this is why we have things like linear types or encapsulating side effects in a state monad to describe these kinds of strict sequencings. I personally think pure functional programming is still very unergonomic but referential transparency in the face of side effects is not an unsolved problem. Besides, it's good practice to limit how widespread side effects are in any program, anyway.
- vc8f6vVV 4y agoReferential transparency is something you can reason about. While technically monads are "reasonable" you are not going to reduce them by substitution. Yes, you can if you have a good imagination, but how does it help? While combining effects is thread safe etc., executing resulting function not necessary is. So we just kicked the can down the road adding another layer on top of existing compiler. Monads is a nice way to hide state I have to admit, but not because of referential transparency and "reasoning".
- remexre 4y agoI'd argue that the difference between a monad and any old type with operations of bind and pure's types is precisely reasonableness -- I can expect Control.Monad.forever to work because the monad laws allow me to reason about monads as an abstraction rather than caring about the precise way the Writer monad might be implemented.
- epgui 4y agoIf we're talking about Haskell monads, they are referentially transparent, and they are very very easy to substitute. For a specific example, see: https://en.wikibooks.org/wiki/Haskell/Understanding_monads/Maybe https://en.wikibooks.org/wiki/Haskell/Understanding_monads/M... Each Haskell monad might have a different implementation of the >>= (bind) operator, which is referentially transparent and which you can easily substitute. The IO monad would be an exception: I believe that one is not referentially transparent and thus cannot be substituted, because it's not implemented in Haskell. You can however imagine that it is a sort of state monad for the external world, but that's a fiction in practice. (Note: Haskell monads are not "real monads" from category theory, and nor are monads in any other programming language AFAIK... So it's helpful to be very specific about what we're talking about when we use the word "monad" without context. You can implement a monad-like thing using classes in Python or many other languages, but those aren't referentially transparent and aren't typically the monads people are talking about in the context of pure functional programming.)
- valenterry 4y ago> So c = ? Still transparent? No, it's not. and a and b are neither in your second example, otherwise they could not produce any result that could be combined with +. Unless `{ .... some complex code ... }` is just `return 42`. Referential transparency means that we can evaluate the same thing over and over again and getting exactly the same value back. Obviously that does not work with what you have constructed. It helps when you annotate your examples with return types. That will make things clear very quickly.