C#: And I thought parallel assigment expressions were good


When I began using Ruby I loved most of the things I saw. I made couple (1 , 2 ) of posts on some of those features that I'd like to see in C#. When I started re-visiting code I wrote sometime back my views started to change considerably. One of these was the parallel assignment constructs in Ruby.


At first it looks tempting and trivial. Let's see the classic example of swapping two variables. In C# you'd do something like

string a = "Abhinaba";

string b = "Basu";

string temp = a;

a = b;

b = temp;


This can be done beautifully using Ruby parallel assignment with just one line and no need for any temporary placeholder.

a = "Abhinaba"
b = "Basu"
a, b = b, a

Parallel assignment works by evaluating all expressions in the right-hand-side before any assignements are made. After that all assignments are made. So the effect is as if all assignments are made is parallel.

x = 5
a, x, c = x, 3, x+= 1

In the code above the values after the assignment is a = 5, x = 3, c = 6. The expressions on the right are evaluated first, even though x is reset to 3 in the middle, it has no effect on the value assigned to c.


The other simple rule is that if there are more lvalues than rvalues then the additional lvalues are made nil (as in C# null) and if there are more rvalues than lvalues then the additional rvalues are ignored. Till this point it's fine. I went around to all the folks I generally bug like Ankur with my usual dictum that these kinds of expressions are cool and C# should support them. Since in C# is strongly typed also has value-types, we can fail compilation when number or type of lvalue does not match the corresponding rvalues.


But things in Ruby get complicated after this. This is specially true if the rvalue contains an array. See the following code snippets from Programming Ruby book

a = [1, 2, 3, 4]
b, c = a # b == 1, c == 2
b, *c = a # b == 1, c == [2, 3, 4]
b, c = 99, a # b == 99, c == [1, 2, 3, 4]
b, *c = 99, a # b == 99, c == [[1, 2, 3, 4]]
b, c = 99, *a # b == 99, c == 1
b, *c = 99, *a # b == 99, c == [1, 2, 3, 4]

So if the last lvalue is prefixed with an asterix as in *c then all the remaining values of the rvalues are converted to an array and assigned to c. Similarly if the last rvalue is an array and it is prefixed with an asterix as in *a, then it is expanded to its constituent values in place. If you think that this is getting complicated go figure out the following nested assignments

b, (c, d), e = 1,2,3,4     # b == 1, c == 2, d == nil, e == 3
b, (c, d), e = [1,2,3,4] # b == 1, c == 2, d == nil, e == 3
b, (c, d), e = 1,[2,3],4 # b == 1, c == 2, d == 3, e == 4
b, (c, d), e = 1,[2,3,4],5 # b == 1, c == 2, d == 3, e == 5
b, (c,*d), e = 1,[2,3,4],5 # b == 1, c == 2, d == [3, 4], e == 5

I did the unfortunate thing of using a complicated nested assignment in some code I wrote for incremental backup of my digital pictures. When I had to fix a bug in that code I had to go through the whole damn spec again!!!

Comments (7)

  1. matt says:

    Uggh! We REALLY don’t need this "feature" in C#.

  2. Doug says:

    Much too clever for my taste.

  3. We can do with this if we stopped with the basic parallel assignment and kept out the funky asterix and convertion to array business. Things in moderation are fine and too much of a good thing starts giving you diabetes….

  4. Joku says:

    I have to agree with the other sentiments.

    I would hate to see any more features in C# that save only a couple lines and do that with confusion.

    At most add only features which can save some considerable or difficult typing such as anon. delegates, var and such.

    If you must add a whole bunch of "little cool stuff" then I’d rather have some new name and extension for that, C## with extension .css (oops). So it would be very obvious that a particular program can have some of these "little cool tricks".

    end rant

  5. Joku says:

    Here’s a clever idea for you.

    Make it possible to add (with VS editor support) any .NET languages in same TYPE such as:

    void CSharpMethod() {

    this.AnotherLanguageMethod();

    }

    Of course there would be some tricky problems, but if there were atleast a very basic support for that, then all those silly language feature maniacs like yourself could have the Ruby or whatever in the same type.

    Thanks for listening!

  6. Joku, wait till you see C#3.0 🙂 or try out the review (CTP) from http://msdn.microsoft.com/vcsharp/future/default.aspx

  7. Sverre says:

    Yes please give C# parallel assignment (and by this also the possibility to return multiple values from a function)!

    My number 1 wish for the language.

Skip to main content