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:
[x] I have searched both open and closed suggestions and proposals on this site and believe this is not a duplicate.
[x] I believe that the spirit of this suggestion is aligned with the design principles and general vision for Q#.
Please tick all that apply:
[ ] This is not a breaking change to the Q# language design
[x] I or my organization would be willing to help implement and/or test this
Suggestion
Q# supports two distinct syntaxes for creating arrays: square brackets like
[1, 2, 3]
, and thenew
keyword likenew Int[3]
. When an array is created using thenew
keyword, all elements are initialized to a default value based on the type. The syntax to create arrays usingnew
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
andT1 -> 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: whilenew 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 (specificallynull
) 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 createnull
values of types likeResult
,String
, and evenUnit
. 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.Affidavit (please fill out)
Please add ticks by placing a cross in the box:
Please tick all that apply: