microsoft / qsharp-language

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

copy-and-update expression is very cryptic #169

Open GabrieleMessina opened 8 months ago

GabrieleMessina commented 8 months ago

Hi, I'm a master's student in computer science, and i'm currently taking a course about Quantum Computing. Seeing that I'm interested in programming language design and that i was positively impressed by the gap between Q# and other existing languages for Quantum Computing, i was hoping i could help with the development. So, i’d like to start by suggesting a change to the current language specification.

Considerations

I think the current syntax for the copy-and-update expression is very cryptic.

 mutable arr = [0, size = 3]; // arr contains [0,0,0]
 set arr w/= 0 <- 10; // arr contains [10,0,0] 

It would be better to have something closer to natural language; The optimal solution would be to keep the syntax:

 mutable arr = [0, size = 3]; // arr contains [0,0,0]
 set arr[0] = 10; // arr contains [10,0,0] 

Which is still considered correct for non-array type variable like in this case:

 mutable foo = 0; // foo contains 0
 set foo = 10; // foo contains 10

Context

I also understand the motivation behind this choice which can be found here. Still, i think that a good trade-off between not misleading syntax and a readable/maintainable one can be found, so let's explore some other options:

mutable arr = [0, size = 3];
set arr = [10, arr[1..]]; // make the new array allocation explicit

//or
mutable arr = [0, size = 3];
set arr with (i) -> i == 0 ? 10 | arr[i]; // make the new array allocation explicit through lambda with array index as parameter

//or
mutable arr = [0, size = 3];
set arr with (_arr) -> _arr[0] = 10; // make the new array allocation explicit through lambda with a new copy of the array as a parameter

Examples I think the second option is the best because if we were passing the same array as a parameter, developers could think that changing a value inside the lambda parameter would affect the original array.

So, for multidimensional arrays that would be:

mutable arr = [[0, size = 3][1, size = 2]];
set arr with (i, j) -> i == 0 ? 10 | arr[i]; // make the new array allocation explicit through lambda with array indexes as parameter

While for not array type that would be:

mutable foo = 0;
set foo with () -> 10; // same syntax for non-array type to drop inconsistency 

and this could become the only way to update a mutable variable even when the variable is not an array. This could be useful to drop the inconsistency between array and not-array mutable variables update.

Affidavit (please fill out)

Please add ticks by placing a cross in the box:

Please tick all that apply: