Question

My workplace mostly uses C# for writing code. I'm trying to figure out a good way to indicate that a class with referentially transparent methods is intended to be referentially transparent (i.e., given the same set of arguments, you will always get the same return value) for future maintainers. I've considered just using static classes for classes that are intended to only contain referentially transparent methods but received pushback from my colleagues as they prefer an approach to unit testing where all classes depending on are stubbed out which they use constructor DI to accomplish. I don't see a disadvantage to not stubbing out referentially transparent functions for unit testing since they are almost always in-memory anyway but I've been unable to convince my colleagues of that.

Our class names use typical OO pattern names like DTO or Factory or Controllers and Models for namespaces. I'm not aware of any pattern names in OO that would indicate the sort of intent I am going for (i.e., to not introduce side-effecting operations or depending on things that read out of the db or filesystem).

Was it helpful?

Solution

The best way I can imagine to do this is to use a namespace named pure or stateless or referentially-transparent (which will likely just confuse most, so stick with a simpler name than referentially transparent). With this all you need to communicate to your colleagues is "Namespace X only contains referentially transparent code" so anytime someone uses that namespace they might get the click in their head of understanding.

OTHER TIPS

Put a comment in the XML header of the class, to the effect of "This static class contains only referentially transparent methods, like those in the System.Math static class. Don't put functions which cause side-effects here."

Referentially-transparent methods are the easiest of all methods to test: hand them a value, and examine the return value. That's it.

Of course, the pushback is going to be "how do I know this 'referentially-transparent' method doesn't call other methods?" The answer to that is that you tested those other methods, and you already know they work, right?

Further Reading
Is static universally "evil" for unit testing and if so why does resharper recommend it?

This is really jumping through hoops but what about creating a base class called ReferentiallyTransparentBase whose constructor throws an exception? Then when the person starts debugging the exception they'll see the comment // THIS CLASS'S METHODS WILL BREAK IF YOU CREATE INSTANCES OF IT. SO DON'T DO IT. Hopefully they'll get the picture.

I don't do much C# development but it seems to me you could define an attribute and apply it to all such classes. You could then give a thorough description of what restrictions that imposes on classes within the documentation of the attribute. That way your intent is still documented but you don't have to copy-and-paste some boilerplate about referential transparency into the documentation for all the classes.

Licensed under: CC-BY-SA with attribution
scroll top