microsoft / qsharp-language

Official repository for design of the quantum programming language Q# and its core libraries
MIT License
235 stars 56 forks source link

Remove "new T[n]" syntax for creating arrays #46

Closed bamarsha closed 3 years ago

bamarsha commented 3 years ago

Suggestion

Q# supports two distinct syntaxes for creating arrays: square brackets like [1, 2, 3], and the new keyword like new Int[3]. When an array is created using the new keyword, all elements are initialized to a default value based on the type. The syntax to create arrays using new should be removed from the language.

Considerations

The existence of new T[n] has negative effects on the language.

The most important negative effect is the assumption that every type has a default value. This is not a reasonable assumption, because it is not possible to define useful default values of types like Qubit and T1 -> T2. Their current default values are invalid and will trigger an error if they are used. Yet the syntax is the same both for types with valid default values, and those without, which is misleading: while new Int[3] is a perfectly well-defined value whose elements can be used immediately, new Qubit[3] creates a potential trap that will crash the program if any value in the array is used.

This assumption is also invalid in the presence of uninhabited types such as Void. If Q# requires that every type has a default value, then uninhabited types are impossible to express properly. This can even cause bugs in the soundness of a type system, as demonstrated by this bug in Java's generics that happened because of the existence of a value (specifically null) for a type that should have been uninhabited.

Q#'s default values also caused a subtle bug in the Q# runtime: because the default values required by Q# do not always match the default values of the corresponding C# types (according to C#'s default keyword), it is possible to create null values of types like Result, String, and even Unit. See microsoft/qsharp-runtime#359.

Finally, the use of the new keyword is inconsistent with other ways to create values in Q#. new is required only when creating a default-initialized array, not when using a square bracket array literal or when creating values of other types.

Context

See microsoft/qsharp-compiler#589 for a more detailed discussion about default values and alternatives to the new T[n] syntax.

Examples

There are functions in the standard library that can create arrays instead of using the new T[n] syntax.

// Instead of:
let empty = new Int[0];
let results = new Result[5];

// Use:
let empty = EmptyArray<Int>();
let results = ConstantArray(5, Zero);

Affidavit (please fill out)

Please add ticks by placing a cross in the box:

Please tick all that apply: