I didn't appreciate how much of a difference it would make until I tried it, but now I know that one of the best ways of making code more comprehensible is to eliminate any questions about interactions between components by using a language with referential transparency. The results of functions should be determined solely by the values of their arguments, with no contamination by shared state and no side effects.
Refactoring code without side effects is so incredibly liberating: I barely have to compile many changes, much less carefully test them, because they're so obviously correct, because I can SEE the flow. I don't have to speculate on what the rest of the system thinks is going on.