Referential Transparency, Redux and React

Introduction

I started my career doing C/C++ programming for Embedded systems and then transitioned to do Java/J2EE for a very long time. For the last year or two, I have been exposed to the world of functional programming through Scala, and for the last couple of months I have been doing actively development in the front end stack using Node.js on the server side and Redux/React on the client side. It has been a great experience and would like to share the connections I can see between the concept of “referential transparency” in functional programming world to Redux/React.

Referential Transparency

[Source Used for reference: Functional programming in Scala book]

Functional programming (FP) is based on a simple premise that we construct our programs using only pure functions – functions that have no side effects. What are side effects? A function has a side effect if it does something other than simply return a result. For eg:

  • Modifying a variable
  • Throwing an exception or halting with error
  • Making IO operations

Functional programming provides many techniques to do the above set of operations as well without side effects. I have written about a couple of patterns here:

Kleisli Monad Transformer

Magic of State Monad

The key idea is that majority of logic that deals with side effects lives at the edges of the application, while the core remains pure. Why do we need to have “pure functions” in the first place? Well, the answer turns out to be simple: Pure functions are easier to reason about. A function f with input type A and output type B, function of type A => B, is a computation that relates every value a of type A to exactly one value b of type B such that b is determined solely by the value of a.

We can formalize this idea of pure functions using the concept of “referential transparency”(RT). This is a property of expressions in general and not just functions. For eg., if we have an expression 2 + 3 in different parts of the program; This expression has no side effect and evaluation of this expression results in the same value 5 every time. In fact, if we saw 2+3 in a program we could simply replace it with the value 5 and it would not change a thing about the meaning of the program. The above case is true for eg., if we have a function called add(int, int): int which takes 2 integers and returns an integer as a result. If we saw for example, add(2, 3) in different parts of the program we could again simply replace it with the value 5 and the meaning of the program stays the same.

Referential Transparency examples
String class and its methods in Java are examples of referential 
transparency, as they do not have any side effect.

String s1 = "Hello"
int length = s1.length() // always going to be 5

Non Referential Transparency examples
StringBuilder class and its methods in Java are examples of non referential
transparency as they have side effect.

StringBuilder s1 = new StringBuilder("Hello");
s1.append(" , World"); // side effecting operation

Pure functions as mentioned earlier are easier to reason about and also has an additional important property that they are inherently thread safe and are very easy to parallelize. In the above example, StringBuilder is not thread safe as it has side effecting operations.

Redux

Redux is a predictable state container for JavaScript apps. The core philosophy of Redux is to have a “single state tree” and they have a reducer function whose signature is (currentstate, action) => nextstate[ReduxSourceCode] and reducer has to be a “pure function”. This basically means, that reducer function is referentially transparent and where ever we see the reducer function call we can replace the function call with the result of making the call and the meaning of the program stays exactly the same.

In the case of UI, state comes from 2 sources:

  • State produced by making a backend service call, which is an IO operation which is solved by Thunk Middleware. Thunk Middleware makes side effects living at the edges of the program within redux, where as the reducer function within the core can remain pure.
  • UI state like checkbox selected, button clicked etc.,

Because of reducers being a pure function and thus referentially transparent, the UI application state has become so easy to reason about.

React

ReactJs, a javascript library for UI interfaces, follows declarative and component based approach. Since the browser DOM operations are impure and causes side effect, it makes reasoning extremely hard. React brings in a notion of virtual dom through “ReactElement” which is a light, stateless, immutable, virtual representation of a DOM Element. A React component is expected to have a render(props, state) function to describe its UI. The signature is not completely accurate, but it captures the essence of the render function. Props are read only and if we push state from the React component into Redux state tree, then the render function has become render(props) which is a pure function and it becomes referentially transparent. This is called “Stateless functional components” in React. So in essence we can have a referentially transparent react component render method using a referentially transparent redux reducer function.

React Redux , which provides react bindings for redux, provides a function called connect(mapStateToProps, mapDispatchToProps) which acts as a bridge connecting the redux state to the react component props and also dispatching actions from react component to trigger the next state calculation using reducer function thus making sure the React Component UI stays up-to-date when its relevant state changes.

The mental model of how React, Redux, React-Redux fits in can be shown as below:

ReactRedux

Conclusion

As we can see, how a core philosophy of “referential transparency” in the world of functional programming is being applied to client side programming using React/Redux which makes UI code very easy to reason about.

 

 

 

4 thoughts on “Referential Transparency, Redux and React

Leave a reply to MADHAV DEVERKONDA Cancel reply