There is an old joke that one day a cat jumped on a keyboard and that’s how Perl was invented. If you ever worked with array updates in Q#, you have certainly felt the pain of the syntax. At least for me, it was always a source of confusion and frustration. It was one of those things, like regular expressions, that I needed to look up every time - and then I would immediately forget it again. And I consider myself to be quite proficient in Q#!
Last week Q# 1.17 was released, and one of the great changes included was a new syntax for array updates.
Current syntax π
The old syntax for updating an array in Q# was a bit cumbersome. You had to use the set keyword, and than use the awkward indexing mechanism.
Consider the following three zeroes array:
// [0, 0, 0]
mutable arr1 = [0, size = 3];
Now, let’s imagine we’d like to update the second element of this array to 5. The old syntax would look like this:
set arr1 w/= 1 <- 5;
This syntax is not only verbose, but also quite unintuitive. The w/= part is particularly confusing, as it looks like a division operation, but it actually means “write to the array” at index n.
It actually gets worse when you deal with multi-dimensional arrays. Consider a 3-dimensional array of strings, like this one here:
mutable arr2 = [[["a", "b", "c"], ["d", "e", "f"]], [["g", "h", "i"], ["j", "k", "l"]]];
Let’s say that we want to update the last entry of the last array to “x”. The old syntax would look like this:
set arr2 w/= 1 <- (arr2[1] w/ 1 <- (arr2[0][1] w/ 2 <- "x"));
This is terribly unreadable and hard to follow. The nested indexing and the w/ syntax make it very difficult to understand what is happening. Let’s break it down:
- arr2[0][1] w/ 2 <- “x” - Takes the array [“d”, “e”, “f”] and creates a new array with the element at index 2 replaced with “x”, resulting in [“d”, “e”, “x”]
- arr2[1] w/ 1 <- (…) - Takes the array [[“g”, “h”, “i”], [“j”, “k”, “l”]] and creates a new array with the element at index 1 replaced with the result from step 1, so the second inner array [“j”, “k”, “l”] becomes [“d”, “e”, “x”]
- set arr2 w/= 1 <- (…) - Updates the mutable variable arr2 by replacing the element at index 1 with the result from step 2
Phew.
New and updated syntax π
Looking at the release notes for Q# 1.17, there is little mention of the new array update syntax. There are sections about “OpenQASM support”, Copilot stuff and Circuit rendering. Then there is an uncospicuous list of other changes, that simply contains an auto-generated list of 73 closed PRs.
41st (!) item in that list is an entry Support Array Update Syntax by @ScottCarda-MS in #2414, which is the one we are interested in. And thank you Scott for this change! It is not a big change, but it is a very welcome one. It makes the Q# language much more pleasant to work with.
The new syntax is much more intuitive and readable - resembling the standard array update syntax from most other programming languages. For our two cases, it would look like this:
mutable arr1 = [0, size = 3];
set arr1[1] = 5;
mutable arr2 = [[["a", "b", "c"], ["d", "e", "f"]], [["g", "h", "i"], ["j", "k", "l"]]];
set arr2[1][1][2] = "x";
This is much simpler, isn’t it? You can use this syntax straight away when upgrading to Q# 1.17. It is also supported in the Q#, such as the Azure Quantum Development Kit (QDK) for VS Code - also version 1.17.
PS. This blog post was written by a cat that jumped on my keyboard. I just had to fix a few typos and add some links. And the array syntax is so much better now, I don’t even need to look it up anymore! π±