views:

218

answers:

4

I've been reading articles on how to program in a functional (i.e F#) style in C#, for example, foregoing loops for recursion and always returning a copy of a value/object instead of returning the same variable with a new state.

For example, what sort of code inspection things should I watch out for? Is there any way to tell if a method on a BCL class causes a mutation?

A: 

Without testing the method, you won't be able to tell if it has any side effects. It would be handy if the documentation mentioned any side effects of a method or function but unfortunately it doesn't.

Keep in mind that you will have to do some extensive testing to be certain that no side effects can occur. If you want to you can always disassemble the assembly and read the code for side effects.

Andrew Hare
+1  A: 

Unfortunately there's no easy way to do that in C# currently. If you're lucky the documentation will tell you, but generally that is not the case.

Inspecting the code with Reflector (assuming we're talking managed code) can reveal if the current implementation has any side effects, but since this is an implementation detail there's no guarantee that it will not change in the future, so basically you will have to repeat the verification every time you update the code in question.

Tools such as NDepend can help you find out dependencies between types - i.e. where you have too look for side effects.

For your own types, you can implement immutability, by making sure instances never leak references to internals. Make sure to copy the contents of reference type instances used to instantiate the objects as other may otherwise keep references to internal state.

Brian Rasmussen
+1  A: 

Here are two things that would help you find variables and fields whose values are getting changed. Mutability is more complex than this, of course (for example these won't find calls to add to collections) but depending on what you're looking for, they may be helpful.

  1. Make all of your fields readonly; then they can only be set from the constructor, and not changed thereafter.

  2. Pick up a copy of ReSharper. It expands on Visual Studio's syntax highlighting, and has an option to set up custom highlighting for mutable local variables. This will let you see at a glance whether locals are being modified.

Joe White
For reference type readonly make the reference read only, not the instance it is pointing to. Thus the instance itself may still be changed.
Brian Rasmussen
True, which is why I said this isn't a complete solution and won't find things like Add calls on collections.
Joe White
+4  A: 

Not only the tool NDepend can tell you where you have side effect, but it can also ensure automatically that a class is immutable (i.e no side effect on its object instances) or a method is pure (i.e no side effects during the execution of the method.

In short, trick is to define an attribute, such as, MyNamespace.ImmutableAttribute and to tag classes that you wish to be immutable.

[Immutable]class MyImmutableClass {...}

If the class is not immutable, or more likely, if one day a developer modifies it and breaks its immutability, then the following NDepend CQL Rules will suddenly warn:

WARN IF Count > 0 IN SELECT TYPES WHERE !IsImmutable AND HasAttribute "MyNamespace.ImmutableAttribute"

I wrote a complete article on immutability/purity/side-effects and NDepend usage: Immutable Types: Understand Them And Use Them

Patrick Smacchia - NDepend dev