Atomicity of tuple assigment


Tuples in C# have been present since version 4.0 as a library without any language support. C# 7.0 finally introduces proper language integration of tuples. For example, the syntax to create a tuple is simply:

var pair = (1,2);

Deconstructing is also supported:

var (x,y) = pair;

Combining these two features lets us use tuple assignment to swap variables:

(a,b) = (b,a);

Which is almost equivalent to, but more compact and more explicit than, the following:

var temp = a;
a = b;
b = temp;

This behaviour of tuple is akin to atomicity, indeed the left-hand side variables, are only assigned to once all the right-hand side ones have been evaluated. In pseudo syntax of my transactional model we would have:

transaction {
  a = b;
  b = a;
}

where a and b are both semi-mutable variables, hence changes would only be visible after the atomic block. Or in standard C# syntax:

var tempA = a;
var tempB = b;
a = tempB;
b = tempaA;

The tuple assignment syntax to swap two variables simplifies some standard algorithms such as the partitioning in the quick sort algorithm:

    public int Partition(int[] v, int low, int high) {
        var p = v[high];
        var i = low-1;
        for (int k = low; k < high; k++) {
            if (v[k] < p) {                
                i++;
                if (i != k) {
                    (v[i], v[k]) = (v[k], v[i]);
                }
            }
        }
        i++;
        (v[i], v[high]) = (v[high], v[i]);
        return i ;
    }

where the big advantage is that there is no need to use a temporary value or to worry about the order of the various node references are assigned. The downside is readability which decreases as the number of variables increases.

Other algorithms which manipulate linked list can also benefit from this syntax, for example the partitioning of a linked list can be written as:

    private ListNode partition(ListNode node, int value) {
        if (node == null) return null;
        ListNode head = node;
        while (node.next != null) {
            if (node.next.value < value) {
                (node.next, node.next.next, head) = (node.next.next, head, node.next);
            } else {
                node = node.next;
            }
        }
        return head;
    }

where the big advantage is that there is no need to use a temporary value or to worry about the order of the various node references are assigned. The downside is readability which decreases as the number of variables increases.

In terms of atomicity of this assignment operation in case of exceptions, exceptions thrown while evaluating the right-hand side will result in none of the left-hand side value being assigned to. However, if any setter in the left-hand side throws, we can end-up with partially assigned values:

(c.r,c.i) = (1,2);

if the setter of c.i throws an exception, only c.r will have been assigned to, leaving c.i unassigned.

Albeit this assignment is only partially atomic, I find it useful in algorithms where is various variables or properties are swapped around.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google+ photo

You are commenting using your Google+ account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s

Awelon Blue

Thoughts on Programming Experience Design

Joe Duffy's Blog

Adventures in the High-tech Underbelly

Design Matters

Furniture design blog from Design Matters author George Walker

Shavings

A Blog for Woodworkers by Gary Rogowski

Paul Sellers' Blog

– A Lifestyle Woodworker –

randallnatomagan

Woodworking, life and all things between

%d bloggers like this: