26 May 2008

Functional Style -- Highlight Mutable Variables

Once you go for lambdas, lazy computations and other functional techniques in programming, you may want your code to be mostly immutable. With ReSharper 4 we didn't do much about data analysis, like do not detect immutable objects or methods. However, one analysis is already available to you: highlight mutable local variables. Open Tools menu, select Options, browse for Fonts and Colors under Environment group. In the Display items find ReSharper Mutable Local Variable and change the appearance as you like. I use Bold font. ReSharper will now highlight every variable that changes its value after the value has been already used.

Try it, and tell us what do you think!

9 comments:

david santos said...

Hello Ilya!
I loved this work. Very good.
By

Dirk Rombauts said...

Hi,

I like this very much - I deplore the fact that C# doesn't let me declare a local variable as "readonly", but highlighting is the next best thing.

One concern, though: when I declare a loop - like "for (int i = 0; i < 42; i++)" - the "i" variable is highlighted as well. This is a case where I want the variable to be mutable, so I would prefer not to have highlighting in that case.

Thanks!

Dirk Rombauts

Ilya Ryzhenkov said...

Dirk, loop variable are mutable, and should be highlighted. Think about this highlighting of loop variables when you accidentaly store them in a closure (use in anonymous function).

fallout said...

Luckily resharper notices when you do that and provides a quick fix to make a copy of the variable.

drew noakes said...

Thanks for this feature. I'd love to see this area developed further in future versions of R#.

I've been thinking about the possibility of allowing types to be declared as 'readonly' in the C# language... something like "public readonly class" This would require that all fields are marked readonly, and are in turn known to be immutable (i.e. known value types, strings and other readonly classes). Such types would also need to be sealed to avoid mutable subtypes. If these ideas don't make it into the C# language, perhaps it's an area that R# could develop via annotations.

drew noakes said...

Thinking about this a little further it seems that the name of this feature is a bit misleading. Actually what we're talking about here is the difference between singly and multiply assigned variables.

All local variables and parameters are technically mutable. There are no immutable variables in C# (unlike in Java).

Furthermore, users might confuse this feature as highlighting immutable data, which is of course a different thing. If a local variable is assigned a reference to, say, a StringBuilder once, then the variable is still mutable, although it is invariant. The object it references is, however, mutable.

To take your reference to functional programming idioms a little further, most functional programming languages only allow 'assignment' to a variable to happen once. This means that all references and data are immutable, which is of course a very different reality to what we have in .NET.

Still I love being able to see which of my variables are invariant.

I also wish Visual Studio would let us control other font properties such as underline and italics.

drew noakes said...

Another idea... how about extending this to readonly fields?

Ilya Ryzhenkov said...

Drew, we are going to give data analysis a big think after ReSharper 4 is released. We understand the importance of data analysis, but without deep architecture change we can only do local analysis. Or pollute the code with tonns of attributes, which is not very good even with NotNull annotations. So, we have to invent something.

drew noakes said...

I listened to Scott Hanselman's podcast on Spec# recently. It seems like the folks at Microsoft Research are working on a candidate superset of the C# language to incorporate various ideas that tighten the contract of callable code beyone basic type constraints.

For example, as we have nullable value types "int?" we could also specify non-nullable reference types "string!". Spec# integrates these features into the language and the compiler introduces run-time checks for these conditions.

I suppose it would be possible to instrument code compiled with ReSharper annotations and inject these checks into the IL.

The Spec# team have apparently also created external annotations for the .NET BCL (although they call them something different).

Spec# looks interesting. Unfortunately it only extends from C# 2.0, and doesn't integrate well into our current tool chain. I hope to see these kinds of features introduced into the C# language in the future.