In some cases, I want to use referentially transparent callables while coding in Python. My goals are to help with handling concurrency, memoization, unit testing, and verification of code correctness.

I want to write down clear rules for myself and other developers to follow that would ensure referential transparency. I don't mind that Python won't enforce any rules - we trust ourselves to follow them. Note that we never modify functions or methods in place (i.e., by hacking into the bytecode).

Would the following make sense?

A callable object c of class C will be referentially transparent if:

  1. Whenever the returned value of c(...) depends on any instance attributes, global variables, or disk files, such attributes, variables, and files must not change for the duration of the program execution; the only exception is that instance attributes may be changed during instance initialization.

  2. When c(...) is executed, no modifications to the program state occur that may affect the behavior of any object accessed through its "public interface" (as defined by us).

If we don't put any restrictions on what "public interface" includes, then rule #2 becomes:

When c(...) is executed, no objects are modified that are visible outside the scope of c.__call__.

Note: I unsuccessfully tried to ask this question on SO, but I'm hoping it's more appropriate to this site.

1 Answer 1


The goal of enforcing referential transparency (RP) may be a bit ambitious given the presence of file IO and global variables. Instead, you can make it a best practice, which basically seems like that you wish to do.

Rules 1 and 2 will certainly push you into the direction of RP, but they are somewhat problematic. First of all, relying on the fact that a disk file doesn't change is risky. It is best to isolate IO to well defined parts of application code. The same holds for global variables. While it is true, that if global variables used by a function don't change, it would allow for RP, it may be too difficult to enforce. Instead, try to avoid global variables. Also, ensure that instance attributes are read-only.

Given that Python is a multi-paradigm language, you can reap the benefits of functional programming as well as OOP. You can structure code such that there are purely functional parts which adhere to RP and there are imperative parts which glue everything together. OOP can be said to structure programs by encapsulating moving parts while FP can be said to reduce moving parts - use both paradigms.

  • I like the "encapsulation" vs "reduction" of moving parts description of OOP and FP. Are there any books, etc that talk about combining the two paradigms?
    – max
    Commented Oct 14, 2012 at 0:32
  • 1
    I'm not aware of any language agnostic books, but this F# book combines both approaches as it is targeted for imperative developers adopting a functional paradigm.
    – eulerfx
    Commented Oct 14, 2012 at 1:30

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.