├── Specifications ├── Language │ ├── 3_Expressions │ │ ├── Identifiers.md │ │ ├── LogicalExpressions.md │ │ ├── Concatentation.md │ │ ├── BitwiseExpressions.md │ │ ├── ArithmeticExpressions.md │ │ ├── ConditionalExpressions.md │ │ ├── Iterations.md │ │ ├── ComparativeExpressions.md │ │ ├── ConditionalBranching.md │ │ ├── CallExpressions.md │ │ ├── README.md │ │ ├── ReturnsAndTermination.md │ │ ├── ConditionalLoops.md │ │ ├── Conjugations.md │ │ ├── ContextualExpressions.md │ │ ├── FunctorApplication.md │ │ ├── Closures.md │ │ ├── ItemAccessExpressions.md │ │ ├── CopyAndUpdateExpressions.md │ │ ├── ValueLiterals.md │ │ └── PrecedenceAndAssociativity.md │ ├── 1_ProgramStructure │ │ ├── 5_Attributes.md │ │ ├── 6_AccessModifiers.md │ │ ├── 2_TypeDeclarations.md │ │ ├── 7_Comments.md │ │ ├── 1_Namespaces.md │ │ ├── README.md │ │ ├── 3_CallableDeclarations.md │ │ └── 4_SpecializationDeclarations.md │ ├── 4_TypeSystem │ │ ├── SingletonTupleEquivalence.md │ │ ├── Immutability.md │ │ ├── TypeInference.md │ │ ├── QuantumDataTypes.md │ │ ├── SubtypingAndVariance.md │ │ ├── README.md │ │ ├── OperationsAndFunctions.md │ │ └── TypeParameterizations.md │ ├── 5_Grammar │ │ ├── README.md │ │ ├── QSharpLexer.g4 │ │ └── QSharpParser.g4 │ ├── 2_Statements │ │ ├── README.md │ │ ├── BindingScopes.md │ │ ├── QuantumMemoryManagement.md │ │ └── VariableDeclarationsAndReassignments.md │ └── README.md └── sync-script │ ├── setup.py │ ├── README.md │ └── replace_links.py ├── .github ├── ISSUE_TEMPLATE │ ├── question.md │ ├── documentation.md │ ├── implementation.md │ └── suggestion.md └── workflows │ └── replace_links.yml ├── Implemented └── README.md ├── Approved └── README.md ├── Declined └── README.md ├── CITATIONS.bib ├── CODE_OF_CONDUCT.md ├── LICENSE.txt ├── Templates ├── suggestion.md └── proposal.md ├── Guidelines.md ├── CoreLibraries ├── ReviewNotes │ └── api-design-2020-07-24.md └── review-process.md ├── SECURITY.md ├── FAQ.md ├── .gitignore └── README.md /Specifications/Language/3_Expressions/Identifiers.md: -------------------------------------------------------------------------------- 1 | 2 | 3 | ← [Back to Index](https://github.com/microsoft/qsharp-language/tree/main/Specifications/Language#index) -------------------------------------------------------------------------------- /Specifications/Language/1_ProgramStructure/5_Attributes.md: -------------------------------------------------------------------------------- 1 | 2 | 3 | ← [Back to Index](https://github.com/microsoft/qsharp-language/tree/main/Specifications/Language#index) -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/question.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Question 3 | about: Ask a question 4 | title: '' 5 | labels: Question 6 | assignees: '' 7 | 8 | --- 9 | 10 | 11 | -------------------------------------------------------------------------------- /Specifications/Language/1_ProgramStructure/6_AccessModifiers.md: -------------------------------------------------------------------------------- 1 | 2 | 3 | ← [Back to Index](https://github.com/microsoft/qsharp-language/tree/main/Specifications/Language#index) -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/documentation.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Documentation 3 | about: File an issue related to the specs and docs maintained on this repo 4 | title: '' 5 | labels: Documentation 6 | assignees: '' 7 | 8 | --- 9 | 10 | 11 | -------------------------------------------------------------------------------- /Implemented/README.md: -------------------------------------------------------------------------------- 1 | # Implemented Language Proposals 2 | 3 | This folder contains the proposals for features that have been implemented and are part of the latest Q# version. The corresponding specifications can be found [here](https://github.com/microsoft/qsharp-language/tree/main/Specifications/Language). 4 | -------------------------------------------------------------------------------- /Specifications/sync-script/setup.py: -------------------------------------------------------------------------------- 1 | from setuptools import setup 2 | 3 | setup( 4 | name = 'ReplaceLinks', 5 | version = '1.0', 6 | py_modules = ['replace_links'], 7 | install_requires=['Click',], 8 | entry_points=''' 9 | [console_scripts] 10 | replace_links=replace_links:main 11 | ''' 12 | ) -------------------------------------------------------------------------------- /Approved/README.md: -------------------------------------------------------------------------------- 1 | # Approved Language Proposals 2 | 3 | This folder contains the proposals for features that have been approved in principle. These features are ready to be implemented. Once they are picked up for implementation, the corresponding issue marked with the `Implementation` label will be filed on this repository to track the progress and discuss any needs for modification of the corresponding proposal. 4 | 5 | -------------------------------------------------------------------------------- /Declined/README.md: -------------------------------------------------------------------------------- 1 | # Declined Language Proposals 2 | 3 | This folder contains the proposals for features that have been declined. While we do our best to give early feedback regarding whether or not a feature aligns with the general vision for Q# and its design principles, in some cases the decision is ultimately made based on the more detailed considerations that are part of a full proposal. These proposals are archived here for future reference. 4 | 5 | 6 | -------------------------------------------------------------------------------- /CITATIONS.bib: -------------------------------------------------------------------------------- 1 | BibTeX: 2 | 3 | @manual{QsSpec2020, 4 | title = {Q\# {Language Specification}}, 5 | author = {Microsoft}, 6 | year = {2020}, 7 | url = {https://github.com/microsoft/qsharp-language/tree/main/Specifications/Language#q-language}, 8 | } 9 | 10 | BiBLaTeX: 11 | 12 | @manual{QsSpec2020, 13 | title = {Q\# {Language Specification}}, 14 | organization = {Microsoft}, 15 | date = {2020}, 16 | url = {https://github.com/microsoft/qsharp-language/tree/main/Specifications/Language#q-language} 17 | } 18 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/implementation.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Implementation 3 | about: Create an issue to track the implementation of an approved feature 4 | title: '' 5 | labels: Implementation 6 | assignees: '' 7 | 8 | --- 9 | 10 | **Implementation** 11 | 12 | TODO: 13 | Please link the approved proposal that you would like to implement. 14 | 15 | *Work items* 16 | 17 | TODO: 18 | Please create a list of the work items that need to be completed, and update the status as it progresses. 19 | * [ ] Add links to feature branch(es) to this issue 20 | * [ ] ... 21 | * [ ] Merge to main 22 | * [ ] Update the Q# language specification 23 | -------------------------------------------------------------------------------- /Specifications/Language/4_TypeSystem/SingletonTupleEquivalence.md: -------------------------------------------------------------------------------- 1 | # Singleton tuple equivalence 2 | 3 | To avoid any ambiguity between tuples and parentheses that group sub-expressions, a tuple with a single element is considered to be equivalent to the contained item, including its type. For example, the types `Int`, `(Int)`, and `((Int))` are treated as being identical. The same holds true for the values `5`, `(5)` and `(((5)))`, or for `(5, (6))` and `(5, 6)`. This equivalence applies for all purposes, including assignment. Since there is no dynamic dispatch or reflection in Q# and all types in Q# are resolvable at compile-time, singleton tuple equivalence can be readily implemented during compilation. 4 | 5 | 6 | ← [Back to Index](https://github.com/microsoft/qsharp-language/tree/main/Specifications/Language#index) -------------------------------------------------------------------------------- /Specifications/Language/3_Expressions/LogicalExpressions.md: -------------------------------------------------------------------------------- 1 | # Logical expressions 2 | 3 | Logical operators are expressed as keywords. 4 | Q# supports the standard logical operators *AND* (`and`), *OR* (`or`), and *NOT* (`not`). Currently, there is not an operator for a logical *XOR*. All of these operators act on operands of type `Bool`, and result in an expression of type `Bool`. 5 | As is common in most languages, the evaluation of *AND* and *OR* short-circuits, meaning if the first expression of *OR* evaluates to `true`, the second expression is not evaluated, and the same holds if the first expression of *AND* evaluates to `false`. The behavior of conditional expressions in a sense is similar, in that only ever the condition and one of the two expressions is evaluated. 6 | 7 | ← [Back to Index](https://github.com/microsoft/qsharp-language/tree/main/Specifications/Language#index) 8 | -------------------------------------------------------------------------------- /Specifications/Language/5_Grammar/README.md: -------------------------------------------------------------------------------- 1 | # Grammar 2 | 3 | A reference implementation of the Q# grammar is available in the [ANTLR4](https://www.antlr.org/) format. 4 | The grammar source files are listed here: 5 | 6 | * [**QSharpLexer.g4**](https://github.com/microsoft/qsharp-language/blob/main/Specifications/Language/5_Grammar/QSharpLexer.g4) describes the lexical structure of Q#. 7 | * [**QSharpParser.g4**](https://github.com/microsoft/qsharp-language/blob/main/Specifications/Language/5_Grammar/QSharpParser.g4) describes the syntax of Q#. 8 | 9 | ## Target language 10 | 11 | The ANTLR grammar contains some embedded C# code. 12 | It looks like this (enclosed in curly braces): 13 | 14 | ```antlr 15 | BraceRight : '}' { if (ModeStack.Count > 0) PopMode(); }; 16 | ``` 17 | 18 | If you want to generate a parser for a target language other than C#, you will need to change these code snippets. 19 | -------------------------------------------------------------------------------- /Specifications/Language/3_Expressions/Concatentation.md: -------------------------------------------------------------------------------- 1 | # Concatenation 2 | 3 | Concatenations are supported for values of type `String` and arrays. In both cases they are expressed via the operator `+`. For instance, `"Hello " + "world!"` evaluates to `"Hello world!"`, and `[1, 2, 3] + [4, 5, 6]` evaluates to `[1, 2, 3, 4, 5, 6]`. 4 | 5 | Concatenating two arrays requires that both arrays be of the same type, in contrast to constructing an [array literal](https://github.com/microsoft/qsharp-language/blob/main/Specifications/Language/3_Expressions/ValueLiterals.md#array-literals) where a common base type for all array items is determined. This is because arrays are treated as [invariant](https://github.com/microsoft/qsharp-language/blob/main/Specifications/Language/4_TypeSystem/SubtypingAndVariance.md#subtyping-and-variance). The type of the entire expression matches the type of the operands. 6 | 7 | ← [Back to Index](https://github.com/microsoft/qsharp-language/tree/main/Specifications/Language#index) 8 | -------------------------------------------------------------------------------- /CODE_OF_CONDUCT.md: -------------------------------------------------------------------------------- 1 | 2 | # Contributing 3 | 4 | This project welcomes contributions and suggestions. Most contributions require you to agree to a 5 | Contributor License Agreement (CLA) declaring that you have the right to, and actually do, grant us 6 | the rights to use your contribution. For details, visit https://cla.opensource.microsoft.com. 7 | 8 | When you submit a pull request, a CLA bot will automatically determine whether you need to provide 9 | a CLA and decorate the PR appropriately (e.g., status check, comment). Simply follow the instructions 10 | provided by the bot. You will only need to do this once across all repos using our CLA. 11 | 12 | # Microsoft Open Source Code of Conduct 13 | 14 | This project has adopted the [Microsoft Open Source Code of Conduct](https://opensource.microsoft.com/codeofconduct/). 15 | For more information see the [Code of Conduct FAQ](https://opensource.microsoft.com/codeofconduct/faq/) or 16 | contact [opencode@microsoft.com](mailto:opencode@microsoft.com) with any additional questions or comments. 17 | 18 | -------------------------------------------------------------------------------- /Specifications/Language/3_Expressions/BitwiseExpressions.md: -------------------------------------------------------------------------------- 1 | # Bitwise expressions 2 | 3 | Bitwise operators are expressed as three non-letter characters. In addition to bitwise versions for *AND* (`&&&`), *OR* (`|||`), and *NOT* (`~~~`), a bitwise *XOR* (`^^^`) exists as well. They expect operands of type `Int` or `BigInt`, and for binary operators, the type of both operands has to match. The type of the entire expression equals the type of the operand(s). 4 | 5 | Additionally, left- and right-shift operators (`<<<` and `>>>` respectively) exist, multiplying or dividing the given left-hand-side (lhs) expression by powers of two. The expression `lhs <<< 3` shifts the bit representation of `lhs` by three, meaning `lhs` is multiplied by `2^3`, provided that is still within the valid range for the data type of `lhs`. The lhs may be of type `Int` or `BigInt`. The right-hand-side expression always has to be of type `Int`. The resulting expression will be of the same type as the lhs operand. 6 | 7 | ← [Back to Index](https://github.com/microsoft/qsharp-language/tree/main/Specifications/Language#index) 8 | -------------------------------------------------------------------------------- /LICENSE.txt: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) Microsoft Corporation. 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE 22 | -------------------------------------------------------------------------------- /.github/workflows/replace_links.yml: -------------------------------------------------------------------------------- 1 | name: Replace links with uids in copy branch 2 | 3 | on: 4 | push: 5 | branches: [ main ] 6 | 7 | jobs: 8 | build: 9 | runs-on: windows-latest 10 | steps: 11 | - uses: actions/checkout@master 12 | with: 13 | persist-credentials: false # otherwise, the token used is the GITHUB_TOKEN, instead of your personal token 14 | fetch-depth: 0 # otherwise, you will failed to push refs to dest repo 15 | - name: Commit changes 16 | run: | 17 | git config --local user.email "action@github.com" 18 | git config --local user.name "GitHub Action" 19 | $ThisCommit = "${{ github.sha }}" 20 | git checkout ⭐Docs 21 | git reset --hard $ThisCommit 22 | pip install ./Specifications/sync-script 23 | replace_links https://raw.githubusercontent.com/MicrosoftDocs/quantum-docs/main/articles/user-guide/language/uid-map.csv ./Specifications/Language/ 24 | git add . 25 | git commit -m "Automatic switch of links to xrefs" -a 26 | shell: pwsh 27 | 28 | - name: Push changes 29 | uses: ad-m/github-push-action@master 30 | with: 31 | github_token: ${{ secrets.GITHUB_TOKEN }} 32 | force: true 33 | branch: ⭐Docs 34 | 35 | -------------------------------------------------------------------------------- /Specifications/sync-script/README.md: -------------------------------------------------------------------------------- 1 | ## Script to adapt the documents for the official docs page 2 | 3 | ### Description of the process 4 | 5 | #### Files 6 | 7 | There are 4 relevant files: 8 | 9 | - `uid-map.csv`: this is a `*.csv` file containing the map between paths and uids that Brad created. This file can be hosted anywhere as long the link is accessible. I recommend storing this file in the same folder as the stub files, so any modification or addition can be easily reflected in the map. 10 | 11 | - `replace_links.yml`: a `*.yml` file containing the workflow for the GitHub action that is described below. This file is in `.github/workflows`. 12 | 13 | - `setup.py`: python file to install the Click command-line application. 14 | 15 | - `replace_links.py`: python script that imports the map from the url where the .csv file is hosted and replaces the files in a specific path. 16 | 17 | 18 | 19 | #### Workflow 20 | 21 | First, there are at least two different branches, `main` and a copy of main where we are going to host the uid version of the docs (`⭐Docs`). The GitHub Actions workflow does the following: 22 | 23 | 1. Opens a Windows console and checkouts to the repository. 24 | 1. Resets the `⭐Docs` branch to match `main`. 25 | 1. Installs the script and runs it through a click command. 26 | 1. Commits and pushes the changes to `⭐Docs`. 27 | -------------------------------------------------------------------------------- /Templates/suggestion.md: -------------------------------------------------------------------------------- 1 | 7 | 8 | # Suggestion 9 | 10 | TODO: 11 | Insert a short outline for what the proposed modification is. 12 | 13 | ## Considerations 14 | 15 | TODO: 16 | Explain why this modification to the Q# language is desirable. 17 | Briefly summarize the benefits and drawbacks of the chosen mechanism opposed to other ways of achieving a similar functionality. 18 | 19 | ## Context 20 | 21 | TODO: 22 | Describe briefly the most important points to consider in more detail going forward. 23 | Link to related suggestions, proposals, specs, documentation or other related topics. 24 | 25 | ## Examples 26 | 27 | TODO: 28 | Give concrete examples for syntax and behavior to illustrate the suggestions above. 29 | 30 | Example 1: 31 | TODO: insert title and caption 32 | 33 | ```qsharp 34 | // TODO: 35 | // Insert code example that illustrates what is described above. 36 | // Comment your code to further elaborate and clarify the example. 37 | ``` 38 | 39 | # Affidavit (please fill out) 40 | 41 | Please add ticks by placing a cross in the box: 42 | * [ ] I have searched both open and closed suggestions and proposals on this site and believe this is not a duplicate. 43 | * [ ] I believe that the spirit of this suggestion is aligned with the design principles and general vision for Q#. 44 | 45 | Please tick all that apply: 46 | * [ ] This is not a breaking change to the Q# language and all current features remain as they are 47 | * [ ] I or my organization would be willing to help implement and/or test this 48 | 49 | 50 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/suggestion.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Suggestion 3 | about: Suggest a new feature 4 | title: '' 5 | labels: '' 6 | assignees: '' 7 | 8 | --- 9 | 10 | **Suggestion** 11 | 12 | TODO: 13 | Insert a short outline for what the proposed modification is. 14 | 15 | *Considerations* 16 | 17 | TODO: 18 | Explain why this modification to the Q# language is desirable. 19 | Briefly summarize the benefits and drawbacks of the chosen mechanism opposed to other ways of achieving a similar functionality. 20 | 21 | *Context* 22 | 23 | TODO: 24 | Describe briefly the most important points to consider in more detail going forward. 25 | Link to related suggestions, proposals, specs, documentation or other related topics. 26 | 27 | *Examples* 28 | 29 | TODO: 30 | Give concrete examples for syntax and behavior to illustrate the suggestions above. 31 | 32 | Example 1: 33 | TODO: insert title and caption 34 | 35 | ```qsharp 36 | // TODO: 37 | // Insert code example that illustrates what is described above. 38 | // Comment your code to further elaborate and clarify the example. 39 | ``` 40 | 41 | **Affidavit (please fill out)** 42 | 43 | Please add ticks by placing a cross in the box: 44 | * [ ] I have searched both open and closed suggestions and proposals on this site and believe this is not a duplicate. 45 | * [ ] I believe that the spirit of this suggestion is aligned with the design principles and general vision for Q#. 46 | 47 | Please tick all that apply: 48 | * [ ] This is not a breaking change to the Q# language design 49 | * [ ] I or my organization would be willing to help implement and/or test this 50 | -------------------------------------------------------------------------------- /Specifications/Language/3_Expressions/ArithmeticExpressions.md: -------------------------------------------------------------------------------- 1 | # Arithmetic expressions 2 | 3 | Arithmetic operators are addition (`+`), subtraction (`-`), multiplication (`*`), division (`/`), negation (`-`), and exponentiation (`^`). They can be applied to operands of type `Int`, `BigInt`, or `Double`. Additionally, for integral types (`Int` and `BigInt`), an operator computing the modulus (`%`) is available. 4 | 5 | For binary operators, the type of both operands must match, except for exponentiation; an exponent for a value of type `BigInt` must be of type `Int`. The type of the entire expression matches the type of the left operand. For exponentiation of `Int` and `BitInt`, the behavior is undefined if the exponent is negative or requires more than 32 bits to represent (that is, if it is larger than 2147483647). 6 | 7 | Division and modulus for values of type `Int` and `BigInt` follow the following behavior for 8 | negative numbers: 9 | 10 | `A` | `B` | `A / B` | `A % B` 11 | ---------|----------|---------|--------- 12 | 5 | 2 | 2 | 1 13 | 5 | -2 | -2 | 1 14 | -5 | 2 | -2 | -1 15 | -5 | -2 | 2 | -1 16 | 17 | That is, `a % b` always has the same sign as `a`, and `b * (a / b) + a % b` always equals `a`. 18 | 19 | Q# does not support automatic conversions between arithmetic data types or any other data types for that matter. This is of importance especially for the `Result` data type and facilitates restricting how runtime information can propagate. It has the benefit of avoiding accidental errors, such as ones related to precision loss. 20 | 21 | ← [Back to Index](https://github.com/microsoft/qsharp-language/tree/main/Specifications/Language#index) 22 | -------------------------------------------------------------------------------- /Specifications/Language/3_Expressions/ConditionalExpressions.md: -------------------------------------------------------------------------------- 1 | # Conditional expressions 2 | 3 | Conditional expressions consist of three sub-expressions, where the left-most sub-expression is of type `Bool` and determines which one of the two other sub-expressions is evaluated. They are of the form 4 | 5 | ```qsharp 6 | cond ? ifTrue | ifFalse 7 | ``` 8 | 9 | Specifically, if `cond` evaluates to `true`, then the conditional expression evaluates to the `ifTrue` expression; otherwise, it evaluates to the `ifFalse` expression. The other expression (the `ifFalse` and `ifTrue` expression, respectively) is never evaluated, much like the branches in an `if` statement. 10 | For instance, in an expression `a == b ? C(qs) | D(qs)`, if `a` equals `b`, then the callable `C` is invoked. Otherwise, `D` is invoked. 11 | 12 | The types of the `ifTrue` and the `ifFalse` expression have to have a [common base type](https://github.com/microsoft/qsharp-language/blob/main/Specifications/Language/4_TypeSystem/SubtypingAndVariance.md#subtyping-and-variance). Independent of which one ultimately yields the value to which the expression evaluates, its type always matches the determined base type. 13 | 14 | For example, if 15 | 16 | - `Op1` is of type `Qubit[] => Unit is Adj` 17 | - `Op2` is of type `Qubit[] => Unit is Ctl` 18 | - `Op3` is of type `Qubit[] => Unit is Adj + Ctl` 19 | 20 | then 21 | 22 | - `cond ? Op1 | Op2` is of type `Qubit[] => Unit` 23 | - `cond ? Op1 | Op3` is of type `Qubit[] => Unit is Adj` 24 | - `cond ? Op2 | Op3` is of type `Qubit[] => Unit is Ctl` 25 | 26 | For more details, see [subtyping](https://github.com/microsoft/qsharp-language/blob/main/Specifications/Language/4_TypeSystem/SubtypingAndVariance.md#subtyping-and-variance). 27 | 28 | ← [Back to Index](https://github.com/microsoft/qsharp-language/tree/main/Specifications/Language#index) 29 | -------------------------------------------------------------------------------- /Guidelines.md: -------------------------------------------------------------------------------- 1 | # Considerations and Guidelines 2 | 3 | There are several considerations that factor into design decisions for the Q# language and core libraries. The ease of adoption, the benefit over time, the cost of implementation and maintenance, alternative approaches, etc. are but a few examples. 4 | Rather than attempting to compile an exhaustive list, we present some rough guidelines that may give a first impression for things we want to be mindful of. For the API design of the core libraries, please also take a look at the [style guide](https://github.com/microsoft/qsharp-language/tree/main/CoreLibraries/style-guide.md). 5 | 6 | ## Try to 7 | 8 | - Maximize the utility of a new feature and syntax 9 | - Develop features that are useful for a wide range of use cases and audiences 10 | - Evolve the language in a predictable manner; consider how a feature will evolve with future versions of Q# 11 | - Enhance consistency, intuitiveness, and readability 12 | - Enable modularity and encapsulation 13 | - Be mindful of how a feature can be executed on quantum hardware 14 | - Reduce the development effort and burden on the developer 15 | - ... 16 | 17 | ## Avoid 18 | 19 | - Introducing functionality that cannot be supported on quantum hardware unless it serves debugging purposes 20 | - Requiring the developer to be familiar with the details of the quantum hardware architecture 21 | - Deferring errors until runtime 22 | - Introducing multiple ways to achieve the same thing 23 | - Making breaking changes 24 | - Suggesting features that are slight variations of features that have been declined previously 25 | - ... 26 | 27 | 28 | Our goal is to achieve stability for each major version; meaning that any changes should not break existing code written in an earlier Q# version with the same major number. However, we may potentially deprecate certain pieces over time, and remove support for them when releasing the next major version. -------------------------------------------------------------------------------- /Specifications/Language/2_Statements/README.md: -------------------------------------------------------------------------------- 1 | # Statements 2 | 3 | Q# distinguishes between statements and expressions. Q# programs consist of a mixture of classical and quantum computations, and the implementation looks much like any other classical programming language. Some statements, such as the `let` and `mutable` bindings, are well-known from classical languages, while others, such qubit allocations, are unique to the quantum domain. 4 | 5 | The following statements are currently available in Q#: 6 | 7 | * **Expression statement** 8 | Contains a Q# expression to be run, such as a call to an operation. If the last statement in a block is an expression statement, it may have its trailing semicolon omitted to give the block the evaluated value of the contained expression. 9 | 10 | * **Variable declaration** 11 | Defines one or more local variables that are valid for the remainder of the current scope, and binds them to the specified values. Variables can be permanently bound or declared to be reassignable later on. See [Variable declarations and reassignments](https://github.com/microsoft/qsharp-language/blob/main/Specifications/Language/2_Statements/VariableDeclarationsAndReassignments.md#variable-declarations-and-reassignments) for more details. 12 | 13 | * **Qubit allocation** 14 | Instantiates and initializes qubits, or arrays of qubits, and binds them to the declared variables. The statement can optionally be used with a specified block of code, in which the qubit allocations are valid. Otherwise the allocations are valid for the enclosing scope. Qubits are automatically released at the end of the appropriate scope. 15 | See [Quantum memory management](https://github.com/microsoft/qsharp-language/blob/main/Specifications/Language/2_Statements/QuantumMemoryManagement.md#quantum-memory-management) for more details. 16 | 17 | ← [Back to Index](https://github.com/microsoft/qsharp-language/tree/main/Specifications/Language#index) 18 | -------------------------------------------------------------------------------- /Specifications/Language/3_Expressions/Iterations.md: -------------------------------------------------------------------------------- 1 | # Iterations 2 | 3 | Loops that iterate over a sequence of values are expressed as `for` loops in Q#. A `for` loop in Q# does not break based on a condition but instead corresponds to an iteration, or what is often expressed as `foreach` or `iter` in other languages. There are currently two data types in Q# that support iteration: arrays and ranges. 4 | 5 | The expression consists of the keyword `for`, followed by a symbol or symbol tuple, the keyword `in`, an expression of array or `Range` type, and a statement block. 6 | 7 | The statement block (the body of the loop) is run repeatedly, with one or more loop variables bound to each value in the range or array. The same deconstruction rules apply to the defined loop variables as to any other variable assignment, such as bindings in `let`, `mutable`, `set`, `use` and `borrow` statements. The loop variables themselves are immutably bound, cannot be reassigned within the body of the loop, and go out of scope when the loop terminates. 8 | The expression over which the loop iterates is evaluated before entering the loop and does not change while the loop is running. 9 | 10 | This is illustrated in the following example. Suppose `qubits` is a value of type `Qubit[]`, then 11 | 12 | ```qsharp 13 | for qubit in qubits { 14 | H(qubit); 15 | } 16 | 17 | mutable results : (Int, Result)[] = []; 18 | for index in 0 .. Length(qubits) - 1 { 19 | set results += [(index, M(qubits[index]))]; 20 | } 21 | 22 | mutable accumulated = 0; 23 | for (index, measured) in results { 24 | if measured == One { 25 | set accumulated += 1 <<< index; 26 | } 27 | } 28 | ``` 29 | 30 | ## Target-specific restrictions 31 | 32 | Because there are no `break` or `continue` primitives in Q#, the length of the loop is known as soon as the iteration value is known. As such, `for` loops can be run on all quantum hardware. 33 | 34 | ← [Back to Index](https://github.com/microsoft/qsharp-language/tree/main/Specifications/Language#index) 35 | -------------------------------------------------------------------------------- /Specifications/Language/3_Expressions/ComparativeExpressions.md: -------------------------------------------------------------------------------- 1 | # Comparative expressions 2 | 3 | ## Equality comparisons 4 | 5 | *Equality comparisons* (`==`) and *inequality comparisons* (`!=`) are currently limited to the following data types: `Int`, `BigInt`, `Double`, `String`, `Bool`, `Result`, `Pauli`, and `Qubit`. Equality comparisons of user-defined types and callables are currently not supported. 6 | 7 | Equality comparison for values of type `Qubit` evaluates whether the two expressions identify the same qubit. There is no notion of a quantum state in Q#; equality comparison, in particular, does *not* access, measure, or modify the quantum state of the qubits. 8 | 9 | Equality comparisons for `Double` values may be misleading due to rounding effects. 10 | For instance, the following comparison evaluates to `false` due to rounding errors: `49.0 * (1.0/49.0) == 1.0`. 11 | 12 | Equality comparison of arrays, and tuples are supported by comparisons of their items, and are only supported if all of their nested types support equality comparison. 13 | 14 | Equality comparison of close-ended ranges are supported, and two ranges are considered equal if they produce the same sequence of integers. For example, the following two ranges 15 | 16 | ```qsharp 17 | let r1 = 0..2..5; // generates the sequence 0,2,4 18 | let r2 = 0..2..4; // generates the sequence 0,2,4 19 | ``` 20 | 21 | are considered equal. Equality comparison of open-ended ranges are not supported. 22 | 23 | ## Quantitative comparison 24 | 25 | The operators *less-than* (`<`), *less-than-or-equal* (`<=`), *greater-than* (`>`), and *greater-than-or-equal* (`>=`) define quantitative comparisons. They can only be applied to data types that support such comparisons, that is, the same data types that can also support [arithmetic expressions](https://github.com/microsoft/qsharp-language/blob/main/Specifications/Language/3_Expressions/ArithmeticExpressions.md#arithmetic-expressions). 26 | 27 | ← [Back to Index](https://github.com/microsoft/qsharp-language/tree/main/Specifications/Language#index) 28 | -------------------------------------------------------------------------------- /Specifications/Language/4_TypeSystem/Immutability.md: -------------------------------------------------------------------------------- 1 | # Immutability 2 | 3 | All types in Q# are *value types*. Q# does not have a concept of a reference or pointer. Instead, it allows you to reassign a new value to a previously declared variable via a `set` statement. For example, there is no distinction in behavior between reassignments for variables of type `Int` or variables of type `Int[]`. Consider the following sequence of statements: 4 | 5 | ```qsharp 6 | mutable arr1 = new Int[3]; 7 | let arr2 = arr1; 8 | set arr1 w/= 0 <- 3; 9 | ``` 10 | 11 | The first statement instantiates a new array of integers `[0,0,0]` and assigns it to `arr1`. 12 | The next statement assigns that value to a variable with name `arr2`. The last statement creates a new array instance based on `arr1` with the same values except for the value at index 0 which is set to 3. The newly created array is then assigned to the variable `arr1`. The last line makes use of the abbreviated syntax for [evaluate-and-reassign statements](https://github.com/microsoft/qsharp-language/blob/main/Specifications/Language/2_Statements/VariableDeclarationsAndReassignments.md#evaluate-and-reassign-statements), and could equivalently have been written as `set arr1 = arr1 w/ 0 <- 1;`. 13 | After running the three statements, `arr1` will contain the value `[3,0,0]` while `arr2` remains unchanged and contains the value `[0,0,0]`. 14 | 15 | 16 | Q# clearly thus distinguishes the mutability of a handle and the behavior of a type. 17 | Mutability within Q# is a concept that applies to a *symbol* rather than a type or value; 18 | it applies to the handle that allows you to access a value rather than to the value itself. It is *not* represented in the type system, implicitly or explicitly. 19 | 20 | Of course, this is merely a description of the formally defined behavior; under the hood, the actual implementation uses a reference counting scheme to avoid copying memory as much as possible. 21 | The modification is specifically done in place as long as there is only one currently valid handle that accesses a certain value. 22 | 23 | 24 | ← [Back to Index](https://github.com/microsoft/qsharp-language/tree/main/Specifications/Language#index) 25 | -------------------------------------------------------------------------------- /Specifications/Language/4_TypeSystem/TypeInference.md: -------------------------------------------------------------------------------- 1 | # Type inference 2 | 3 | Q#'s type inference algorithm is based on inference algorithms designed for the Hindley-Milner type system. 4 | While top-level callables must be declared with explicit type annotations, most types used within a callable can be inferred. 5 | For example, given these callables: 6 | 7 | ```qsharp 8 | function Length<'a>(xs : 'a[]) : Int 9 | function Mapped<'a, 'b>(f : 'a -> 'b, xs : 'a[]) : 'b[] 10 | ``` 11 | 12 | and this expression: 13 | 14 | ```qsharp 15 | Mapped(Length, [[], ["a"], ["b", "c"]]) 16 | ``` 17 | 18 | then the type argument to `Length` is inferred to be `Length`, and the type arguments to `Mapped` are inferred to be `Mapped`. 19 | It is not required to write these types explicitly. 20 | 21 | ## Ambiguous types 22 | 23 | Sometimes there is not one single principal type that can be inferred for a type variable. 24 | In these cases, type inference fails with an error referring to an ambiguous type. 25 | For example, change the previous example slightly: 26 | 27 | ```qsharp 28 | Mapped(Length, [[]]) 29 | ``` 30 | 31 | What is the type of `[[]]`? 32 | In some type systems, it's possible to give it the type `∀a. a[][]`, but this is not supported in Q#. 33 | A concrete type is required, but there are an infinite number of types that work: `String[][]`, `(Int, Int)[][]`, `Double[][][]`, and so on. 34 | You must explicitly say which type you meant. 35 | 36 | There are multiple ways to do this, depending on the situation. 37 | For example: 38 | 39 | 1. Call `Length` with a type argument. 40 | 41 | ```qsharp 42 | Mapped(Length, [[]]) 43 | ``` 44 | 45 | 2. Call `Mapped` with its first type argument. 46 | (The `_` for its second type argument means that it should still be inferred.) 47 | 48 | ```qsharp 49 | Mapped(Length, [[]]) 50 | ``` 51 | 52 | 3. Replace the empty array literal with an explicitly-typed call to a library function. 53 | 54 | ```qsharp 55 | Mapped(Length, [EmptyArray()]) 56 | ``` 57 | 58 | --- 59 | 60 | ← [Back to Index](https://github.com/microsoft/qsharp-language/tree/main/Specifications/Language#index) 61 | -------------------------------------------------------------------------------- /Specifications/Language/3_Expressions/ConditionalBranching.md: -------------------------------------------------------------------------------- 1 | # Conditional branching 2 | 3 | Conditional branching is expressed in the form of `if` expressions. An `if` expression consists of an `if` clause, followed by zero or more `elif` clauses and optionally an else-block. Each clause follows the pattern 4 | 5 | ```qsharp 6 | keyword condition { 7 | 8 | } 9 | ``` 10 | 11 | where `keyword` is replaced with `if` or `elif` respectively, `condition` is an expression of type `Bool`, and `` is to be replaced with zero or more statements. The optional `else`-block consists of the keyword `else` followed by zero or more statements enclosed in braces, `{` `}`. 12 | 13 | The first block for which the `condition` evaluates to `true` will run. The `else` block, if present, runs if none of the conditions evaluate to `true`. The block is executed in its own scope, meaning any bindings made as part of the block are not visible after the block ends. 14 | 15 | For example, suppose `qubits` is value of type `Qubit[]` and `r1` and `r2` are of type `Result`, 16 | 17 | ```qsharp 18 | if r1 == One { 19 | let q = qubits[0]; 20 | H(q); 21 | } 22 | elif r2 == One { 23 | let q = qubits[1]; 24 | H(q); 25 | } 26 | else { 27 | H(qubits[2]); 28 | } 29 | ``` 30 | 31 | You can also express simple branching in the form of a [conditional expression](https://github.com/microsoft/qsharp-language/blob/main/Specifications/Language/3_Expressions/ConditionalExpressions.md#conditional-expressions). 32 | 33 | ## Target-specific restrictions 34 | 35 | The tight integration between control-flow constructs and quantum computations poses a challenge for current quantum hardware. Certain quantum processors do not support branching based on measurement outcomes. As such, comparison for values of type `Result` will always result in a compilation error for Q# programs that are targeted to run on such hardware. 36 | 37 | Other quantum processors support specific kinds of branching based on measurement outcomes. The more general `if` expressions supported in Q# are compiled into suitable instructions that can be run on such processors. The imposed restrictions are that values of type `Result` may only be compared as part of the condition within `if` expressions in operations. Furthermore, the conditionally run blocks cannot contain any `return` expressions or update mutable variables that are declared outside that block. 38 | 39 | ← [Back to Index](https://github.com/microsoft/qsharp-language/tree/main/Specifications/Language#index) 40 | -------------------------------------------------------------------------------- /Specifications/Language/3_Expressions/CallExpressions.md: -------------------------------------------------------------------------------- 1 | # Call expressions 2 | 3 | Call expressions are an important part of any programming language. Operation and function calls, much like [partial applications](https://github.com/microsoft/qsharp-language/blob/main/Specifications/Language/3_Expressions/Closures.md#partial-application), can be used as an expression anywhere as long as the returned value is of a suitable type. 4 | 5 | The usefulness of calling operations in this form primarily lies in debugging, and such operation calls are one of the most common constructs in any Q# program. At the same time, operations can only be called from within other operations and not from within functions. For more information, see also [Qubits](https://github.com/microsoft/qsharp-language/blob/main/Specifications/Language/4_TypeSystem/QuantumDataTypes.md#qubits). 6 | 7 | With callables being first-class values, call expressions are a generic way of supporting patterns that aren't common enough to merit their own dedicated language construct, or dedicated syntax has not (yet) been introduced for other reasons. Some examples of library methods that serve that purpose are `ApplyIf`, which invokes an operation conditional on a classical bit being set; `ApplyToEach`, which applies a given operation to each element in an array; and `ApplyWithInputTransformation`, as shown in the following sample. 8 | 9 | ```qsharp 10 | operation ApplyWithInputTransformation<'TArg, 'TIn>( 11 | fn : 'TIn -> 'TArg, 12 | op : 'TArg => Unit, 13 | input : 'TIn 14 | ) : Unit { 15 | 16 | op(fn(input)); 17 | } 18 | ``` 19 | 20 | `ApplyWithInputTransformation` takes a function `fn`, an operation `op`, and an `input` value as arguments and then applies the given function to the input before invoking the given operation with the value returned from the function. 21 | 22 | For the compiler to auto-generate the specializations to support particular [functors](https://github.com/microsoft/qsharp-language/blob/main/Specifications/Language/3_Expressions/FunctorApplication.md#functor-application), it usually requires that the called operations support those functors as well. The two exceptions are calls in outer blocks of [conjugations](https://github.com/microsoft/qsharp-language/blob/main/Specifications/Language/3_Expressions/Conjugations.md#conjugations), which always need to support the `Adjoint` functor but never need to support the `Controlled` functor, and self-adjoint operations, which support the `Adjoint` functor without imposing any additional requirements on the individual calls. 23 | 24 | ← [Back to Index](https://github.com/microsoft/qsharp-language/tree/main/Specifications/Language#index) 25 | -------------------------------------------------------------------------------- /CoreLibraries/ReviewNotes/api-design-2020-07-24.md: -------------------------------------------------------------------------------- 1 | # Q# API Design Meeting / 24 July 2020 2 | Attendees (in order by username): @bettinaheim, @cgranade, @efratshabtai, @msoeken. 3 | 4 | ## Agenda 5 | 6 | - New `Microsoft.Quantum.Random` namespace 7 | 8 | ## Discussion 9 | 10 | Proposal: https://github.com/microsoft/QuantumLibraries/issues/304 11 | 12 | - This proposal requires changes to the `QSharpCore` project in the qsharp-runtime repo, and thus should be done as soon as possible to help manage dependency. 13 | - How difficult would it be to adapt simulation runtime and translators? Should be fine, as runtime changes localized to `SimulatorBase`. 14 | - **Resolution:** Create issue on qsharp-runtime to track needed modifications to QSharpCore and `SimulatorBase`. 15 | 16 | - Impact on / from Q# language discussions: 17 | - Possible language discussion area: type classes. 18 | - E.g.: Cannot meaningfully compare equality on callables, so even equality requires type-class–like concept. 19 | - Q# API design should consider what reasonable type classes may look like. 20 | 21 | - API for target machines to expose random seed setting. 22 | - For Q# standalone implementation, should we propagate the random seed settings via project properties? 23 | - Inappropriate to expose at Q# level, since not all targets need expose a PRNG at all; could be QRNG-backed. 24 | - The proposed API intentionally does not distinguish between an engine that produces randomness, and distributions based on that source of randomness. 25 | - **Resolution:** Proposal unmodified, as random seeds are simulator-specific and shouldn't be exposed at Q# level. 26 | 27 | - No distribution over complex numbers in current proposal. 28 | - Should we introduce `ComplexDistribution`? 29 | - Ensure coverage for all reasonable arithmetic data types (e.g.: `BigDiscreteDistribution`, eventually `Distribution`). 30 | Current arithmetic data types in Q#: 31 | - `Fraction`, `BigFraction` 32 | - `Complex`, `ComplexPolar` 33 | - `Int`, `BigInt` 34 | - `Double` 35 | - Don't try to be minimal, but aim for coverage. Minimal only in sense that isn't redundant. 36 | - **Resolution:** Proposal modified to improve coverage of arithmetic data types. 37 | 38 | - Introducing new arithmetic UDTs comes at a large cost: need to support in all future arithmetic APIs. Opportunity to improve existing support to better cover `BigInt` (https://github.com/microsoft/QuantumLibraries/issues/95). 39 | - **Proposal**: Adopt as API design principle that functionality should cover all relevant built-in and standard library types. 40 | 41 | **Consensus**: 42 | - The proposed API changes are reasonable and meet with Q# design principles. -------------------------------------------------------------------------------- /Specifications/Language/3_Expressions/README.md: -------------------------------------------------------------------------------- 1 | # Expressions 2 | 3 | At the core, Q# expressions are either [value literals](https://github.com/microsoft/qsharp-language/blob/main/Specifications/Language/3_Expressions/ValueLiterals.md) or [identifiers](https://github.com/microsoft/qsharp-language/blob/main/Specifications/Language/3_Expressions/Identifiers.md#identifiers), where identifiers can refer to either locally declared variables or to globally declared callables (there are currently no global constants in Q#). 4 | Operators, combinators, and modifiers can be used to combine these into a wider variety of expressions. 5 | 6 | - *Operators* in a sense are nothing but dedicated syntax for particular callables. 7 | >Even though Q# is not yet expressive enough to formally capture the capabilities of each operator in the form of a backing callable declaration, that should be remedied in the future. 8 | 9 | - *Modifiers* can only be applied to certain expressions. One or more modifiers can be applied to expressions that are either identifiers, array item access expressions, named item access expressions, or an expression within parenthesis which is the same as a single item tuple (see [this section](https://github.com/microsoft/qsharp-language/blob/main/Specifications/Language/4_TypeSystem/SingletonTupleEquivalence.md#singleton-tuple-equivalence)). 10 | They can either precede (prefix) the expression or follow (postfix) the expression. They are thus special unary operators that bind tighter than function or operation calls, but less tight than any kind of item access. 11 | Concretely, [functors](https://github.com/microsoft/qsharp-language/blob/main/Specifications/Language/3_Expressions/FunctorApplication.md#functor-application) are prefix modifiers, whereas the [unwrap operator](https://github.com/microsoft/qsharp-language/blob/main/Specifications/Language/3_Expressions/ItemAccessExpressions.md#item-access-for-user-defined-types) is a postfix modifier. 12 | 13 | - Like modifiers, function and operation calls as well as item access can be seen as a special kind of operator subject to the same restrictions regarding where they can be applied; we refer to them as *combinators*. 14 | 15 | The section on [precedence and associativity](https://github.com/microsoft/qsharp-language/blob/main/Specifications/Language/3_Expressions/PrecedenceAndAssociativity.md) contains a complete [list of all operators](https://github.com/microsoft/qsharp-language/blob/main/Specifications/Language/3_Expressions/PrecedenceAndAssociativity.md#operators) as well as a complete [list of all modifiers and combinators](https://github.com/microsoft/qsharp-language/blob/main/Specifications/Language/3_Expressions/PrecedenceAndAssociativity.md#modifiers-and-combinators). 16 | 17 | 18 | ← [Back to Index](https://github.com/microsoft/qsharp-language/tree/main/Specifications/Language#index) 19 | -------------------------------------------------------------------------------- /SECURITY.md: -------------------------------------------------------------------------------- 1 | 2 | 3 | ## Security 4 | 5 | Microsoft takes the security of our software products and services seriously, which includes all source code repositories managed through our GitHub organizations, which include [Microsoft](https://github.com/Microsoft), [Azure](https://github.com/Azure), [DotNet](https://github.com/dotnet), [AspNet](https://github.com/aspnet), [Xamarin](https://github.com/xamarin), and [our GitHub organizations](https://opensource.microsoft.com/). 6 | 7 | If you believe you have found a security vulnerability in any Microsoft-owned repository that meets [Microsoft's definition of a security vulnerability](https://aka.ms/opensource/security/definition), please report it to us as described below. 8 | 9 | ## Reporting Security Issues 10 | 11 | **Please do not report security vulnerabilities through public GitHub issues.** 12 | 13 | Instead, please report them to the Microsoft Security Response Center (MSRC) at [https://msrc.microsoft.com/create-report](https://aka.ms/opensource/security/create-report). 14 | 15 | If you prefer to submit without logging in, send email to [secure@microsoft.com](mailto:secure@microsoft.com). If possible, encrypt your message with our PGP key; please download it from the [Microsoft Security Response Center PGP Key page](https://aka.ms/opensource/security/pgpkey). 16 | 17 | You should receive a response within 24 hours. If for some reason you do not, please follow up via email to ensure we received your original message. Additional information can be found at [microsoft.com/msrc](https://aka.ms/opensource/security/msrc). 18 | 19 | Please include the requested information listed below (as much as you can provide) to help us better understand the nature and scope of the possible issue: 20 | 21 | * Type of issue (e.g. buffer overflow, SQL injection, cross-site scripting, etc.) 22 | * Full paths of source file(s) related to the manifestation of the issue 23 | * The location of the affected source code (tag/branch/commit or direct URL) 24 | * Any special configuration required to reproduce the issue 25 | * Step-by-step instructions to reproduce the issue 26 | * Proof-of-concept or exploit code (if possible) 27 | * Impact of the issue, including how an attacker might exploit the issue 28 | 29 | This information will help us triage your report more quickly. 30 | 31 | If you are reporting for a bug bounty, more complete reports can contribute to a higher bounty award. Please visit our [Microsoft Bug Bounty Program](https://aka.ms/opensource/security/bounty) page for more details about our active programs. 32 | 33 | ## Preferred Languages 34 | 35 | We prefer all communications to be in English. 36 | 37 | ## Policy 38 | 39 | Microsoft follows the principle of [Coordinated Vulnerability Disclosure](https://aka.ms/opensource/security/cvd). 40 | 41 | 42 | -------------------------------------------------------------------------------- /Specifications/Language/3_Expressions/ReturnsAndTermination.md: -------------------------------------------------------------------------------- 1 | # Returns and termination 2 | 3 | There are two expressions available that conclude the execution of the current subroutine or the program; the `return` and the `fail` expressions. Generally, callables may end their execution before executing all of their statements with a `return` or `fail` expression. A `return` expression will just end the execution of the current callalbe, while a `fail` will end the execution of the whole program and result in a runtime error. 4 | 5 | ## Return expression 6 | 7 | The `return` expression exits from the current callable and returns control to the callee. It changes the context of the execution by popping a stack frame. 8 | 9 | The expression always returns a value to the context of the callee; it consists of the keyword `return`, followed by an expression of the appropriate type. The return value is evaluated before any terminating actions are performed and control is returned. Terminating actions include, for example, cleaning up and releasing qubits that are allocated within the context of the callable. When running on a simulator or validator, terminating actions often also include checks related to the state of those qubits, for example, whether they are properly disentangled from all qubits that remain live. 10 | 11 | The `return` expression at the end of a callable that returns a `Unit` value may be omitted. In that case, control is returned automatically when all statements have run and all terminating actions have been performed. Callables may contain multiple `return` expressions, albeit the adjoint implementation for operations containing multiple `return` expressions cannot be automatically generated. 12 | 13 | For example, 14 | 15 | ```qsharp 16 | return 1; 17 | ``` 18 | 19 | or 20 | 21 | ```qsharp 22 | return (); 23 | ``` 24 | 25 | ## Fail expression 26 | 27 | The `fail` expression ends the computation entirely. It corresponds to a fatal error that aborts the program. 28 | 29 | It consists of the keyword `fail`, followed by an expression of type `String`. 30 | The `String` should provide information about the encountered failure. 31 | 32 | For example, 33 | 34 | ```qsharp 35 | fail "Impossible state reached"; 36 | ``` 37 | 38 | or, using an [interpolated string](https://github.com/microsoft/qsharp-language/blob/main/Specifications/Language/3_Expressions/ValueLiterals.md#string-literals), 39 | 40 | ```qsharp 41 | fail $"Syndrome {syn} is incorrect"; 42 | ``` 43 | 44 | In addition to the given `String`, a `fail` expression ideally collects and permits the retrieval of information about the program state. This facilitates diagnosing and remedying the source of the error, and requires support from the executing runtime and firmware, which may vary across different targets. 45 | 46 | ← [Back to Index](https://github.com/microsoft/qsharp-language/tree/main/Specifications/Language#index) 47 | -------------------------------------------------------------------------------- /Specifications/Language/2_Statements/BindingScopes.md: -------------------------------------------------------------------------------- 1 | # Binding scopes 2 | 3 | In general, symbol bindings in Q# become inoperative at the end of the statement block they occur in. However, there are some exceptions to this rule. 4 | 5 | ## Visibility of local variables 6 | 7 | | Scope | Visibility | 8 | |------|-----| 9 | | Loop variables |Bindings of loop variables in a [`for`](https://github.com/microsoft/qsharp-language/blob/main/Specifications/Language/3_Expressions/Iterations.md#iterations) loop are defined only for the body of the loop. They are inoperative outside of the loop. | 10 | | [`use`](https://github.com/microsoft/qsharp-language/blob/main/Specifications/Language/2_Statements/QuantumMemoryManagement.md#quantum-memory-management) and [`borrow`](https://github.com/microsoft/qsharp-language/blob/main/Specifications/Language/2_Statements/QuantumMemoryManagement.md#quantum-memory-management) statements |Bindings of allocated qubits in `use` and `borrow` statements are defined for the body of the allocation, and are inoperative after the statement terminates. This only applies to `use` and `borrow` statements that have an associated statement block.| 11 | | [`repeat`](https://github.com/microsoft/qsharp-language/blob/main/Specifications/Language/3_Expressions/ConditionalLoops.md#conditional-loops) expressions |For `repeat` expressions, both blocks, as well as the condition, are treated as a single scope, that is, symbols that are bound in the body are accessible in both the condition and in the `fixup` block. | 12 | | Loops |Each iteration of a loop runs in its own scope, and all defined variables are bound anew for each iteration. | 13 | 14 | Bindings in outer blocks are visible and defined in inner blocks. 15 | A symbol may only be bound multiple times per block in which case the last binding in scope is the one used for logic. This is known as "shadowing". 16 | 17 | The following sequences are valid: 18 | 19 | ```qsharp 20 | if a == b { 21 | ... 22 | let n = 5; 23 | ... // n is 5 24 | } 25 | let n = 8; 26 | ... // n is 8 27 | ``` 28 | 29 | and 30 | 31 | ```qsharp 32 | if a == b { 33 | ... 34 | let n = 5; 35 | ... // n is 5 36 | } else { 37 | ... 38 | let n = 8; 39 | ... // n is 8 40 | } 41 | ... // n is not bound to a value 42 | ``` 43 | 44 | ```qsharp 45 | let n = 5; 46 | ... // n is 5 47 | let n = 8; 48 | ... // n is 8 49 | ``` 50 | 51 | and 52 | 53 | ```qsharp 54 | let n = 8; 55 | if a == b { 56 | ... // n is 8 57 | let n = 5; 58 | ... // n is 5 59 | } 60 | ... // n is 8 again 61 | ``` 62 | 63 | For more details, see [Variable Declarations and Reassignments](https://github.com/microsoft/qsharp-language/blob/main/Specifications/Language/2_Statements/VariableDeclarationsAndReassignments.md#variable-declarations-and-reassignments). 64 | 65 | ← [Back to Index](https://github.com/microsoft/qsharp-language/tree/main/Specifications/Language#index) 66 | -------------------------------------------------------------------------------- /Specifications/sync-script/replace_links.py: -------------------------------------------------------------------------------- 1 | #!/bin/env python 2 | # -*- coding: utf-8 -*- 3 | ## 4 | # replace_links.py: replaces the relevant links with uid cross references. 5 | # Copyright (c) Microsoft Corporation. All rights reserved. 6 | # Licensed under the MIT License. 7 | ## 8 | 9 | """ 10 | Replaces GitHub links with uid cross references for the files specified 11 | in a uid-map.csv file. This script is used to create a usable copy of 12 | the files for the documentation repository. 13 | 14 | """ 15 | import click 16 | import csv 17 | from urllib.request import urlopen 18 | import os 19 | 20 | @click.command() 21 | @click.argument("URL_MAP") 22 | @click.argument("SOURCE_DIR") 23 | def main(url_map: str, source_dir: str): 24 | map_link_to_uid = extract_csv(url_map) 25 | links_to_xrefs(source_dir, map_link_to_uid) 26 | remove_index(source_dir) 27 | 28 | def extract_csv(url_map) -> dict: 29 | f = urlopen(url_map) 30 | lines = [l.decode('utf-8') for l in f.readlines()] 31 | reader = csv.reader(lines) 32 | csv_file = dict(reader) 33 | return csv_file 34 | 35 | def links_to_xrefs(source_dir, map_link_to_uid): 36 | for subdir, dirs, files in os.walk(source_dir): 37 | for filename in files: 38 | filepath = subdir + os.sep + filename 39 | if filepath.endswith(".md"): 40 | with open(filepath, "rt", encoding='utf-8') as f: 41 | text = f.readlines() 42 | new_text = [] 43 | for line in text: 44 | for url in map_link_to_uid: 45 | uid = map_link_to_uid[url] 46 | # Handle both /blob/ and /tree/ links 47 | full_blob_url = 'https://github.com/microsoft/qsharp-language/blob/main/Specifications/Language/'+url 48 | full_tree_url = 'https://github.com/microsoft/qsharp-language/tree/main/Specifications/Language/'+url 49 | full_uid = 'xref:' + uid 50 | line = line.replace(full_blob_url, full_uid) 51 | line = line.replace( 52 | '← [Back to Index](https://github.com/microsoft/qsharp-language/tree/main/Specifications/Language#index)', '') 53 | line = line.replace( 54 | 'https://docs.microsoft.com', '') 55 | line = line.replace(full_tree_url, full_uid) 56 | new_text.append(line) 57 | with open(filepath, "wt", encoding='utf-8') as f: 58 | for line in new_text: 59 | f.write(line) 60 | 61 | def remove_index(source_dir): 62 | lines = open(source_dir + 'README.md').readlines() 63 | f = open(source_dir + 'README.md', 'w') 64 | for line in lines: 65 | if "## Index" in line: 66 | break 67 | else: 68 | f.writelines(line) 69 | f.close() 70 | 71 | if __name__ == "__main__": 72 | main() 73 | -------------------------------------------------------------------------------- /Specifications/Language/1_ProgramStructure/2_TypeDeclarations.md: -------------------------------------------------------------------------------- 1 | # Type Declarations 2 | 3 | Q# supports user-defined types. User-defined types are similar to record types in F#; they are immutable but support a [copy-and-update](https://github.com/microsoft/qsharp-language/blob/main/Specifications/Language/3_Expressions/CopyAndUpdateExpressions.md) construct. 4 | 5 | ## User-defined types 6 | 7 | User-defined types may contain both named and anonymous items. 8 | The following declaration within a namespace, for example, defines a type `Complex` which has two named items `Real` and `Imaginary`, both of type `Double`: 9 | 10 | ```qsharp 11 | newtype Complex = (Real: Double, Imaginary : Double); 12 | ``` 13 | 14 | Any combination of named and unnamed items is supported, and inner items may also be named. 15 | For example, the type `Nested`, defined as 16 | 17 | ```qsharp 18 | newtype Nested = (Double, (ItemName : Int, String)); 19 | ``` 20 | 21 | contains two anonymous items of type `Double` and `String` respectively, and a named item `ItemName` of type `Int`. 22 | 23 | You can access the contained items via their name or by *deconstruction* (for more information, see [item access](https://github.com/microsoft/qsharp-language/blob/main/Specifications/Language/3_Expressions/ItemAccessExpressions.md#item-access-for-user-defined-types)). 24 | You can also access a tuple of all items where the shape matches the one defined in the declaration via the [unwrap operator](https://github.com/microsoft/qsharp-language/blob/main/Specifications/Language/3_Expressions/ItemAccessExpressions.md#item-access-for-user-defined-types). 25 | 26 | User-defined types are useful for two reasons. First, 27 | as long as the libraries and programs that use the defined types access items via their name rather than by deconstruction, the type can be extended to contain additional items later on without breaking any library code. Because of this, accessing items via deconstruction is generally discouraged. 28 | 29 | Second, Q# allows you to convey the intent and expectations for a specific data type since there is no automatic conversion between values of two user-defined types, even if their item types are identical. 30 | 31 | For example, the arithmetic library includes quantum arithmetic operations for both big-endian and little-endian quantum integers. 32 | It hence defines two types, `BigEndian` and `LittleEndian`, both of which contain a single anonymous item of type `Qubit[]`: 33 | 34 | ```qsharp 35 | newtype BigEndian = Qubit[]; 36 | newtype LittleEndian = Qubit[]; 37 | ``` 38 | 39 | These types allow operations to specify whether they are written for big-endian or little-endian representations and leverages the type system to ensure at compile-time that mismatched operands aren't allowed. 40 | 41 | ## User-defined constructors 42 | 43 | >Constructors for user-defined types are automatically generated by the compiler. Currently, it is not possible to define a custom constructor, though this may be an addition to the language in the future. 44 | 45 | ← [Back to Index](https://github.com/microsoft/qsharp-language/tree/main/Specifications/Language#index) 46 | -------------------------------------------------------------------------------- /Specifications/Language/3_Expressions/ConditionalLoops.md: -------------------------------------------------------------------------------- 1 | # Conditional loops 2 | 3 | Like most classical programming languages, Q# supports loops that break based on a condition: loops for which the number of iterations is unknown and may vary from run to run. Since the instruction sequence is unknown at compile-time, the compiler handles these conditional loops in a particular way in a quantum runtime. 4 | 5 | As long as the condition does not depend on quantum measurements, conditional loops are processed with a just-in-time compilation before sending the instruction sequence to the quantum processor. 6 | In particular, using conditional loops within functions is unproblematic since code within functions can always run on conventional (non-quantum) hardware. Q#, therefore, supports the use of traditional `while` loops within functions. 7 | 8 | Q# also allows you to express control flow that depends on the results of quantum measurements. 9 | This capability enables probabilistic implementations that can significantly reduce computational costs. 10 | A common example is the *repeat-until-success* pattern, which repeats a computation until a certain condition - which usually depends on a measurement - is satisfied. Such `repeat` loops are widely used in particular classes of quantum algorithms. Q# hence has a dedicated language construct to express them, despite that they still pose a challenge for execution on quantum hardware. 11 | 12 | ## Repeat expression 13 | 14 | The `repeat` expression takes the following form 15 | 16 | ```qsharp 17 | repeat { 18 | // ... 19 | } 20 | until condition 21 | fixup { 22 | // ... 23 | } 24 | ``` 25 | 26 | or alternatively 27 | 28 | ```qsharp 29 | repeat { 30 | // ... 31 | } 32 | until condition; 33 | ``` 34 | 35 | where `condition` is an arbitrary expression of type `Bool`. 36 | 37 | The `repeat` loop runs a block of statements before evaluating a condition. If the condition evaluates to true, the loop exits. If the condition evaluates to false, an additional block of statements defined as part of an optional `fixup` block, if present, is run prior to entering the next loop iteration. 38 | 39 | ### Target-specific restrictions 40 | 41 | Loops that break based on a condition are challenging to process on quantum hardware if the condition depends on measurement outcomes since the length of the instruction sequence to run is not known ahead of time. 42 | 43 | Despite their common presence in particular classes of quantum algorithms, current hardware does not yet provide native support for these kinds of control flow constructs. Running on quantum hardware can potentially be supported in the future by imposing a maximum number of iterations, or as additional hardware support becomes available. 44 | 45 | ## While loop 46 | 47 | A more familiar-looking loop for classical computations is the `while` loop, which consists of the keyword `while`, an expression of type `Bool`, and a statement block. 48 | For example, if `arr` is an array of positive integers, 49 | 50 | ```qsharp 51 | mutable (item, index) = (-1, 0); 52 | while index < Length(arr) && item < 0 { 53 | set item = arr[index]; 54 | set index += 1; 55 | } 56 | ``` 57 | 58 | The statement block is run as long as the condition evaluates to `true`. 59 | 60 | ← [Back to Index](https://github.com/microsoft/qsharp-language/tree/main/Specifications/Language#index) 61 | -------------------------------------------------------------------------------- /Specifications/Language/4_TypeSystem/QuantumDataTypes.md: -------------------------------------------------------------------------------- 1 | # Quantum-specific data types 2 | 3 | This topic describes the `Qubit` type, along with two other types that are somewhat specific to the quantum domain: `Pauli` and `Result`. 4 | 5 | ## Qubit 6 | 7 | Q# treats qubits as opaque items that can be passed to both functions and operations, but can only be interacted with by passing them to instructions that are native to the targeted quantum processor. Such instructions are always defined in the form of operations, since their intent is to modify the quantum state. 8 | The restriction that functions cannot modify the quantum state, despite the fact that qubits can be passed as input arguments, is enforced by the requiring that functions can only call other functions, and cannot call operations. 9 | 10 | The Q# libraries are compiled against a standard set of intrinsic operations, meaning operations which have no definition for their implementation within the language. 11 | Upon targeting, the implementations that express them in terms of the instructions that are native to the execution target are linked in by the compiler. 12 | A Q# program thus combines these operations as defined by a target machine to create new, 13 | higher-level operations to express quantum computation. 14 | In this way, Q# makes it very easy to express the logic underlying quantum and hybrid quantum-classical 15 | algorithms, while also being very general with respect to the structure of a target machine and its 16 | realization of quantum state. 17 | 18 | Within Q# itself, there is no type or construct in Q# that represents the quantum state. 19 | Instead, a qubit represents the smallest addressable physical unit in a quantum computer. 20 | As such, a qubit is a long-lived item, so Q# has no need for linear types. 21 | Hence, we do not explicitly refer to the state within Q#, 22 | but rather describe how the state is transformed by the program, for example, via the application of operations such as `X` and `H`. 23 | Similar to how a graphics shader program accumulates a description of transformations to each vertex, a quantum program in Q# accumulates transformations to quantum states, 24 | represented as entirely opaque references to the internal structure of a target machine. 25 | 26 | A Q# program has no ability to introspect into the state of a qubit, 27 | and thus is entirely agnostic about what a quantum state is or on how it is realized. 28 | Rather, a program can call operations such as `Measure` to learn information about the quantum state of the computation. 29 | 30 | ## Pauli 31 | 32 | Values of type `Pauli` specify a single-qubit Pauli operator; the possibilities are `PauliI`, `PauliX`, `PauliY`, and `PauliZ`. `Pauli` values are used primarily to specify the basis for a quantum measurement. 33 | 34 | ## Result 35 | 36 | The `Result` type specifies the result of a quantum measurement. Q# mirrors most quantum hardware by providing measurements in products of single-qubit Pauli operators; a `Result` of `Zero` indicates that the +1 eigenvalue was measured, and a `Result` of `One` indicates that the -1 eigenvalue was measured. That is, Q# represents eigenvalues by the power to which -1 is raised. 37 | This convention is more common in the quantum algorithms community, as it maps more closely to classical bits. 38 | 39 | ← [Back to Index](https://github.com/microsoft/qsharp-language/tree/main/Specifications/Language#index) -------------------------------------------------------------------------------- /Specifications/Language/3_Expressions/Conjugations.md: -------------------------------------------------------------------------------- 1 | # Conjugations 2 | 3 | Conjugations are common in quantum computations. In mathematical terms, they are patterns of the form *U†VU* for two unitary transformations *U* and *V*. That pattern is relevant due to the particularities of quantum memory: computations build up quantum correlations, or *entanglement*, to leverage the unique assets of quantum. However, that also means that once a subroutine no longer needs its qubits, those qubits cannot easily be reset and released since observing their state would impact the rest of the system. For that reason, the effect of a previous computation usually needs to be reversed before releasing and reusing quantum memory. 4 | 5 | Q# hence has a dedicated construct for expressing computations that require such a cleanup. The expressions consists of two code blocks, one containing the implementation of *U* and one containing the implementation of *V*. The *uncomputation* (that is, the application of *U†*) is done automatically as part of the expression. 6 | 7 | The expression takes the form 8 | 9 | ```qsharp 10 | within { 11 | 12 | } 13 | apply { 14 | 15 | } 16 | ``` 17 | 18 | where `` is replaced with any number of statements defining the implementation of *U* and *V* respectively. 19 | Both blocks may contain arbitrary classical computations, aside from the usual restrictions for automatically generating adjoint versions that apply to the `within` block. Mutably bound variables used as part of the `within` block may not be reassigned as part of the `apply` block. 20 | 21 | The example of the `ApplyXOrIfGreater` operation defined in the arithmetic library illustrates the usage of such a conjugation: 22 | The operation maps |lhs⟩|rhs⟩|res⟩ → |lhs⟩|rhs⟩|res ⊕ (lhs>rhs)⟩, that is, it coherently applies an XOR to a given qubit `res` if the quantum integer represented by `lhs` is greater than the one in `rhs`. The two integers are represented in little-endian encoding, as indicated by the usage of the corresponding data type. 23 | 24 | ```qsharp 25 | operation ApplyXOrIfGreater( 26 | lhs : LittleEndian, 27 | rhs : LittleEndian, 28 | res : Qubit 29 | ) : Unit is Adj + Ctl { 30 | 31 | let (x, y) = (lhs!, rhs!); 32 | let shuffled = Zip3(Most(x), Rest(y), Rest(x)); 33 | 34 | use anc = Qubit(); 35 | within { 36 | ApplyToEachCA(X, x + [anc]); 37 | ApplyMajorityInPlace(x[0], [y[0], anc]); 38 | ApplyToEachCA(MAJ, shuffled); 39 | } 40 | apply { 41 | X(res); 42 | CNOT(Tail(x), res); 43 | } 44 | } 45 | ``` 46 | 47 | The temporary storage qubit `anc` is automatically cleaned up before it is released at the end of the operation. The statements in the `within` block are applied first, followed by the statements in the `apply` block, and finally, the automatically generated adjoint of the `within` block is applied to clean up the temporary qubit `anc`. 48 | 49 | > [!NOTE] 50 | > Returning control from within the `apply` block is not yet supported. However, it may be supported in the future. The expected behavior, in this case, is to evaluate the returned value before the adjoint of the `within` block is run, then release any qubits going out of scope (`anc` in this case), and finally, return control to the callee. In short, the expression should behave similarly to a `try-finally` pattern in C#. 51 | 52 | ← [Back to Index](https://github.com/microsoft/qsharp-language/tree/main/Specifications/Language#index) 53 | -------------------------------------------------------------------------------- /Specifications/Language/1_ProgramStructure/7_Comments.md: -------------------------------------------------------------------------------- 1 | # Comments 2 | 3 | Comments begin with two forward slashes (`//`) and continue until the end of line. 4 | Such end-of-line comments may appear anywhere in the source code. 5 | Q# does not currently support block comments. 6 | 7 | ## Documentation Comments 8 | 9 | Comments that begin with three forward slashes, `///`, 10 | are treated specially by the compiler when they appear before a type or callable declaration. 11 | In that case, their contents are taken as documentation for the defined 12 | type or callable, as for other .NET languages. 13 | 14 | Within `///` comments, text to appear as a part of API documentation is 15 | formatted as [Markdown](https://daringfireball.net/projects/markdown/syntax), 16 | with different parts of the documentation indicated by specially-named 17 | headers. 18 | As an extension to Markdown, cross-references to operations, functions, and 19 | user-defined types in Q# can be included using `@","` 20 | where `` is replaced by the fully qualified name of the 21 | code object being referenced. 22 | Optionally, a documentation engine may also support additional 23 | Markdown extensions. 24 | 25 | For example: 26 | 27 | ```qsharp 28 | /// # Summary 29 | /// Given an operation and a target for that operation, 30 | /// applies the given operation twice. 31 | /// 32 | /// # Input 33 | /// ## op 34 | /// The operation to be applied. 35 | /// ## target 36 | /// The target to which the operation is to be applied. 37 | /// 38 | /// # Type Parameters 39 | /// ## 'T 40 | /// The type expected by the given operation as its input. 41 | /// 42 | /// # Example 43 | /// ```Q# 44 | /// // Should be equivalent to the identity. 45 | /// ApplyTwice(H, qubit); 46 | /// ``` 47 | /// 48 | /// # See Also 49 | /// - Microsoft.Quantum.Intrinsic.H 50 | operation ApplyTwice<'T>(op : ('T => Unit), target : 'T) : Unit { 51 | op(target); 52 | op(target); 53 | } 54 | ``` 55 | 56 | Q# recognizes the following names as documentation comment headers. 57 | 58 | - **Summary**: A short summary of a function or operation's behavior 59 | or the purpose of a type. The first paragraph of the summary is used 60 | for hover information. It should be plain text. 61 | - **Description**: A description of a function or operation's behavior 62 | or the purpose of a type. The summary and description are concatenated to 63 | form the generated documentation file for the function, operation, or type. 64 | The description may contain in-line LaTeX-formatted symbols and equations. 65 | - **Input**: A description of the input tuple for an operation or function. 66 | May contain additional Markdown subsections indicating each element of the input tuple. 67 | - **Output**: A description of the tuple returned by an operation or function. 68 | - **Type Parameters**: An empty section that contains one additional 69 | subsection for each generic type parameter. 70 | - **Named Items**: A description of the named items in a user-defined type. 71 | May contain additional Markdown subsections with the description for each named item. 72 | - **Example**: A short example of the operation, function, or type in use. 73 | - **Remarks**: Miscellaneous prose describing some aspect of the operation, 74 | function, or type. 75 | - **See Also**: A list of fully qualified names indicating related functions, 76 | operations, or user-defined types. 77 | - **References**: A list of references and citations for the documented item. 78 | 79 | ← [Back to Index](https://github.com/microsoft/qsharp-language/tree/main/Specifications/Language#index) 80 | -------------------------------------------------------------------------------- /CoreLibraries/review-process.md: -------------------------------------------------------------------------------- 1 | # Introduction 2 | 3 | This page defines the Q# API design review process, used to help review API proposals for consistency with the [Q# API Design Principles](https://docs.microsoft.com/azure/quantum/contributing-api-design-principles). 4 | 5 | ## Scope 6 | 7 | The API design review process includes and addresses the following: 8 | 9 | - New Q# library designs (i.e.: new namespace and/or package) 10 | - Major new Q# library features 11 | - Significant refactoring of existing Q# libraries 12 | 13 | Code and API designs covered by this process may be in any public repository that includes Q# APIs. In particular: 14 | 15 | - microsoft/qsharp-runtime (i.e.: subsets implementing QSharpCore) 16 | - microsoft/QuantumLibraries 17 | - microsoft/Quantum-NC 18 | 19 | ## Out of Scope 20 | 21 | This document does not include and does not address: 22 | 23 | - Q# applications not intended for use as libraries (NB: the Q# style guide still applies even to Q# applications without an API surface). For example, samples, katas, and other documentation code are not affected by this proposal, as design changes can be made without breaking user code. 24 | - Fixes and improvements to Q# libraries made directly through GitHub pull requests that do not include API changes. Note that even small changes to API surface may be in scope, however. 25 | 26 | ## Principles 27 | 28 | - **Consistency with design principles**: All Q# APIs and library designs produced through this process will be consistent with established [API design principles](https://docs.microsoft.com/azure/quantum/contributing-api-design-principles). 29 | 30 | - **Transparency**: Decisions about Q# APIs and library designs will be traceable to help members of the quantum development community understand motivations and principles behind the Quantum Development Kit product. 31 | 32 | - **User-driven**: Decisions about Q# API and library designs will be motivated by user needs, and offering the best user experience possible. The decision-making process will explicitly take into account user feedback, as well as the impact of breaking user code, weighing that impact against potential improvements that can be enabled via breaking changes. 33 | 34 | - **Creative disagreement**: Providing input and feedback will not mean that suggestions and designs are automatically adopted. The libraries team will retain final say over Q# API designs and will work through this process to ensure that all disagreements are respectful and creative in nature. 35 | 36 | - **Inclusive**: In keeping with the [Microsoft Open Source Code of Conduct](https://microsoft.github.io/codeofconduct/), this process will not tolerate discriminatory and exclusive behavior. Participants that act in contravention to the Code of Conduct will not be allowed to continue providing feedback or joining discussions. 37 | 38 | ## Process 39 | ### API Review Meeting 40 | Early in each monthly release cycle, the libraries team will convene a 90-minute meeting. API designs for major refactoring of existing libraries, for major new library features, or for new libraries will be reviewed for adherence to design principles, and notes will be recorded on the result of this review and discussion. As time allows, these meetings will also consider future and early-stage proposals for new libraries, features, and refactorings. 41 | 42 | ### Broad Feedback Period 43 | Notes from each meeting will be published as to reflect consensus thinking. The pull request for each new meeting summary will be used to collect discussions and feedback from internal and external members of the quantum development community. 44 | -------------------------------------------------------------------------------- /Specifications/Language/1_ProgramStructure/1_Namespaces.md: -------------------------------------------------------------------------------- 1 | # Namespaces 2 | 3 | At its top-level, a Q# program consists of a set of namespaces. Aside from [comments](https://github.com/microsoft/qsharp-language/blob/main/Specifications/Language/1_ProgramStructure/7_Comments.md#comments), namespaces are the only top-level elements in a Q# program, and any other elements must reside within a namespace. 4 | Each file may contain zero or more namespaces, and each namespace may span multiple files. Q# does not support nested namespaces. 5 | 6 | A namespace block consists of the keyword `namespace`, followed by the namespace name, and the content of the block inside braces `{ }`. 7 | Namespace names consist of a sequence of one or more [legal symbols](https://github.com/microsoft/qsharp-language/blob/main/Specifications/Language/3_Expressions/Identifiers.md#identifiers) separated by a dot (`.`). 8 | While namespace names may contain dots for better readability, Q# does not support relative references to namespaces. For example, two namespaces `Foo` and `Foo.Bar` are unrelated, and there is no notion of a hierarchy. In particular, for a function `Baz` defined in `Foo.Bar`, it is *not* possible to open `Foo` and then access that function via `Bar.Baz`. 9 | 10 | Namespace blocks may contain [open directives](#open-directives) as well as [operation](https://github.com/microsoft/qsharp-language/blob/main/Specifications/Language/1_ProgramStructure/3_CallableDeclarations.md#callable-declarations), [function](https://github.com/microsoft/qsharp-language/blob/main/Specifications/Language/1_ProgramStructure/3_CallableDeclarations.md#callable-declarations), and [type](https://github.com/microsoft/qsharp-language/blob/main/Specifications/Language/1_ProgramStructure/2_TypeDeclarations.md#type-declarations) declarations. These may occur in any order and are recursive by default, meaning they can be declared and used in any order and can call themselves; there is no need for the declaration of a type or callable to precede its use. 11 | 12 | ## Open Directives 13 | 14 | By default, everything declared within the same namespace can be accessed without further qualification. However, declarations in a different namespace can only be used by qualifying their name with the name of the namespace they belong to or by opening that namespace before it is used, as shown in the following example. 15 | 16 | ```qsharp 17 | namespace Microsoft.Quantum.Samples { 18 | 19 | open Microsoft.Quantum.Arithmetic; 20 | open Microsoft.Quantum.Arrays as Array; 21 | 22 | // ... 23 | } 24 | ``` 25 | 26 | The example uses an `open` directive to import all types and callables declared in the Microsoft.Quantum.Artithmetic namespace. They can then be referred to by their unqualified name unless that name conflicts with a declaration in the namespace block or another opened namespace. 27 | 28 | To avoid typing out the full name while still distinguishing where certain elements come from, you can define an alternative name, or *alias*, which is usually shorter, for a particular namespace. In this case, all types and callables declared in that namespace can be qualified by the defined short name instead. 29 | In the previous example, this is the case for the `Microsoft.Quantum.Arrays` namespace. A function `IndexRange` declared in `Microsoft.Quantum.Arrays`, for example, can then be used via `Array.IndexRange` within that namespace block. 30 | 31 | Whether you are opening a namespace or defining an alias, `open` directives are valid throughout the namespace piece in that file only. 32 | 33 | ← [Back to Index](https://github.com/microsoft/qsharp-language/tree/main/Specifications/Language#index) 34 | -------------------------------------------------------------------------------- /Specifications/Language/3_Expressions/ContextualExpressions.md: -------------------------------------------------------------------------------- 1 | # Contextual and omitted expressions 2 | 3 | Contextual expressions are expressions that are only valid in certain contexts, such as the use of item names in [copy-and-update expressions](https://github.com/microsoft/qsharp-language/blob/main/Specifications/Language/3_Expressions/CopyAndUpdateExpressions.md#copy-and-update-expressions) without having to qualify them. 4 | 5 | Expressions can be *omitted* when they can be inferred and automatically inserted by the compiler, for example, in the case of [evaluate-and-reassign statements](https://github.com/microsoft/qsharp-language/blob/main/Specifications/Language/2_Statements/VariableDeclarationsAndReassignments.md#evaluate-and-reassign-statements). 6 | 7 | Open-ended ranges are another example that apply to both contextual and omitted expressions. They are are valid only within a certain context, and the compiler translates them into normal `Range` expressions during compilation by inferring suitable boundaries. 8 | 9 | A value of type `Range` generates a sequence of integers, specified by a start value, a step value (optional), and an end value. For example, the `Range` literal expression `1..3` generates the sequence 1,2,3. Likewise, the expression `3..-1..1` generates the sequence 3,2,1. You can also use ranges to create a new array from an existing one by slicing, for example: 10 | 11 | ```qsharp 12 | let arr = [1,2,3,4]; 13 | let slice1 = arr[1..2..4]; // contains [2,4] 14 | let slice2 = arr[2..-1..0]; // contains [3,2,1] 15 | ``` 16 | 17 | You cannot define an infinite range in Q#; the start and end values always need to be specified. The only exception is when you use a `Range` to slice an array. In that case, the start or end values of the range can reasonably be inferred by the compiler. 18 | 19 | In the previous array slicing examples, it is reasonable for the compiler to assume that the intended range end should be the index of the last item in the array if the step size is positive. If the step size is negative, then the range end likely should be the index of the first item in the array, `0`. The converse holds for the start of the range. 20 | 21 | To summarize, if you omit the range start value, the inferred start value 22 | 23 | - is zero if no step is specified or the specified step is positive. 24 | - is the length of the array minus one if the specified step is negative. 25 | 26 | If you omit the range end value, the inferred end value 27 | 28 | - is the length of the array minus one if no step is specified or the specified step is positive. 29 | - is zero if the specified step is negative. 30 | 31 | Q# hence allows the use of open-ended ranges within array slicing expressions, for example: 32 | 33 | ```qsharp 34 | let arr = [1,2,3,4,5,6]; 35 | let slice1 = arr[3...]; // slice1 is [4,5,6]; 36 | let slice2 = arr[0..2...]; // slice2 is [1,3,5]; 37 | let slice3 = arr[...2]; // slice3 is [1,2,3]; 38 | let slice4 = arr[...2..3]; // slice4 is [1,3]; 39 | let slice5 = arr[...2...]; // slice5 is [1,3,5]; 40 | let slice7 = arr[4..-2...]; // slice7 is [5,3,1]; 41 | let slice8 = arr[...-1..3]; // slice8 is [6,5,4]; 42 | let slice9 = arr[...-1...]; // slice9 is [6,5,4,3,2,1]; 43 | let slice10 = arr[...]; // slice10 is [1,2,3,4,5,6]; 44 | ``` 45 | 46 | Since the determination of whether the range step is positive or negative happens at runtime, the compiler inserts a suitable expression that will be evaluated at runtime. For omitted end values, the inserted expression is `step < 0 ? 0 | Length(arr)-1`, and for omitted start values it is `step < 0 ? Length(arr)-1 | 0`, where `step` is the expression given for the range step, or `1` if no step is specified. 47 | 48 | ← [Back to Index](https://github.com/microsoft/qsharp-language/tree/main/Specifications/Language#index) 49 | -------------------------------------------------------------------------------- /Specifications/Language/1_ProgramStructure/README.md: -------------------------------------------------------------------------------- 1 | # Program execution 2 | 3 | The following program gives a first glimpse at how a Q# command-line application is implemented: 4 | 5 | ```qsharp 6 | namespace Microsoft.Quantum.Samples { 7 | 8 | open Microsoft.Quantum.Arithmetic; 9 | open Microsoft.Quantum.Arrays as Array; 10 | open Microsoft.Quantum.Canon; 11 | open Microsoft.Quantum.Convert; 12 | open Microsoft.Quantum.Diagnostics as Diagnostics; 13 | open Microsoft.Quantum.Intrinsic; 14 | open Microsoft.Quantum.Math; 15 | open Microsoft.Quantum.Preparation; 16 | 17 | operation ApplyQFT (reg : LittleEndian) : Unit 18 | is Adj + Ctl { 19 | 20 | let qs = reg!; 21 | SwapReverseRegister(qs); 22 | 23 | for (i in Array.IndexRange(qs)) { 24 | for (j in 0 .. i-1) { 25 | Controlled R1Frac([qs[i]], (1, i - j, qs[j])); 26 | } 27 | H(qs[i]); 28 | } 29 | } 30 | 31 | @EntryPoint() 32 | operation RunProgram(vector : Double[]) : Unit { 33 | 34 | let n = Floor(Log(IntAsDouble(Length(vector))) / LogOf2()); 35 | if (1 <<< n != Length(vector)) { 36 | fail "Length(vector) needs to be a power of two."; 37 | } 38 | 39 | let amps = Array.Mapped(ComplexPolar(_,0.), vector); 40 | use qs = Qubit[n] { 41 | let reg = LittleEndian(qs); 42 | 43 | PrepareArbitraryState(amps, reg); 44 | Message("Before QFT:"); 45 | Diagnostics.DumpRegister((), qs); 46 | 47 | ApplyQFT(reg); 48 | Message("After QFT:"); 49 | Diagnostics.DumpRegister((), qs); 50 | 51 | ResetAll(qs); 52 | } 53 | } 54 | } 55 | ``` 56 | 57 | The operation `PrepareArbitraryState` initializes a quantum state where the amplitudes for each basis state correspond to the normalized entries of the specified vector. A quantum Fourier transformation (QFT) is then applied to that state. 58 | 59 | The corresponding project file to build the application is the following: 60 | 61 | ```xml 62 | 63 | 64 | 65 | Exe 66 | netcoreapp3.1 67 | 68 | 69 | 70 | ``` 71 | 72 | The first line specifies the version number of the software development kit used to build the application, and line 4 indicates that the project is executable opposed to e.g. a library that cannot be invoked from the command line. 73 | 74 | To run the application, you will need to install [.NET Core](https://docs.microsoft.com/dotnet/core/install/). Then put both files in the same folder and run `dotnet build `, where `` is to be replaced with the path to the project file. 75 | 76 | To run the program after having built it, run the command 77 | 78 | ```azurecli 79 | dotnet run --no-build --vector 1. 0. 0. 0. 80 | ``` 81 | 82 | The output from this invocation shows that the amplitudes of the quantum state after application of the QFT are evenly distributed and real. Note that the reason that we can so readily output the amplitudes of the state vector is that the previous program is, by default, run on a full state simulator, which supports outputting the tracked quantum state via `DumpRegister` for debugging purposes. The same would not be possible if we were to run it on quantum hardware instead, in which case the two calls to `DumpRegister` wouldn't do anything. You can see this by targeting the application to a particular hardware platform by adding the project property `honeywell.qpu` after ``. 83 | 84 | 85 | ← [Back to Index](https://github.com/microsoft/qsharp-language/tree/main/Specifications/Language#index) 86 | -------------------------------------------------------------------------------- /Specifications/Language/3_Expressions/FunctorApplication.md: -------------------------------------------------------------------------------- 1 | # Functor application 2 | 3 | Functors are factories that allow you to access particular specialization implementations of a callable. Q# currently supports two functors; the `Adjoint` and the `Controlled`, both of which can be applied to operations that provide the necessary specializations. 4 | 5 | The `Controlled` and `Adjoint` functors commute; if `ApplyUnitary` is an operation that supports both functors, then there is no difference between `Controlled Adjoint ApplyUnitary` and `Adjoint Controlled ApplyUnitary`. 6 | Both have the same type and, upon invocation, execute the implementation defined for the `controlled adjoint` [specialization](https://github.com/microsoft/qsharp-language/blob/main/Specifications/Language/1_ProgramStructure/4_SpecializationDeclarations.md#specialization-declarations). 7 | 8 | ## Adjoint functor 9 | 10 | If the operation `ApplyUnitary` defines a unitary transformation *U* of the quantum state, `Adjoint ApplyUnitary` accesses the implementation of *U†*. The `Adjoint` functor is its own inverse, since *(U†)† = U* by definition. For example, `Adjoint Adjoint ApplyUnitary` is the same as `ApplyUnitary`. 11 | 12 | The expression `Adjoint ApplyUnitary` is an operation of the same type as `ApplyUnitary`; it has the same argument and return type and supports the same functors. Like any operation, it can be invoked with an argument of suitable type. The following expression applies the [adjoint specialization](https://github.com/microsoft/qsharp-language/blob/main/Specifications/Language/1_ProgramStructure/4_SpecializationDeclarations.md#specialization-declarations) of `ApplyUnitary` to an argument `arg`: 13 | 14 | ```qsharp 15 | Adjoint ApplyUnitary(arg) 16 | ``` 17 | 18 | ## Controlled functor 19 | 20 | For an operation `ApplyUnitary` that defines a unitary transformation *U* of the quantum state, `Controlled ApplyUnitary` accesses the implementation that applies *U* conditional on all qubits in an array of control qubits being in the |1⟩ state. 21 | 22 | The expression `Controlled ApplyUnitary` is an operation with the same return type and [operation characteristics](https://github.com/microsoft/qsharp-language/blob/main/Specifications/Language/4_TypeSystem/OperationsAndFunctions.md#operation-characteristics) as `ApplyUnitary`, meaning it supports the same functors. 23 | It takes an argument of type `(Qubit[], )`, where `` should be replaced with the argument type of `ApplyUnitary`, taking [singleton tuple equivalence](https://github.com/microsoft/qsharp-language/blob/main/Specifications/Language/4_TypeSystem/SingletonTupleEquivalence.md#singleton-tuple-equivalence) into account. 24 | 25 | | Operation | Argument Type | Controlled Argument Type | 26 | | --- | --- | --- | 27 | | X | `Qubit` | `(Qubit[], Qubit)` | 28 | | SWAP | `(Qubit, Qubit)` | `(Qubit[], (Qubit, Qubit))` | 29 | | ApplyQFT | `LittleEndian` | `(Qubit[], LittleEndian)` | 30 | 31 | Concretely, if `cs` contains an array of qubits, `q1` and `q2` are two qubits, and the operation `SWAP` is as defined [here](https://github.com/microsoft/qsharp-language/blob/main/Specifications/Language/1_ProgramStructure/4_SpecializationDeclarations.md#specialization-declarations), then the following expression exchanges the state of `q1` and `q2` if all qubits in `cs` are in the |1⟩ state: 32 | 33 | ```qsharp 34 | Controlled SWAP(cs, (q1, q2)) 35 | ``` 36 | 37 | >[!NOTE] 38 | > Conditionally applying an operation based on the control qubits being in a state other than the |1⟩ state may be achieved by applying the appropriate adjointable transformation to the control qubits before invocation, and applying the inverses after. Conditioning the transformation on all control qubits being in the |0⟩ state, for example, can be achieved by applying the `X` operation before and after. This can be conveniently expressed using a [conjugation](https://github.com/microsoft/qsharp-language/blob/main/Specifications/Language/3_Expressions/Conjugations.md#conjugations). Nonetheless, the verbosity of such a construct may merit additional support for a more compact syntax in the future. 39 | 40 | ← [Back to Index](https://github.com/microsoft/qsharp-language/tree/main/Specifications/Language#index) 41 | -------------------------------------------------------------------------------- /Specifications/Language/3_Expressions/Closures.md: -------------------------------------------------------------------------------- 1 | # Closures 2 | 3 | Closures are callables that capture variables from the enclosing environment. 4 | Both function and operation closures can be created. 5 | An operation closure can be created inside a function, but it can only be applied in an operation. 6 | 7 | Q# has two mechanisms for creating closures: lambda expressions and partial application. 8 | 9 | ## Lambda expressions 10 | 11 | A lambda expression creates an anonymous function or operation. 12 | The basic syntax is a symbol tuple to bind the parameters, an arrow (`->` for a function and `=>` for an operation), and an expression to evaluate when applied. 13 | 14 | ```qsharp 15 | // Function that captures 'x': 16 | y -> x + y 17 | 18 | // Operation that captures 'qubit': 19 | deg => Rx(deg * PI() / 180.0, qubit) 20 | 21 | // Function that captures nothing: 22 | (x, y) -> x + y 23 | ``` 24 | 25 | ### Parameters 26 | 27 | Parameters are bound using a symbol tuple that is identical to the left-hand side of a [variable declaration statement](https://github.com/microsoft/qsharp-language/blob/main/Specifications/Language/2_Statements/VariableDeclarationsAndReassignments.md). 28 | The type of the parameter tuple is implicit. 29 | Type annotations are not supported; if type inference fails, you may need to create a top-level callable declaration and use partial application instead. 30 | 31 | ### Mutable capture variables 32 | 33 | Mutable variables cannot be captured. 34 | If you only need to capture the value of a mutable variable at the instant the lambda expression is created, you can create an immutable copy: 35 | 36 | ```qsharp 37 | // ERROR: 'variable' cannot be captured. 38 | mutable variable = 1; 39 | let f = () -> variable; 40 | 41 | // OK. 42 | let value = variable; 43 | let g = () -> value; 44 | ``` 45 | 46 | ### Characteristics 47 | 48 | The characteristics of an anonymous operation are inferred based on the applications of the lambda. If the lambda is used with a functor application, or in a context that expects a characteristic, the lambda is then inferred to have that characteristic. 49 | For example: 50 | 51 | ```qsharp 52 | operation NoOp(q : Qubit) : Unit is Adj {} 53 | operation Main() : Unit { 54 | use q = Qubit(); 55 | let foo = () => NoOp(q); 56 | foo(); // Has type Unit => Unit with no characteristics 57 | 58 | let bar = () => NoOp(q); 59 | Adjoint bar(); // Has type Unit => Unit is Adj 60 | } 61 | ``` 62 | 63 | If you need different characteristics for an operation lambda than what was inferred, you will need to create a top-level operation declaration instead. 64 | 65 | ## Partial application 66 | 67 | Partial application is a convenient shorthand for applying some, but not all, of a callable's arguments. 68 | The syntax is the same as a call expression, but unapplied arguments are replaced with `_`. 69 | Conceptually, partial application is equivalent to a lambda expression that captures the applied arguments and takes in the unapplied arguments as parameters. 70 | 71 | For example, given that `f` is a function and `o` is an operation, and the captured variable `x` is immutable: 72 | 73 | | Partial application | Lambda expression | 74 | | ---------------------- | ------------------------------------- | 75 | | `f(x, _)` | `a -> f(x, a)` | 76 | | `o(x, _)` | `a => o(x, a)` | 77 | | `f(_, (1, _))` | `(a, b) -> f(a, (1, b))`[^1] | 78 | | `f((_, _, x), (1, _))` | `((a, b), c) -> f((a, b, x), (1, c))` | 79 | 80 | ### Mutable capture variables 81 | 82 | Unlike lambda expressions, partial application can automatically capture a copy of the value of a mutable variable: 83 | 84 | ```qsharp 85 | mutable variable = 1; 86 | let f = Foo(variable, _); 87 | ``` 88 | 89 | This is equivalent to the following lambda expression: 90 | 91 | ```qsharp 92 | mutable variable = 1; 93 | let value = variable; 94 | let f = x -> Foo(value, x); 95 | ``` 96 | 97 | --- 98 | 99 | ← [Back to Index](https://github.com/microsoft/qsharp-language/tree/main/Specifications/Language#index) 100 | 101 | [^1]: The parameter tuple is strictly written `(a, (b))`, but [`(b)` is equivalent to `b`](https://github.com/microsoft/qsharp-language/blob/main/Specifications/Language/4_TypeSystem/SingletonTupleEquivalence.md). 102 | -------------------------------------------------------------------------------- /Templates/proposal.md: -------------------------------------------------------------------------------- 1 | --- 2 | description: 3 | author: 4 | date: 5 | --- 6 | 7 | # QEP 0: Title 8 | 9 | ## Proposal 10 | 11 | TODO: 12 | Insert a short outline for what the proposal is. 13 | 14 | ## Justification 15 | 16 | TODO: 17 | Explain why this modification to the Q# language is needed or desirable. 18 | Explain both the benefit of the proposed modification as well as briefly summarize the benefits of the chosen mechanism opposed to other ways of achieving a similar functionality. 19 | 20 | ## Description 21 | 22 | TODO: 23 | Describe the proposal and how it ties in with other aspects of the Q# language in more detail. 24 | Provide general information about the relevant mechanisms and their role in Q#, and how the proposal relates to them. 25 | 26 | ### Current Status 27 | 28 | TODO: 29 | Describe all aspects of the current version of Q# that will be impacted by the proposed modification. 30 | Describe in detail the current behavior or limitations that make the proposed change necessary. 31 | Describe how the targeted functionality can be achieved with the current version of Q#. 32 | Refer to the examples given below to illustrate your descriptions. 33 | 34 | #### Examples 35 | 36 | Example 1: 37 | TODO: insert title and caption 38 | 39 | ```qsharp 40 | // TODO: 41 | // Insert code example that illustrates what is described above. 42 | // Comment your code to further elaborate and clarify the example. 43 | 44 | ``` 45 | TODO: 46 | Add more examples following the structure above. 47 | 48 | ### Proposed Modification 49 | 50 | TODO: 51 | Describe how the proposed modification changes the behavior and/or syntax described in [Current Status](#current-status). 52 | Describe in detail how the proposed modification is supposed to behave how it is supposed to be used. 53 | Describe in detail any impact on existing code and how to interpret all new language structures. 54 | Refer to the code examples below to illustrate your descriptions. 55 | 56 | #### Examples 57 | 58 | Example 1: 59 | TODO: insert title and caption 60 | 61 | ```qsharp 62 | // TODO: 63 | // Insert code example that illustrates what is described above. 64 | // Comment your code to further elaborate and clarify the example. 65 | 66 | ``` 67 | TODO: 68 | Add more examples following the structure above. 69 | 70 | ## Implementation 71 | 72 | TODO: 73 | Describe how the made proposal could be implemented and why it should be implemented in this way. 74 | Be specific regarding the efficiency, and potential caveats of such an implementation. 75 | Based on that description a user should be able to determine when to use or not to use the proposed modification and how. 76 | 77 | ### Timeline 78 | 79 | TODO: 80 | List any dependencies that the proposed implementation relies on. 81 | Estimate the resources required to accomplish each step of the proposed implementation. 82 | 83 | ## Further Considerations 84 | 85 | TODO: 86 | Provide any context and background information that is needed to discuss the concepts in detail that are related to or impacted by your proposal. 87 | 88 | ### Related Mechanisms 89 | 90 | TODO: 91 | Provide detailed information about the mechanisms and concepts that are relevant for or related to your proposal, 92 | as well as their role, realization and purpose within Q#. 93 | 94 | ### Impact on Existing Mechanisms 95 | 96 | TODO: 97 | Describe in detail the impact of your proposal on existing mechanisms and concepts within Q#. 98 | 99 | ### Anticipated Interactions with Future Modifications 100 | 101 | TODO: 102 | Describe how the proposed modification ties in with possible future developments of Q#. 103 | Describe what developments it can facilitate and/or what functionalities depend on the proposed modification. 104 | 105 | ### Alternatives 106 | 107 | TODO: 108 | Explain alternative mechanisms that would serve a similar purpose as the proposed modification. 109 | For each one, discuss what the implications are for the future development of Q#. 110 | 111 | ### Comparison to Alternatives 112 | 113 | TODO: 114 | Compare your proposal to the possible alternatives and compare the advantages and disadvantages of each approach. 115 | Compare in particular their impact on the future development of Q#. 116 | 117 | ## Raised Concerns 118 | 119 | Any concerns about the proposed modification will be listed here and can be addressed in the [Response](#response) section below. 120 | 121 | ### Response 122 | -------------------------------------------------------------------------------- /Specifications/Language/5_Grammar/QSharpLexer.g4: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. 2 | // Licensed under the MIT License. 3 | 4 | lexer grammar QSharpLexer; 5 | 6 | options { 7 | language = CSharp; 8 | } 9 | 10 | // Keywords 11 | 12 | Adj : 'Adj'; 13 | AdjointFunctor : 'Adjoint'; 14 | AdjointGenerator : 'adjoint'; 15 | And : 'and'; 16 | Apply : 'apply'; 17 | As : 'as'; 18 | Auto : 'auto'; 19 | BigInt : 'BigInt'; 20 | Body : 'body'; 21 | Bool : 'Bool'; 22 | Borrow : 'borrow'; 23 | Borrowing : 'borrowing'; 24 | ControlledFunctor : 'Controlled'; 25 | ControlledGenerator : 'controlled'; 26 | Ctl : 'Ctl'; 27 | Distribute : 'distribute'; 28 | Double : 'Double'; 29 | Elif : 'elif'; 30 | Else : 'else'; 31 | Fail : 'fail'; 32 | False : 'false'; 33 | Fixup : 'fixup'; 34 | For : 'for'; 35 | Function : 'function'; 36 | If : 'if'; 37 | In : 'in'; 38 | Int : 'Int'; 39 | Internal : 'internal'; 40 | Intrinsic : 'intrinsic'; 41 | Invert : 'invert'; 42 | Is : 'is'; 43 | Let : 'let'; 44 | Mutable : 'mutable'; 45 | Namespace : 'namespace'; 46 | New : 'new'; 47 | Newtype : 'newtype'; 48 | Not : 'not'; 49 | One : 'One'; 50 | Open : 'open'; 51 | Operation : 'operation'; 52 | Or : 'or'; 53 | Pauli : 'Pauli'; 54 | PauliI : 'PauliI'; 55 | PauliX : 'PauliX'; 56 | PauliY : 'PauliY'; 57 | PauliZ : 'PauliZ'; 58 | Qubit : 'Qubit'; 59 | Range : 'Range'; 60 | Repeat : 'repeat'; 61 | Result : 'Result'; 62 | Return : 'return'; 63 | Self : 'self'; 64 | Set : 'set'; 65 | String : 'String'; 66 | True : 'true'; 67 | Unit : 'Unit'; 68 | Until : 'until'; 69 | Use : 'use'; 70 | Using : 'using'; 71 | While : 'while'; 72 | Within : 'within'; 73 | Zero : 'Zero'; 74 | 75 | // Operators 76 | 77 | AndEqual : 'and='; 78 | ArrowLeft : '<-'; 79 | ArrowRight : '->'; 80 | Asterisk : '*'; 81 | AsteriskEqual : '*='; 82 | At : '@'; 83 | Bang : '!'; 84 | BraceLeft : '{' -> pushMode(DEFAULT_MODE); 85 | BraceRight : '}' { if (ModeStack.Count > 0) PopMode(); }; 86 | BracketLeft : '['; 87 | BracketRight : ']'; 88 | Caret : '^'; 89 | CaretEqual : '^='; 90 | Colon : ':'; 91 | Comma : ','; 92 | DollarQuote : '$"' -> pushMode(INTERPOLATED); 93 | Dot : '.'; 94 | DoubleAmpersand : '&&'; 95 | DoubleColon : '::'; 96 | DoubleDot : '..'; 97 | DoubleEqual : '=='; 98 | DoublePipe : '||'; 99 | DoubleQuote : '"' -> pushMode(STRING); 100 | Ellipsis : '...'; 101 | Equal : '='; 102 | FatArrowRight : '=>'; 103 | Greater : '>'; 104 | GreaterEqual : '>='; 105 | Less : '<'; 106 | LessEqual : '<='; 107 | Minus : '-'; 108 | MinusEqual : '-='; 109 | NotEqual : '!='; 110 | OrEqual : 'or='; 111 | ParenLeft : '('; 112 | ParenRight : ')'; 113 | Percent : '%'; 114 | PercentEqual : '%='; 115 | Pipe : '|'; 116 | Plus : '+'; 117 | PlusEqual : '+='; 118 | Question : '?'; 119 | Semicolon : ';'; 120 | Slash : '/'; 121 | SlashEqual : '/='; 122 | TripleAmpersand : '&&&'; 123 | TripleAmpersandEqual : '&&&='; 124 | TripleCaret : '^^^'; 125 | TripleCaretEqual : '^^^='; 126 | TripleGreater : '>>>'; 127 | TripleGreaterEqual : '>>>='; 128 | TripleLess : '<<<'; 129 | TripleLessEqual : '<<<='; 130 | TriplePipe : '|||'; 131 | TriplePipeEqual : '|||='; 132 | TripleTilde : '~~~'; 133 | Underscore : '_'; 134 | With : 'w/'; 135 | WithEqual : 'w/='; 136 | 137 | // Literals 138 | 139 | fragment Digit : [0-9]; 140 | 141 | IntegerLiteral 142 | : Digit+ 143 | | ('0x' | '0X') [0-9a-fA-F]+ 144 | | ('0o' | '0O') [0-7]+ 145 | | ('0b' | '0B') [0-1]+ 146 | ; 147 | 148 | BigIntegerLiteral : IntegerLiteral ('L' | 'l'); 149 | 150 | fragment Exponent : ('e' | 'E') ('+' | '-')? Digit+; 151 | 152 | DoubleLiteral 153 | : Digit+ '.' Digit+ Exponent? 154 | | '.' Digit+ Exponent? 155 | | Digit+ '.' Exponent 156 | // "n.." should be interpreted as an integer range, not the double "n." followed by a dot. 157 | | Digit+ '.' { InputStream.LA(1) != '.' }? 158 | | Digit+ Exponent 159 | ; 160 | 161 | Identifier : IdentifierStart IdentifierContinuation*; 162 | 163 | IdentifierStart 164 | : Underscore 165 | | [\p{Letter}] 166 | | [\p{Letter_Number}] 167 | ; 168 | 169 | IdentifierContinuation 170 | : [\p{Connector_Punctuation}] 171 | | [\p{Decimal_Number}] 172 | | [\p{Format}] 173 | | [\p{Letter}] 174 | | [\p{Letter_Number}] 175 | | [\p{Nonspacing_Mark}] 176 | | [\p{Spacing_Mark}] 177 | ; 178 | 179 | TypeParameter : '\'' Identifier; 180 | 181 | Whitespace : (' ' | '\n' | '\r' | '\t')+ -> channel(HIDDEN); 182 | 183 | Comment : '//' ~('\n' | '\r')* -> channel(HIDDEN); 184 | 185 | Invalid : . -> channel(HIDDEN); 186 | 187 | // Strings 188 | 189 | mode STRING; 190 | 191 | StringEscape : '\\' .; 192 | 193 | StringText : ~('"' | '\\')+; 194 | 195 | StringDoubleQuote : '"' -> popMode; 196 | 197 | mode INTERPOLATED; 198 | 199 | InterpStringEscape : '\\' .; 200 | 201 | InterpBraceLeft : '{' -> pushMode(DEFAULT_MODE); 202 | 203 | InterpStringText : ~('\\' | '"' | '{')+; 204 | 205 | InterpDoubleQuote : '"' -> popMode; 206 | -------------------------------------------------------------------------------- /Specifications/Language/4_TypeSystem/SubtypingAndVariance.md: -------------------------------------------------------------------------------- 1 | # Subtyping and variance 2 | 3 | Q# supports only a few conversion mechanisms. Implicit conversions can happen only when applying binary operators, evaluating conditional expressions, or constructing an array literal. In these cases, a common supertype is determined and the necessary conversions are performed automatically. Aside from such implicit conversions, explicit conversions via function calls are possible and often necessary. 4 | 5 | Currently, the only subtyping relation that exists applies to operations. Intuitively, it makes sense that one should be allowed to substitute an operation that supports more than the required set of functors. Concretely, for any two concrete types `TIn` and `TOut`, the subtyping relation is 6 | 7 | ``` 8 | (TIn => TOut) :> 9 | (TIn => TOut is Adj), (TIn => TOut is Ctl) :> 10 | (TIn => TOut is Adj + Ctl) 11 | ``` 12 | 13 | where `A :> B` indicates that `B` is a subtype of `A`. Phrased differently, `B` is more restrictive than `A` such that a value of type `B` can be used wherever a value of type `A` is required. If a callable relies on an argument (item) of being of type `A`, then an argument of type `B` can safely be substituted since if provides all the necessary capabilities. 14 | 15 | This kind of polymorphism extends to tuples in that a tuple of type `B` is a subtype of a tuple type `A` if it contains the same number of items and the type of each item is a subtype of the corresponding item type in `A`. This is known as *depth subtyping*. There is currently no support for *width subtyping*, that is, there is no subtype relation between any two user-defined types or a user-defined type and any built-in type. The existence of the `unwrap` operator, which allows you to extract a tuple containing all named and anonymous items, prevents this. 16 | 17 | >[!NOTE] 18 | >In regards to callables, if a callable processes an argument of type `A`, then it is also capable of processing an argument of type `B`. If a callable is passed as an argument to another callable, then it has to be capable of processing anything that the type signature may require. This means that if the callable needs to be able to process an argument of type `B`, any callable that is capable of processing a more general argument of type `A` can be passed safely. Conversely, we expect that if we require that the passed callable returns a value of type `A`, then the promise to return a value of type `B` is sufficient, since that value will provide all necessary capabilities. 19 | 20 | The operation or function type is *contravariant* in its argument type and *covariant* in its return type. `A :> B` hence implies that for any concrete type `T1`, 21 | 22 | ``` 23 | (B → T1) :> (A → T1), and 24 | (T1 → A) :> (T1 → B) 25 | ``` 26 | 27 | where `→` here can mean either a function or operation, and we omit any annotations for characteristics. 28 | Substituting `A` with `(B → T2)` and `(T2 → A)` respectively, 29 | and substituting `B` with `(A → T2)` and `(T2 → B)` respectively, leads to the conclusion that, for any concrete type `T2`, 30 | 31 | ``` 32 | ((A → T2) → T1) :> ((B → T2) → T1), and 33 | ((T2 → B) → T1) :> ((T2 → A) → T1), and 34 | (T1 → (B → T2)) :> (T1 → (A → T2)), and 35 | (T1 → (T2 → A)) :> (T1 → (T2 → B)) 36 | ``` 37 | 38 | By induction, it follows that every additional indirection reverses the variance of the argument type, and leaves the variance of the return type unchanged. 39 | 40 | >[!NOTE] 41 | >This also makes it clear what the variance behavior of arrays needs to be; retrieving items via an item access operator corresponds to invoking a function of type `(Int -> TItem)`, where `TItem` is the type of the elements in the array. Since this function is implicitly passed when passing an array, it follows that arrays need to be covariant in their item type. The same considerations also hold for tuples, which are immutable and thus covariant with respect to each item type. 42 | >If arrays weren't immutable, the existence of a construct that would allow you to set items in an array, and thus take an argument of type `TItem`, would imply that arrays also need to be contravariant. The only option for data types that support getting and setting items is hence to be *invariant*, meaning there is no subtyping relation whatsoever; `B[]` is *not* a subtype of `A[]` even if `B` is a subtype of `A`. Despite the fact that arrays in Q# are [immutable](https://github.com/microsoft/qsharp-language/blob/main/Specifications/Language/4_TypeSystem/Immutability.md#immutability), they are invariant rather than covariant. This means, for example, that a value of type `(Qubit => Unit is Adj)[]` cannot be passed to a callable that requires an argument of type `(Qubit => Unit)[]`. 43 | Keeping arrays invariant allows for more flexibility related to how arrays are handled and optimized in the runtime, but it may be possible to revise that in the future. 44 | 45 | 46 | ← [Back to Index](https://github.com/microsoft/qsharp-language/tree/main/Specifications/Language#index) -------------------------------------------------------------------------------- /Specifications/Language/3_Expressions/ItemAccessExpressions.md: -------------------------------------------------------------------------------- 1 | # Item access 2 | 3 | Q# supports item access for array items and for items in user defined types. In both cases, the access is read-only; the value cannot be changed without creating a new instance using a [copy-and-update expression](https://github.com/microsoft/qsharp-language/blob/main/Specifications/Language/3_Expressions/CopyAndUpdateExpressions.md#copy-and-update-expressions). 4 | 5 | ## Array item access and array slicing 6 | 7 | Given an array expression and an expression of type `Int` or `Range`, a new expression may be formed using the array item access operator consisting of `[` and `]`. 8 | 9 | If the expression inside the brackets is of type `Int`, then the new expression contains the array item at that index. 10 | For example, if `arr` is of type `Double[]` and contains five or more items, then `arr[4]` is an expression of type `Double`. 11 | 12 | If the expression inside the brackets is of type `Range`, then the new expression contains an array of all the items indexed by the specified `Range`. If the `Range` is empty, then the resulting array is empty. 13 | For example, 14 | 15 | ```qsharp 16 | let arr = [10, 11, 36, 49]; 17 | let ten = arr[0]; // contains the value 10 18 | let odds = arr[1..2..4]; // contains the value [11, 49] 19 | let reverse = arr[...-1...]; // contains the value [49, 36, 11, 10] 20 | ``` 21 | 22 | In the last line of the example, the start and end value of the range have been omitted for convenience. For more information, see [Contextual expressions](https://github.com/microsoft/qsharp-language/blob/main/Specifications/Language/3_Expressions/ContextualExpressions.md#contextual-and-omitted-expressions). 23 | 24 | If the array expression is not a simple identifier, it must be enclosed in parentheses in order to extract an item or a slice. 25 | For instance, if `arr1` and `arr2` are both arrays of integers, an item from the concatenation would be expressed as `(arr1 + arr2)[13]`. For more information, see [Precedence and associativity](https://github.com/microsoft/qsharp-language/blob/main/Specifications/Language/3_Expressions/PrecedenceAndAssociativity.md#precedence-and-associativity). 26 | 27 | All arrays in Q# are zero-based, that is, the first element of an array `arr` is always `arr[0]`. 28 | An exception is thrown at runtime if the index or one of the indices used for slicing is outside the bounds of the array, for example, if it is less than zero or larger or equal to the length of the array. 29 | 30 | ## Item access for user-defined types 31 | 32 | (For more information about how to define custom types containing one or more named or anonymous items, see [Type declarations](https://github.com/microsoft/qsharp-language/blob/main/Specifications/Language/1_ProgramStructure/2_TypeDeclarations.md#type-declarations)). 33 | 34 | The contained items can be accessed via their name or by deconstruction, illustrated by the following statements that may be used as part of an operation or function implementation: 35 | 36 | ```qsharp 37 | let complex = Complex(1., 0.); // create a value of type Complex 38 | let (re, _) = complex!; // item access via deconstruction 39 | let im = complex::Imaginary; // item access via name 40 | ``` 41 | 42 | The item access operator (`::`) retrieves named items, as illustrated by the following example: 43 | 44 | ```qsharp 45 | newtype TwoStrings = (str1 : String, str2 : String); 46 | 47 | operation LinkTwoStrings(str : TwoStrings) : String { 48 | let s1 = str::str1; 49 | let s2 = str::str2; 50 | return s1 + s2; 51 | } 52 | ``` 53 | 54 | While named items can be accessed by their name or via deconstruction, anonymous items can only be accessed by the latter. Since deconstruction relies on all of the contained items, the use of anonymous items is discourage when these items need to be accessed outside the compilation unit in which the type is defined. 55 | 56 | Access via deconstruction makes use of the unwrap operator (`!`). The unwrap operator returns a tuple of all contained items, where the shape of the tuple matches the one defined in the declaration, and a single item tuple is equivalent to the item itself (see [this section](https://github.com/microsoft/qsharp-language/blob/main/Specifications/Language/4_TypeSystem/SingletonTupleEquivalence.md#singleton-tuple-equivalence)). 57 | 58 | For example, for a value `nested` of type `Nested` that is defined as follows 59 | 60 | ```qsharp 61 | newtype Nested = (Double, (ItemName : Int, String)); 62 | ``` 63 | 64 | the expression `nested!` return a value of type `(Double, (Int, String))`. 65 | 66 | The `!` operator has lower [precedence](https://github.com/microsoft/qsharp-language/blob/main/Specifications/Language/3_Expressions/PrecedenceAndAssociativity.md#modifiers-and-combinators) than both item access operators, but higher precedence than any other operator. For a complete list of precedences, see [Precedence and associativity](https://github.com/microsoft/qsharp-language/blob/main/Specifications/Language/3_Expressions/PrecedenceAndAssociativity.md#precedence-and-associativity). 67 | 68 | ← [Back to Index](https://github.com/microsoft/qsharp-language/tree/main/Specifications/Language#index) 69 | -------------------------------------------------------------------------------- /FAQ.md: -------------------------------------------------------------------------------- 1 | # Frequently Asked Questions 2 | 3 | ### *Where can I give feedback on the Quantum Intermediate Representation (QIR)?* 4 | 5 | We very much welcome input for the QIR! We choose to make our current thinking public early on to encourage contributions and feedback on how to make it usable across a wide variety of hardware backends and software frontends. Please use our [documentation template](https://github.com/microsoft/qsharp-language/issues/new?labels=Documentation&template=documentation.md) to share ideas around QIR. 6 | 7 | ### *Where can I find the current specification of the Q# language?* 8 | 9 | The specification for the latest Q# version shipped with the [Quantum Development Kit](https://www.microsoft.com/quantum/development-kit) can be found [here](https://github.com/microsoft/qsharp-language/tree/main/Specifications/Language). 10 | We are working on a more formal spec to add to the current documentation. Please reach out to us by filing and issue following our [documentation template](https://github.com/microsoft/qsharp-language/issues/new?labels=Documentation&template=documentation.md) if you are interested in contributing or have feedback related to the specs and docs maintained on this repository. 11 | 12 | ### *What features are currently being implemented? Is there a roadmap for Q#?* 13 | 14 | Please take a look at our [readme](https://github.com/microsoft/qsharp-language#repository-content) for useful links around the current status. 15 | We are working on putting together a roadmap that we will add to this repo in the near future. 16 | 17 | ### *How do I make a suggestion for a feature?* 18 | 19 | Please create a new issue following on our [suggestion template](https://github.com/microsoft/qsharp-language/issues/new?template=suggestion.md). 20 | 21 | ### *Can I help implement a feature?* 22 | 23 | Yes! Please take a look at the proposals that have been [approved in principle](https://github.com/microsoft/qsharp-language/tree/main/Approved) and are ready for implementation. If a feature is under active development a corresponding open issue labeled with `Implementation` exists on this repository, and otherwise the development has not yet started. If you would like to help with the implementation of a feature that is already [being developed](https://github.com/microsoft/qsharp-language/labels/Implementation), please comment on the corresponding issue to indicate your interest. If you would like to implement a feature for which development has not yet started, please create an issue following our [implementation template](https://github.com/microsoft/qsharp-language/issues/new?template=implementation.md). Once the issue is created, we will respond to follow up with a discussion to flesh out the details of the implementation. 24 | 25 | ### *How do I create a good feature request?* 26 | 27 | For every feature there should be a clear purpose and benefit for a large group of users; introducing new features comes at a cost not just in terms of implementation but also in terms of adoption. When introducing a feature, it is hence important to maximize its utility. Furthermore, it should tie in well with other features and syntax; some features are mutually exclusive, whereas others are a natural extension that enhance the flow of the language. Coherence and a predictable evolution of the language are important factors. [This document](https://github.com/microsoft/qsharp-language/blob/main/Guidelines.md) lists further considerations. Be specific when you file an suggestion both regarding the need it addresses and how you suggest to address it. Briefly list the context you can think of; why you think this is the right approach, and what alternatives you see. 28 | 29 | ### *Why has my suggestion been declined?* 30 | 31 | A suggestion may be declined for a variety of reasons, and sometimes we have to decline even features we would love to have. Q# is a domain specific language for a rather unique domain. Please take a look a the [Q# design principles](https://github.com/microsoft/qsharp-language#design-principles) as well as other [considerations](https://github.com/microsoft/qsharp-language/blob/main/Guidelines.md) we factor into our decisions. 32 | 33 | ### *How can I use Q# and where do I get development tools?* 34 | 35 | Q# is part of the [Quantum Development Kit](https://www.microsoft.com/quantum/development-kit) (QDK) shipped by Microsoft. Please take a look at the [documentation](https://docs.microsoft.com/azure/quantum/) for further instructions on what tools are available and how to [install](https://docs.microsoft.com/azure/quantum/install-overview-qdk/) them. 36 | 37 | ### *Where can I learn more about quantum development and/or quantum computing?* 38 | 39 | There are a lot of good resources, and we will list but a few suggestions to help you get started. 40 | Our [Microsoft Learn modules](https://docs.microsoft.com/learn/browse/?terms=quantum) are a good place to get started. The popular [Quantum Katas](https://github.com/microsoft/QuantumKatas) offer a hands-on experience consisting programming tasks that cover topics which progress from very simple to quite challenging. Further explanations can be found in our [tutorials](https://github.com/microsoft/QuantumKatas#list-of-tutorials-) and [docs](https://docs.microsoft.com/azure/quantum/overview-azure-quantum). 41 | 42 | 43 | -------------------------------------------------------------------------------- /Specifications/Language/3_Expressions/CopyAndUpdateExpressions.md: -------------------------------------------------------------------------------- 1 | # Copy-and-update expressions 2 | 3 | To reduce the need for mutable bindings, Q# supports copy-and-update expressions for value types with item access. User-defined types and arrays both are immutable and fall into this category. 4 | User-defined types allow you to access items via name, whereas arrays allow you to access items via an index or range of indices. 5 | 6 | Copy-and-update expressions instantiate a new value with all items set to the corresponding value in the original expression, except certain specified items, which are set to the ones defined on the right-hand side of the expression. 7 | They are constructed using a ternary operator `w/` `<-`; the syntax `w/` should be read as the commonly used short notation for "with": 8 | 9 | ```qsharp 10 | original w/ itemAccess <- modification 11 | ``` 12 | 13 | where `original` is either an expression of user-defined type or an array expression. For the corresponding requirements for `itemAccess` and `modification`, see [Copy-and-update of user-defined types](#copy-and-update-of-user-defined-types) and [Copy-and-update of arrays](#copy-and-update-of-arrays). 14 | 15 | In terms of precedence, the copy-and-update operator is left-associative and has lowest precedence, and, in particular, lower precedence than the range operator (`..`) or the ternary conditional operator (`?` `|`). 16 | The chosen left associativity allows easy chaining of copy-and-update expressions: 17 | 18 | ```qsharp 19 | let model = Default() 20 | w/ Structure <- ClassifierStructure() 21 | w/ Parameters <- parameters 22 | w/ Bias <- bias; 23 | ``` 24 | 25 | As for any operator that constructs an expression of the same type as the left-most expression involved, the corresponding [evaluate-and-reassign statement](https://github.com/microsoft/qsharp-language/blob/main/Specifications/Language/2_Statements/VariableDeclarationsAndReassignments.md#evaluate-and-reassign-statements) is available. 26 | The two following statements, for example, achieve the following: The first statement declares a mutable variable `arr` and binds it to the default value of an integer array. The second statement then builds a new array with the first item (with index 0) set to 10 and reassigns it to `arr`. 27 | 28 | ```qsharp 29 | mutable arr = [0, size = 3]; // arr contains [0, 0, 0] 30 | set arr w/= 0 <- 10; // arr contains [10, 0, 0] 31 | ``` 32 | 33 | The second statement is just short-hand for the more verbose syntax `set arr = arr w/ 0 <- 10;`. 34 | 35 | ## Copy-and-update of user-defined types 36 | 37 | If the value `original` is a user-defined type, then `itemAccess` denotes the name of the item that diverges from the original value. This is not just another expression, like `original` and `modification`, because the ability to use the item name without any further qualification is limited to this context; it is one of two [contextual expressions](https://github.com/microsoft/qsharp-language/blob/main/Specifications/Language/3_Expressions/ContextualExpressions.md#contextual-and-omitted-expressions) in Q#. 38 | 39 | The type of the `modification` expression needs to match the type of the named item that diverges. 40 | For instance, if `complex` contains the value `Complex(0., 0.)`, where the type `Complex` is defined [here](https://github.com/microsoft/qsharp-language/blob/main/Specifications/Language/1_ProgramStructure/2_TypeDeclarations.md#type-declarations), then 41 | 42 | ```qsharp 43 | complex w/ Re <- 1. 44 | ``` 45 | 46 | is an expression of type `Complex` that evaluates to `Complex(1., 0.)`. 47 | 48 | ## Copy-and-update of arrays 49 | 50 | For arrays, `itemAccess` can be an arbitrary expression of a suitable type; 51 | the same types that are valid for array slicing are valid in this context. Concretely, the `itemAccess` expression can be of type `Int` or `Range`. If `itemAccess` is a value of type `Int`, then the type of `modification` has to match the item type of the array. If `itemAccess` is a value of type `Range`, then the type of `modification` has to be the same as the array type. 52 | 53 | For example, if `arr` contains an array `[0, 1, 2, 3]`, then 54 | 55 | - `arr w/ 0 <- 10` is the array `[10, 1, 2, 3]`. 56 | - `arr w/ 2 <- 10` is the array `[0, 1, 10, 3]`. 57 | - `arr w/ 0..2..3 <- [10, 12]` is the array `[10, 1, 12, 3]`. 58 | 59 | Copy-and-update expressions allow the efficient creation of new arrays based on existing ones. 60 | The implementation for copy-and-update expressions avoids copying the entire array 61 | by duplicating only the necessary parts to achieve the desired behavior and performs an in-place modification if possible. Hence, array initializations do not incur additional overhead due to immutability. 62 | 63 | The `Microsoft.Quantum.Arrays` namespace provides an arsenal of convenient tools for array creation and manipulation. 64 | 65 | Copy-and-update expressions are a convenient way to construct new arrays on the fly; 66 | the following expression, for example, evaluates to an array with all items set to `PauliI`, except the item at index `i`, which is set to `PauliZ`: 67 | 68 | ```qsharp 69 | [PauliI, size = n] w/ i <- PauliZ 70 | ``` 71 | 72 | ← [Back to Index](https://github.com/microsoft/qsharp-language/tree/main/Specifications/Language#index) 73 | -------------------------------------------------------------------------------- /Specifications/Language/2_Statements/QuantumMemoryManagement.md: -------------------------------------------------------------------------------- 1 | # Quantum memory management 2 | 3 | A program always starts without qubits, meaning you cannot pass values of type `Qubit` as entry point arguments. This restriction is intentional since the purpose of Q# is to express and reason about a program in its entirety. 4 | Instead, a program allocates and releases qubits, or quantum memory, as it goes. 5 | In this regard, Q# models the quantum computer as a qubit heap. 6 | 7 | Rather than supporting separate *allocate* and *release* statements for quantum memory, 8 | Q# supports quantum memory allocation in the form of *block statements*, where the memory is accessible only within the scope of that block statement. The statement block can be implicitly defined when allocating qubits for the duration of the current scope, as described in more detail in the sections about the `use` and `borrow` statements. Attempting to access the allocated qubits after the statement terminates results in a runtime exception. 9 | 10 | Q# has two statements, `use` and `borrow`, that instantiate qubit values, arrays of qubits, or any combination thereof. You can only use these statements within operations. They gather the instantiated qubit values, bind them to the variables specified in the statement, and then run a block of statements. 11 | At the end of the block, the bound variables go out of scope and are no longer defined. 12 | 13 | Q# distinguishes between the allocation of *clean* and *dirty* qubits. Clean qubits are unentangled and are not used by another part of the computation. Dirty qubits are qubits whose state is unknown and can even be entangled with other parts of the quantum processor's memory. 14 | 15 | ## Use statement 16 | 17 | Clean qubits are allocated by the `use` statement. 18 | 19 | - The statement consists of the keyword `use` followed by a binding and an optional statement block. 20 | - If a statement block is present, the qubits are only available within that block. 21 | Otherwise, the qubits are available until the end of the current scope. 22 | - The binding follows the same pattern as `let` statements: either a single symbol or a tuple of symbols, followed by an equals sign `=`, and either a single tuple or a matching tuple of *initializers*. 23 | 24 | Initializers are available either for a single qubit, indicated as `Qubit()`, or an array of qubits, `Qubit[n]`, where `n` is an `Int` expression. 25 | For example, 26 | 27 | ```qsharp 28 | use qubit = Qubit(); 29 | // ... 30 | 31 | use (aux, register) = (Qubit(), Qubit[5]); 32 | // ... 33 | 34 | use qubit = Qubit() { 35 | // ... 36 | } 37 | 38 | use (aux, register) = (Qubit(), Qubit[5]) { 39 | // ... 40 | } 41 | ``` 42 | 43 | The qubits are guaranteed to be in a |0⟩ state upon allocation. They are released at the end of the scope and are required to be in a |0⟩ state upon release. This requirement is not compiler-enforced since this would require a symbolic evaluation that quickly gets prohibitively expensive. When running on simulators, the requirement can be runtime enforced. On quantum processors, the requirement cannot be runtime enforced; an unmeasured qubit may be reset to |0⟩ via unitary transformation. Failing to do so results in incorrect behavior. 44 | 45 | The `use` statement allocates the qubits from the quantum processor's free qubit heap and returns them to the heap no later than the end of the scope in which the qubits are bound. 46 | 47 | ## Borrow statement 48 | 49 | The `borrow` statement grants access to qubits that are already allocated but not currently in use. These qubits can be in an arbitrary state and need to be in the same state again when the borrow statement terminates. 50 | Some quantum algorithms can use qubits without relying on their exact state, and without requiring that they are unentangled with the rest of the system. That is, they require extra qubits temporarily, but they can ensure that those qubits are returned exactly to their original state, independent of which state that was. 51 | 52 | If there are qubits that are in use but not touched during parts of a subroutine, those qubits can be borrowed for use by such an algorithm instead of allocating additional quantum memory. 53 | Borrowing instead of allocating can significantly reduce the overall quantum memory requirements of an algorithm and is a quantum example of a typical space-time tradeoff. 54 | 55 | A `borrow` statement follows the same pattern described previously for the [`use` statement](#use-statement), with the same initializers being available. 56 | For example, 57 | 58 | ```qsharp 59 | borrow qubit = Qubit(); 60 | // ... 61 | 62 | borrow (aux, register) = (Qubit(), Qubit[5]); 63 | // ... 64 | 65 | borrow qubit = Qubit() { 66 | // ... 67 | } 68 | 69 | borrow (aux, register) = (Qubit(), Qubit[5]) { 70 | // ... 71 | } 72 | ``` 73 | 74 | The borrowed qubits are in an unknown state and go out of scope at the end of the statement block. 75 | The borrower commits to leaving the qubits in the same state as when they were borrowed; that is, their state at the beginning and the end of the statement block is expected to be the same. 76 | 77 | The `borrow` statement retrieves in-use qubits that are guaranteed not to be used by the program from the time the qubit is bound until the last use of that qubit. 78 | If there aren't enough qubits available to borrow, then qubits are allocated from and returned to the heap like a `use` statement. 79 | 80 | > [!NOTE] 81 | > Among the known use-cases of dirty qubits are implementations of multi-controlled CNOT gates that require very few qubits, and implementations of incrementers. This [paper on factoring with qubits](https://arxiv.org/abs/1611.07995) provides an example of an algorithm that utilizes borrowed qubits. 82 | 83 | ← [Back to Index](https://github.com/microsoft/qsharp-language/tree/main/Specifications/Language#index) 84 | -------------------------------------------------------------------------------- /Specifications/Language/4_TypeSystem/README.md: -------------------------------------------------------------------------------- 1 | # Type System 2 | 3 | With the focus for quantum algorithm being more towards what should be achieved rather than on a problem representation in terms of data structures, taking a more functional perspective on language design is a natural choice. At the same time, the type system is a powerful mechanism that can be leveraged for program analysis and other compile-time checks that facilitate formulating robust code. 4 | 5 | All in all, the Q# type system is fairly minimalist, in the sense that there isn't an explicit notion of classes or interfaces as one might be used to from classical languages like C# or Java. We also take a somewhat pragmatic approach making incremental progress, such that certain construct are not yet fully integrated into the type system. An example are functors, which can be used within expressions but don't yet have a representation in the type system. Correspondingly, they cannot currently be assigned or passed as arguments, similar as it is the case for type parametrized callables. 6 | We expect to make incremental progress in extending the type system to be more complete, and balance immediate needs with longer-term plans. 7 | 8 | ## Available Types 9 | 10 | All types in Q# are [immutable](https://github.com/microsoft/qsharp-language/blob/main/Specifications/Language/4_TypeSystem/Immutability.md#immutability). 11 | 12 | Type | Description 13 | ---------|---------- 14 | `Unit` | Represents a singleton type whose only value is `()`. 15 | `Int` | Represents a 64-bit signed integer. [Values](https://github.com/microsoft/qsharp-language/blob/main/Specifications/Language/3_Expressions/ValueLiterals.md#int-literals) range from -9,223,372,036,854,775,808 to 9,223,372,036,854,775,807. 16 | `BigInt` | Represents signed integer [values](https://github.com/microsoft/qsharp-language/blob/main/Specifications/Language/3_Expressions/ValueLiterals.md#bigint-literals) of any size. 17 | `Double` | Represents a double-precision 64-bit floating-point number. [Values](https://github.com/microsoft/qsharp-language/blob/main/Specifications/Language/3_Expressions/ValueLiterals.md#double-literals) range from -1.79769313486232e308 to 1.79769313486232e308 as well as NaN (not a number). 18 | `Bool` | Represents Boolean [values](https://github.com/microsoft/qsharp-language/blob/main/Specifications/Language/3_Expressions/ValueLiterals.md#bool-literals). Possible values are `true` or `false`. 19 | `String` | Represents text as [values](https://github.com/microsoft/qsharp-language/blob/main/Specifications/Language/3_Expressions/ValueLiterals.md#string-literals) that consist of a sequence of UTF-16 code units. 20 | `Qubit` | Represents an opaque identifier by which virtual quantum memory can be addressed. [Values](https://github.com/microsoft/qsharp-language/blob/main/Specifications/Language/3_Expressions/ValueLiterals.md#qubit-literals) of type `Qubit` are instantiated via allocation. 21 | `Result` | Represents the result of a projective measurement onto the eigenspaces of a quantum operator with eigenvalues ±1. Possible [values](https://github.com/microsoft/qsharp-language/blob/main/Specifications/Language/3_Expressions/ValueLiterals.md#result-literals) are `Zero` or `One`. 22 | `Pauli` | Represents a single-qubit Pauli matrix. Possible [values](https://github.com/microsoft/qsharp-language/blob/main/Specifications/Language/3_Expressions/ValueLiterals.md#pauli-literals) are `PauliI`, `PauliX`, `PauliY`, or `PauliZ`. 23 | `Range` | Represents an ordered sequence of equally spaced `Int` values. [Values](https://github.com/microsoft/qsharp-language/blob/main/Specifications/Language/3_Expressions/ValueLiterals.md#range-literals) may represent sequences in ascending or descending order. 24 | Array | Represents [values](https://github.com/microsoft/qsharp-language/blob/main/Specifications/Language/3_Expressions/ValueLiterals.md#array-literals) that each contain a sequence of values of the same type. 25 | Tuple | Represents [values](https://github.com/microsoft/qsharp-language/blob/main/Specifications/Language/3_Expressions/ValueLiterals.md#tuple-literals) that each contain a fixed number of items of different types. Tuples containing a single element are equivalent to the element they contain. 26 | User defined type | Represents a [user defined type](https://github.com/microsoft/qsharp-language/blob/main/Specifications/Language/1_ProgramStructure/2_TypeDeclarations.md#type-declarations) consisting of named and anonymous items of different types. [Values](https://github.com/microsoft/qsharp-language/blob/main/Specifications/Language/3_Expressions/ValueLiterals.md#literals-for-user-defined-types) are instantiated by invoking the constructor. 27 | Operation | Represents a non-deterministic [callable](https://github.com/microsoft/qsharp-language/blob/main/Specifications/Language/4_TypeSystem/OperationsAndFunctions.md#operations-and-functions) that takes one (possibly tuple-valued) input argument returns one (possibly tuple-valued) output. Calls to operation [values](https://github.com/microsoft/qsharp-language/blob/main/Specifications/Language/3_Expressions/ValueLiterals.md#operation-literals) may have side effects and the output may vary for each call even when invoked with the same argument. 28 | Function | Represents a deterministic [callable](https://github.com/microsoft/qsharp-language/blob/main/Specifications/Language/4_TypeSystem/OperationsAndFunctions.md#operations-and-functions) that takes one (possibly tuple-valued) input argument returns one (possibly tuple-valued) output. Calls to function [values](https://github.com/microsoft/qsharp-language/blob/main/Specifications/Language/3_Expressions/ValueLiterals.md#function-literals) do not have side effects and the output is will always be the same given the same input. 29 | 30 | 31 | ← [Back to Index](https://github.com/microsoft/qsharp-language/tree/main/Specifications/Language#index) -------------------------------------------------------------------------------- /Specifications/Language/4_TypeSystem/OperationsAndFunctions.md: -------------------------------------------------------------------------------- 1 | # Operations and functions 2 | 3 | 4 | As elaborated in more detail in the description of the [qubit data type](https://github.com/microsoft/qsharp-language/blob/main/Specifications/Language/4_TypeSystem/QuantumDataTypes.md#qubits), quantum computations are executed in the form of side effects of operations that are natively supported on the targeted quantum processor. These are, in fact, the only side effects in Q#. Since all types are [immutable](https://github.com/microsoft/qsharp-language/blob/main/Specifications/Language/4_TypeSystem/Immutability.md#immutability), there are no side effects that impact a value that is explicitly represented in Q#. Hence, as long as an implementation of a certain callable does not directly or indirectly call any of these natively implemented operations, its execution always produces the same output, given the same input. 5 | 6 | Q# allows you to explicitly split out such purely deterministic computations into *functions*. Since the set of natively supported instructions is not fixed and built into the language itself, but rather fully configurable and expressed as a Q# library, determinism is guaranteed by requiring that functions can only call other functions and cannot call any operations. Additionally, native instructions that are not deterministic, that is, because they impact the quantum state, are represented as operations. With these two restrictions, functions can be evaluated as soon as their input value is known, and, in principle, never need to be evaluated more than once for the same input. 7 | 8 | 9 | Q# therefore distinguishes between two types of [callables](https://github.com/microsoft/qsharp-language/blob/main/Specifications/Language/1_ProgramStructure/3_CallableDeclarations.md): operations and functions. All callables take a single argument (potentially tuple-valued) as input and produce a single value (tuple) as output. Syntactically, the operation type is expressed as ` => is `, where `` is to be replaced by the argument type, `` is to be replaced by the return type, and `` is to be replaced by the [operation characteristics](#operation-characteristics). If no characteristics need to be specified, the syntax simplifies to ` => `. Similarly, function types are expressed as ` -> `. 10 | 11 | Aside from this determinism guarantee, there is little difference between operations and functions. Both are first-class values that can be passed around freely; they can be used as return values or arguments to other callables, as shown in the following example: 12 | 13 | ```qsharp 14 | function Pow<'T>(op : 'T => Unit, pow : Int) : 'T => Unit { 15 | return PowImpl(op, pow, _); 16 | } 17 | ``` 18 | 19 | 20 | Both can be instantiated based on a type-parametrized definition, for example, the [type parametrized](https://github.com/microsoft/qsharp-language/blob/main/Specifications/Language/4_TypeSystem/TypeParameterizations.md#type-parameterizations) function `Pow` above, and they can be [partially applied](https://github.com/microsoft/qsharp-language/blob/main/Specifications/Language/3_Expressions/Closures.md#partial-application) as done in the `return` statement in the example. 21 | 22 | 23 | 24 | ## Operation characteristics 25 | 26 | In addition to the information about input and output type, the operation type contains information about the characteristics of an operation. This information, for example, describes what functors are supported by the operation. Additionally, the internal representation also contains optimization-relevant information that is inferred by the compiler. 27 | 28 | The characteristics of an operation are a set of predefined and built-in labels. 29 | They are expressed in the form of a special expression that is part of the type signature. The expression consists either of one of the predefined sets of labels, or of a combination of characteristics expressions via a supported binary operator. 30 | 31 | There are two predefined sets, `Adj` and `Ctl`. 32 | 33 | - `Adj` is the set that contains a single label indicating that an operation is adjointable, meaning it supports the [`Adjoint` functor](https://github.com/microsoft/qsharp-language/blob/main/Specifications/Language/3_Expressions/FunctorApplication.md#functor-application) and the applied quantum transformation can be "undone", that is, it can be inverted. 34 | - `Ctl` is the set that contains a single label indicating that an operation is controllable, meaning it supports the [`Controlled` functor](https://github.com/microsoft/qsharp-language/blob/main/Specifications/Language/3_Expressions/FunctorApplication.md#functor-application) and 35 | its execution can be conditioned on the state of other qubits. 36 | 37 | The two operators that are supported as part of characteristics expressions are the set union `+` and the set intersection `*`. 38 | In EBNF, 39 | 40 | ``` 41 | predefined = "Adj" | "Ctl"; 42 | characteristics = predefined 43 | | "(", characteristics, ")" 44 | | characteristics ("+"|"*") characteristics; 45 | ``` 46 | 47 | As one would expect, `*` has higher precedence than `+` and both are left-associative. The type of a unitary operation, for example, is expressed as ` => is Adj + Ctl`, where `` should be replaced with the type of the operation argument, and `` replaced with the type of the returned value. 48 | 49 | >[!NOTE] 50 | >Indicating the characteristics of an operation in this form has two major advantages; for one, new labels can be introduced without having exponentially many language keywords for all combinations of labels. Perhaps more importantly, using expressions to indicate the characteristics of an operation also supports parameterizations over operation characteristics in the future. 51 | 52 | ← [Back to Index](https://github.com/microsoft/qsharp-language/tree/main/Specifications/Language#index) -------------------------------------------------------------------------------- /Specifications/Language/1_ProgramStructure/3_CallableDeclarations.md: -------------------------------------------------------------------------------- 1 | # Callable declarations 2 | 3 | Callable declarations, or *callables*, declared at a global scope are publicly visible by default; that is, they can be used anywhere in the same project and in a project that references the assembly in which they are declared. [Access modifiers](https://github.com/microsoft/qsharp-language/blob/main/Specifications/Language/1_ProgramStructure/6_AccessModifiers.md#access-modifiers) allow you to restrict their visibility to the current assembly only, such that implementation details can be changed later on without breaking code that relies on a specific library. 4 | 5 | Q# supports two kinds of callables: operations and functions. The topic [Operations and Functions](https://github.com/microsoft/qsharp-language/blob/main/Specifications/Language/4_TypeSystem/OperationsAndFunctions.md#operations-and-functions) elaborates on the distinction between the two. Q# also supports defining *templates*; for example, type-parameterized implementations for a certain callable. For more information, see [Type parameterizations](https://github.com/microsoft/qsharp-language/blob/main/Specifications/Language/4_TypeSystem/TypeParameterizations.md#type-parameterizations). 6 | 7 | > [!NOTE] 8 | > Such type-parametrized implementations may not use any language constructs that rely on particular properties of the type arguments; there is currently no way to express type constraints in Q#, or to define specialized implementations for particular type arguments. 9 | 10 | ## Callables and functors 11 | 12 | Q# allows specialized implementations for specific purposes; for example, operations in Q# can implicitly or explicitly define support for certain *functors*, and along with it the specialized implementations to invoke when a specific functor is applied to that callable. 13 | 14 | A functor, in a sense, is a factory that defines a new callable implementation that has a specific relation to the callable it was applied to. 15 | Functors are more than traditional higher-level functions in that they require access to the implementation details of the callable they have been applied to. In that sense, they are similar to other factories, such as templates. Correspondingly, they can be applied not just to callables, but templates as well. 16 | 17 | The example program shown in [Program implementation](https://github.com/microsoft/qsharp-language/tree/main/Specifications/Language/1_ProgramStructure), for example, defines the operation `ApplyQFT` and the operation `RunProgram`, which is used as an entry point. `ApplyQFT` takes a tuple-valued argument containing an integer and a value of type `LittleEndian` and returns a value of type `Unit`. The annotation `is Adj + Ctl` in the declaration of `ApplyQFT` indicates that the operation supports both the `Adjoint` and the `Controlled` functor. (For more information, see [Operation characteristics](https://github.com/microsoft/qsharp-language/blob/main/Specifications/Language/4_TypeSystem/OperationsAndFunctions.md#operation-characteristics)). If `Unitary` is an operation that has an adjoint and a controlled specialization, the expression `Adjoint Unitary` accesses the specialization that implements the adjoint of `Unitary`, and `Controlled Unitary` accesses the specialization that implements the controlled version of `Unitary`. 18 | In addition to the original operation’s argument, the controlled version of an operation takes an array of control qubits and then applies the original operation conditional on all of these control qubits being in a |1⟩ state. 19 | 20 | In theory, an operation for which an adjoint version can be defined should also have a controlled version and vice versa. In practice, however, it may be hard to develop an implementation for one or the other, especially for probabilistic implementations following a repeat-until-success pattern. 21 | For that reason, Q# allows you to declare support for each functor individually. However, since the two functors commute, an operation that defines support for both also has to have an implementation (usually implicitly defined, meaning compiler-generated) for when both functors are applied to the operation. 22 | 23 | There are no functors that can be applied to functions, such that functions currently have exactly one body implementation and no further specializations. For example, the declaration 24 | 25 | ```qsharp 26 | function Hello (name : String) : String { 27 | $"Hello, {name}!" 28 | } 29 | ``` 30 | 31 | is equivalent to 32 | 33 | ```qsharp 34 | function Hello (name : String) : String { 35 | body ... { 36 | $"Hello, {name}!" 37 | } 38 | } 39 | ``` 40 | 41 | Here, `body` specifies that the given implementation applies to the default body of the function `Hello`, meaning the implementation is invoked when no functors or other factory mechanisms have been applied prior to invocation. The three dots in `body ...` correspond to a compiler directive indicating that the argument items in the function declaration should be copy and pasted into this spot. 42 | 43 | The reasons behind explicitly indicating where the arguments of the parent callable declaration are to be copied and pasted are twofold: one, it is unnecessary to repeat the argument declaration, and two, and more importantly, it ensures that functors that require additional arguments, like the `Controlled` functor, can be introduced in a consistent manner. 44 | 45 | The same applies to operations; when there is exactly one specialization defining the implementation of the default body, the additional wrapping of the form `body ... { }` may be omitted. 46 | 47 | ## Recursion 48 | 49 | Q# callables can be directly or indirectly recursive and can be declared in any order; an operation or function may call itself, or it may call another callable that directly or indirectly calls the caller. 50 | 51 | When running on quantum hardware, stack space may be limited, and recursions that exceed that stack space limit result in a runtime error. 52 | 53 | ← [Back to Index](https://github.com/microsoft/qsharp-language/tree/main/Specifications/Language#index) 54 | -------------------------------------------------------------------------------- /Specifications/Language/4_TypeSystem/TypeParameterizations.md: -------------------------------------------------------------------------------- 1 | # Type parameterizations 2 | 3 | Q# supports type-parameterized operations and functions. The Q# standard libraries make heavy use of type-parametrized callables to provide a host of useful abstractions, including functions like `Mapped` and `Fold` that are familiar from functional languages. 4 | 5 | To motivate the concept of type parameterizations, consider the example of the function `Mapped`, which applies a given function to each value in an array and returns a new array with the computed values. This functionality can be perfectly described without specifying the item types of the input and output arrays. Since the exact types do not change the implementation of the function `Mapped`, it makes sense that it should be possible to define this implementation for arbitrary item types; we want to define a *factory* or *template* that, given the concrete types for the items in the input and output array, returns the corresponding function implementation. This notion is formalized in the form of type parameters. 6 | 7 | ## Concretization 8 | 9 | Any operation or function declaration may specify one or more type parameters that can be used as the types, or part of the types, of the callable's input or output, or both. The exceptions are entry points, which must be concrete and cannot be type-parametrized. Type parameter names start with a tick (') and may appear multiple times in the input and output types. 10 | All arguments that correspond to the same type parameter in the callable signature must be of the same type. 11 | 12 | A type-parametrized callable needs to be concretized, that is, it must be provided with the necessary type arguments before it can be assigned or passed as argument, such that all type parameters can be replaced with concrete types. A type is considered to be concrete if it is one of the built-in types, a user-defined type, or if it is concrete within the current scope. The following example illustrates what it means for a type to be concrete within the current scope, and is explained in more detail below: 13 | 14 | ```qsharp 15 | function Mapped<'T1, 'T2> ( 16 | mapper : 'T1 -> 'T2, 17 | array : 'T1[] 18 | ) : 'T2[] { 19 | 20 | mutable mapped = new 'T2[Length(array)]; 21 | for (i in IndexRange(array)) { 22 | set mapped w/= i <- mapper(array[i]); 23 | } 24 | return mapped; 25 | } 26 | 27 | function AllCControlled<'T3> ( 28 | ops : ('T3 => Unit)[] 29 | ) : ((Bool,'T3) => Unit)[] { 30 | 31 | return Mapped(CControlled<'T3>, ops); 32 | } 33 | ``` 34 | 35 | The function `CControlled` is defined in the `Microsoft.Quantum.Canon` namespace. It takes an operation `op` of type `'TIn => Unit` as argument and returns a new operation of type `(Bool, 'TIn) => Unit` that applies the original operation, provided a classical bit (of type `Bool`) is set to *true*; this is often referred to as the classically controlled version of `op`. 36 | 37 | The function `Mapped` takes an array of an arbitrary item type `'T1` as argument, applies the given `mapper` function to each item, and returns a new array of type `'T2[]` containing the mapped items. It is defined in the `Microsoft.Quantum.Array` namespace. For the purpose of the example, the type parameters are numbered to avoid making the discussion more confusing by giving the type parameters in both functions the same name. This is not necessary; type parameters for different callables may have the same name, and the chosen name is only visible and relevant within the definition of that callable. 38 | 39 | The function `AllCControlled` takes an array of operations and returns a new array containing the classically controlled versions of these operations. The call of `Mapped` resolves its type parameter `'T1` to `'T3 => Unit`, and its type parameter `'T2` to `(Bool,'T3) => Unit`. The resolving type arguments are inferred by the compiler based on the type of the given argument. We say that they are *implicitly* defined by the argument of the call expression. Type arguments can also be specified explicitly, as is done for `CControlled` in the same line. The explicit concretization `CControlled<'T3>` is necessary when the type arguments cannot be inferred. 40 | 41 | The type `'T3` is concrete within the context of `AllCControlled`, since it is known for each *invocation* of `AllCControlled`. That means that as soon as the entry point of the program - which cannot be type-parametrized - is known, so is the concrete type `'T3` for each call to `AllCControlled`, such that a suitable implementation for that particular type resolution can be generated. Once the entry point to a program is known, all usages of type parameters can be eliminated at compile-time. We refer to this process as *monomorphization*. 42 | 43 | Some restrictions are needed to ensure that this can indeed be done at compile-time as opposed to only at run time. 44 | 45 | ## Restrictions 46 | 47 | Consider the following example: 48 | 49 | ```qsharp 50 | operation Foo<'TArg> ( 51 | op : 'TArg => Unit, 52 | arg : 'TArg 53 | ) : Unit { 54 | 55 | let cbit = RandomInt(2) == 0; 56 | Foo(CControlled(op), (cbit, arg)); 57 | } 58 | ``` 59 | 60 | Ignoring that an invocation of `Foo` will result in an infinite loop, it serves for the purpose of illustration. `Foo` invokes itself with the classically controlled version of the original operation `op` that has been passed in, as well as a tuple containing a random classical bit in addition to the original argument. 61 | 62 | For each iteration in the recursion, the type parameter `'TArg` of the next call is resolved to `(Bool, 'TArg)`, where `'TArg` is the type parameter of the current call. Concretely, suppose `Foo` is invoked with the operation `H` and an argument `arg` of type `Qubit`. `Foo` will then invoke itself with a type argument `(Bool, Qubit)`, which will then invoke `Foo` with a type argument `(Bool, (Bool, Qubit))`, and so on. Clearly, in this case `Foo` cannot be monomorphized at compile-time. 63 | 64 | Additional restrictions apply to cycles in the call graph that involve only type-parametrized callables. Each callable needs to be invoked with the same set of type arguments after traversing the cycle. 65 | 66 | >[!NOTE] 67 | >It would be possible to be less restrictive and require that for each callable in the cycle, there is a finite number of cycles after which it is invoked with the original set of type arguments, such as the case for the following function: 68 | >```qsharp 69 | > function Bar<'T1,'T2,'T3>(a1:'T1, a2:'T2, a3:'T3) : Unit{ 70 | > Bar<'T2,'T3,'T1>(a2, a3, a1); 71 | > } 72 | >``` 73 | >For simplicity, the more restrictive requirement is enforced. Note that for cycles that involve at least one concrete callable without any type parameter, such a callable will ensure that the type-parametrized callables within that cycle are always called with a fixed set of type arguments. 74 | 75 | ← [Back to Index](https://github.com/microsoft/qsharp-language/tree/main/Specifications/Language#index) 76 | -------------------------------------------------------------------------------- /Specifications/Language/2_Statements/VariableDeclarationsAndReassignments.md: -------------------------------------------------------------------------------- 1 | # Variable declarations and reassignments 2 | 3 | Values can be bound to symbols using the `let` and `mutable` statements. 4 | These kinds of bindings provide a convenient way to access a value via the defined handle. 5 | Despite the misleading terminology borrowed from other languages, handles declared on a local scope and containing values are called *variables*. 6 | This may be misleading because `let` statements define *single-assignment handles*, which are handles that remain bound to the same value for the duration of their validity. Variables that can be re-bound to different values at different points in the code need to be explicitly declared as such, and are specified using the `mutable` statement. 7 | 8 | ```qsharp 9 | let var1 = 3; 10 | mutable var2 = 3; 11 | set var2 = var2 + 1; 12 | ``` 13 | 14 | In this example, the `let` statement declares a variable named `var1` that cannot be reassigned and always contains the value `3`. The `mutable` statement defines a variable `var2` that is temporarily bound to the value `3` but can be reassigned to a different value later on using a `set` statement, as shown in the last line. You can express the same statement with the shorter version `set var2 += 1;`, as is common in other languages. For more information, see [Evaluate and reassign statements](#evaluate-and-reassign-statements). 15 | 16 | To summarize: 17 | 18 | * `let` is used to create an immutable binding. 19 | * `mutable` is used to create a mutable binding. 20 | * `set` is used to change the value of a mutable binding. 21 | 22 | For all three statements, the left-hand side consists of a symbol or a symbol tuple. 23 | If the right-hand side of the binding is a tuple, then that tuple may be fully or partially deconstructed upon assignment. The only requirement for deconstruction is that the shape of the tuple on the right-hand side matches the shape of the symbol tuple on the left side. 24 | The symbol tuple may contain nested tuples or omitted symbols, or both, indicated by an underscore. 25 | For example: 26 | 27 | ```qsharp 28 | let (a, (_, b)) = (1, (2, 3)); // a is bound to 1, b is bound to 3 29 | mutable (x, y) = ((1, 2), [3, 4]); // x is bound to (1, 2), y is bound to [3, 4] 30 | set (x, _, y) = ((5, 6), 7, [8]); // x is re-bound to (5,6), y is re-bound to [8] 31 | ``` 32 | 33 | All assignments in Q# obey the same deconstruction rules, including, for example, qubit allocations and loop-variable assignments. 34 | 35 | For both kinds of bindings, the types of the variables are inferred from the right-hand side of the binding. The type of a variable always remains the same, and a `set` statement cannot change it. 36 | Local variables can be declared as either being mutable or immutable. There are some exceptions, such as loop-variables in `for` loops, where the behavior is predefined and cannot be specified. 37 | Function and operation arguments are always immutably bound. In combination with the lack of reference types, as discussed in the [Immutability](https://github.com/microsoft/qsharp-language/blob/main/Specifications/Language/4_TypeSystem/Immutability.md#immutability) topic, this means that a called function or operation can never change any values on the caller side. 38 | 39 | Since the states of `Qubit` values are not defined or observable from within Q#, this does not preclude the accumulation of quantum side effects, which are observable only via measurements. For more information, see [Quantum data types](https://github.com/microsoft/qsharp-language/blob/main/Specifications/Language/4_TypeSystem/QuantumDataTypes.md#qubits). 40 | 41 | Independent of how a value is bound, the values themselves are immutable. 42 | In particular, this is true for arrays and array items. 43 | In contrast to popular classical languages where arrays often are reference types, arrays in Q# - like all types - are value types and always immutable; that is, you cannot modify them after initialization. 44 | Changing the values accessed by array-type variables thus requires explicitly constructing a new array and reassigning it to the same symbol. For more information, see [Immutability](https://github.com/microsoft/qsharp-language/blob/main/Specifications/Language/4_TypeSystem/Immutability.md) and [Copy and update expressions](https://github.com/microsoft/qsharp-language/blob/main/Specifications/Language/3_Expressions/CopyAndUpdateExpressions.md#copy-and-update-expressions). 45 | 46 | ## Evaluate-and-reassign statements 47 | 48 | Statements of the form `set intValue += 1;` are common in many other languages. Here, `intValue` needs to be a mutably bound variable of type `Int`. 49 | Such statements provide a convenient way of concatenation if the right-hand side consists of applying a binary operator and the result is rebound to the left argument of the operator. 50 | For example, this code segment 51 | 52 | ```qsharp 53 | mutable counter = 0; 54 | for i in 1 .. 2 .. 10 { 55 | set counter += 1; 56 | // ... 57 | } 58 | ``` 59 | 60 | increments the value of the counter `counter` in each iteration of the `for` loop and is equivalent to 61 | 62 | ```qsharp 63 | mutable counter = 0; 64 | for i in 1 .. 2 .. 10 { 65 | set counter = counter + 1; 66 | // ... 67 | } 68 | ``` 69 | 70 | Similar statements exist for a wide range of [operators](https://github.com/microsoft/qsharp-language/blob/main/Specifications/Language/3_Expressions/PrecedenceAndAssociativity.md#operators). The `set` keyword in such evaluate-and-reassign statements must be followed by a single mutable variable, which is inserted as the left-most sub-expression by the compiler. 71 | Such evaluate-and-reassign statements exist for all operators where the type of the left-most sub-expression matches the expression type. 72 | More precisely, they are available for binary logical and bitwise operators including right and left shift, arithmetic expressions including exponentiation and modulus, and concatenations, as well as [copy-and-update expressions](https://github.com/microsoft/qsharp-language/blob/main/Specifications/Language/3_Expressions/CopyAndUpdateExpressions.md#copy-and-update-expressions). 73 | 74 | The following function example computes the sum of an array of [`Complex`](https://github.com/microsoft/qsharp-language/blob/main/Specifications/Language/1_ProgramStructure/2_TypeDeclarations.md#type-declarations) numbers: 75 | 76 | ```qsharp 77 | function ComplexSum(values : Complex[]) : Complex { 78 | mutable res = Complex(0., 0.); 79 | for complex in values { 80 | set res w/= Re <- res::Re + complex::Re; 81 | set res w/= Im <- res::Im + complex::Im; 82 | } 83 | return res; 84 | } 85 | ``` 86 | 87 | Similarly, the following function multiplies each item in an array with the given factor: 88 | 89 | ```qsharp 90 | function Multiplied(factor : Double, array : Double[]) : Double[] { 91 | mutable res = new Double[Length(array)]; 92 | for i in IndexRange(res) { 93 | set res w/= i <- factor * array[i]; 94 | } 95 | return res; 96 | } 97 | ``` 98 | 99 | For more information, see [Contextual expressions](https://github.com/microsoft/qsharp-language/blob/main/Specifications/Language/3_Expressions/ContextualExpressions.md#contextual-and-omitted-expressions), which contains other examples where expressions can be omitted in a specific context when a suitable expression can be inferred by the compiler. 100 | 101 | ← [Back to Index](https://github.com/microsoft/qsharp-language/tree/main/Specifications/Language#index) 102 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | ## Ignore Visual Studio temporary files, build results, and 2 | ## files generated by popular Visual Studio add-ons. 3 | ## 4 | ## Get latest from https://github.com/github/gitignore/blob/master/VisualStudio.gitignore 5 | 6 | # User-specific files 7 | *.rsuser 8 | *.suo 9 | *.user 10 | *.userosscache 11 | *.sln.docstates 12 | 13 | # User-specific files (MonoDevelop/Xamarin Studio) 14 | *.userprefs 15 | 16 | # Mono auto generated files 17 | mono_crash.* 18 | 19 | # Build results 20 | [Dd]ebug/ 21 | [Dd]ebugPublic/ 22 | [Rr]elease/ 23 | [Rr]eleases/ 24 | x64/ 25 | x86/ 26 | [Aa][Rr][Mm]/ 27 | [Aa][Rr][Mm]64/ 28 | bld/ 29 | [Bb]in/ 30 | [Oo]bj/ 31 | [Ll]og/ 32 | [Ll]ogs/ 33 | 34 | # Visual Studio 2015/2017 cache/options directory 35 | .vs/ 36 | # Uncomment if you have tasks that create the project's static files in wwwroot 37 | #wwwroot/ 38 | 39 | # Visual Studio 2017 auto generated files 40 | Generated\ Files/ 41 | 42 | # MSTest test Results 43 | [Tt]est[Rr]esult*/ 44 | [Bb]uild[Ll]og.* 45 | 46 | # NUnit 47 | *.VisualState.xml 48 | TestResult.xml 49 | nunit-*.xml 50 | 51 | # Build Results of an ATL Project 52 | [Dd]ebugPS/ 53 | [Rr]eleasePS/ 54 | dlldata.c 55 | 56 | # Benchmark Results 57 | BenchmarkDotNet.Artifacts/ 58 | 59 | # .NET Core 60 | project.lock.json 61 | project.fragment.lock.json 62 | artifacts/ 63 | 64 | # StyleCop 65 | StyleCopReport.xml 66 | 67 | # Files built by Visual Studio 68 | *_i.c 69 | *_p.c 70 | *_h.h 71 | *.ilk 72 | *.meta 73 | *.obj 74 | *.iobj 75 | *.pch 76 | *.pdb 77 | *.ipdb 78 | *.pgc 79 | *.pgd 80 | *.rsp 81 | *.sbr 82 | *.tlb 83 | *.tli 84 | *.tlh 85 | *.tmp 86 | *.tmp_proj 87 | *_wpftmp.csproj 88 | *.log 89 | *.vspscc 90 | *.vssscc 91 | .builds 92 | *.pidb 93 | *.svclog 94 | *.scc 95 | 96 | # Chutzpah Test files 97 | _Chutzpah* 98 | 99 | # Visual C++ cache files 100 | ipch/ 101 | *.aps 102 | *.ncb 103 | *.opendb 104 | *.opensdf 105 | *.sdf 106 | *.cachefile 107 | *.VC.db 108 | *.VC.VC.opendb 109 | 110 | # Visual Studio profiler 111 | *.psess 112 | *.vsp 113 | *.vspx 114 | *.sap 115 | 116 | # Visual Studio Trace Files 117 | *.e2e 118 | 119 | # TFS 2012 Local Workspace 120 | $tf/ 121 | 122 | # Guidance Automation Toolkit 123 | *.gpState 124 | 125 | # ReSharper is a .NET coding add-in 126 | _ReSharper*/ 127 | *.[Rr]e[Ss]harper 128 | *.DotSettings.user 129 | 130 | # TeamCity is a build add-in 131 | _TeamCity* 132 | 133 | # DotCover is a Code Coverage Tool 134 | *.dotCover 135 | 136 | # AxoCover is a Code Coverage Tool 137 | .axoCover/* 138 | !.axoCover/settings.json 139 | 140 | # Visual Studio code coverage results 141 | *.coverage 142 | *.coveragexml 143 | 144 | # NCrunch 145 | _NCrunch_* 146 | .*crunch*.local.xml 147 | nCrunchTemp_* 148 | 149 | # MightyMoose 150 | *.mm.* 151 | AutoTest.Net/ 152 | 153 | # Web workbench (sass) 154 | .sass-cache/ 155 | 156 | # Installshield output folder 157 | [Ee]xpress/ 158 | 159 | # DocProject is a documentation generator add-in 160 | DocProject/buildhelp/ 161 | DocProject/Help/*.HxT 162 | DocProject/Help/*.HxC 163 | DocProject/Help/*.hhc 164 | DocProject/Help/*.hhk 165 | DocProject/Help/*.hhp 166 | DocProject/Help/Html2 167 | DocProject/Help/html 168 | 169 | # Click-Once directory 170 | publish/ 171 | 172 | # Publish Web Output 173 | *.[Pp]ublish.xml 174 | *.azurePubxml 175 | # Note: Comment the next line if you want to checkin your web deploy settings, 176 | # but database connection strings (with potential passwords) will be unencrypted 177 | *.pubxml 178 | *.publishproj 179 | 180 | # Microsoft Azure Web App publish settings. Comment the next line if you want to 181 | # checkin your Azure Web App publish settings, but sensitive information contained 182 | # in these scripts will be unencrypted 183 | PublishScripts/ 184 | 185 | # NuGet Packages 186 | *.nupkg 187 | # NuGet Symbol Packages 188 | *.snupkg 189 | # The packages folder can be ignored because of Package Restore 190 | **/[Pp]ackages/* 191 | # except build/, which is used as an MSBuild target. 192 | !**/[Pp]ackages/build/ 193 | # Uncomment if necessary however generally it will be regenerated when needed 194 | #!**/[Pp]ackages/repositories.config 195 | # NuGet v3's project.json files produces more ignorable files 196 | *.nuget.props 197 | *.nuget.targets 198 | 199 | # Microsoft Azure Build Output 200 | csx/ 201 | *.build.csdef 202 | 203 | # Microsoft Azure Emulator 204 | ecf/ 205 | rcf/ 206 | 207 | # Windows Store app package directories and files 208 | AppPackages/ 209 | BundleArtifacts/ 210 | Package.StoreAssociation.xml 211 | _pkginfo.txt 212 | *.appx 213 | *.appxbundle 214 | *.appxupload 215 | 216 | # Visual Studio cache files 217 | # files ending in .cache can be ignored 218 | *.[Cc]ache 219 | # but keep track of directories ending in .cache 220 | !?*.[Cc]ache/ 221 | 222 | # Others 223 | ClientBin/ 224 | ~$* 225 | *~ 226 | *.dbmdl 227 | *.dbproj.schemaview 228 | *.jfm 229 | *.pfx 230 | *.publishsettings 231 | orleans.codegen.cs 232 | 233 | # Including strong name files can present a security risk 234 | # (https://github.com/github/gitignore/pull/2483#issue-259490424) 235 | #*.snk 236 | 237 | # Since there are multiple workflows, uncomment next line to ignore bower_components 238 | # (https://github.com/github/gitignore/pull/1529#issuecomment-104372622) 239 | #bower_components/ 240 | 241 | # RIA/Silverlight projects 242 | Generated_Code/ 243 | 244 | # Backup & report files from converting an old project file 245 | # to a newer Visual Studio version. Backup files are not needed, 246 | # because we have git ;-) 247 | _UpgradeReport_Files/ 248 | Backup*/ 249 | UpgradeLog*.XML 250 | UpgradeLog*.htm 251 | ServiceFabricBackup/ 252 | *.rptproj.bak 253 | 254 | # SQL Server files 255 | *.mdf 256 | *.ldf 257 | *.ndf 258 | 259 | # Business Intelligence projects 260 | *.rdl.data 261 | *.bim.layout 262 | *.bim_*.settings 263 | *.rptproj.rsuser 264 | *- [Bb]ackup.rdl 265 | *- [Bb]ackup ([0-9]).rdl 266 | *- [Bb]ackup ([0-9][0-9]).rdl 267 | 268 | # Microsoft Fakes 269 | FakesAssemblies/ 270 | 271 | # GhostDoc plugin setting file 272 | *.GhostDoc.xml 273 | 274 | # Node.js Tools for Visual Studio 275 | .ntvs_analysis.dat 276 | node_modules/ 277 | 278 | # Visual Studio 6 build log 279 | *.plg 280 | 281 | # Visual Studio 6 workspace options file 282 | *.opt 283 | 284 | # Visual Studio 6 auto-generated workspace file (contains which files were open etc.) 285 | *.vbw 286 | 287 | # Visual Studio LightSwitch build output 288 | **/*.HTMLClient/GeneratedArtifacts 289 | **/*.DesktopClient/GeneratedArtifacts 290 | **/*.DesktopClient/ModelManifest.xml 291 | **/*.Server/GeneratedArtifacts 292 | **/*.Server/ModelManifest.xml 293 | _Pvt_Extensions 294 | 295 | # Paket dependency manager 296 | .paket/paket.exe 297 | paket-files/ 298 | 299 | # FAKE - F# Make 300 | .fake/ 301 | 302 | # CodeRush personal settings 303 | .cr/personal 304 | 305 | # Python Tools for Visual Studio (PTVS) 306 | __pycache__/ 307 | *.pyc 308 | 309 | # Cake - Uncomment if you are using it 310 | # tools/** 311 | # !tools/packages.config 312 | 313 | # Tabs Studio 314 | *.tss 315 | 316 | # Telerik's JustMock configuration file 317 | *.jmconfig 318 | 319 | # BizTalk build output 320 | *.btp.cs 321 | *.btm.cs 322 | *.odx.cs 323 | *.xsd.cs 324 | 325 | # OpenCover UI analysis results 326 | OpenCover/ 327 | 328 | # Azure Stream Analytics local run output 329 | ASALocalRun/ 330 | 331 | # MSBuild Binary and Structured Log 332 | *.binlog 333 | 334 | # NVidia Nsight GPU debugger configuration file 335 | *.nvuser 336 | 337 | # MFractors (Xamarin productivity tool) working folder 338 | .mfractor/ 339 | 340 | # Local History for Visual Studio 341 | .localhistory/ 342 | 343 | # BeatPulse healthcheck temp database 344 | healthchecksdb 345 | 346 | # Backup folder for Package Reference Convert tool in Visual Studio 2017 347 | MigrationBackup/ 348 | 349 | # Ionide (cross platform F# VS Code tools) working folder 350 | .ionide/ 351 | 352 | # VS Code working folder 353 | .vscode/ 354 | 355 | -------------------------------------------------------------------------------- /Specifications/Language/1_ProgramStructure/4_SpecializationDeclarations.md: -------------------------------------------------------------------------------- 1 | # Specialization declarations 2 | 3 | As explained in the section about [callable declarations](https://github.com/microsoft/qsharp-language/blob/main/Specifications/Language/1_ProgramStructure/3_CallableDeclarations.md#callable-declarations), there is currently no reason to explicitly declare specializations for functions. This topic applies to operations and elaborates on how to declare the necessary specializations to support certain functors. 4 | 5 | It is quite a common problem in quantum computing to require the adjoint of a given transformation. Many quantum algorithms require both an operation and its adjoint to perform a computation. 6 | Q# employs symbolic computation that can automatically generate the corresponding adjoint implementation for a particular body implementation. This generation is possible even for implementations that freely mix classical and quantum computations. There are, however, some restrictions that apply in this case. For example, auto-generation is not supported for performance reasons if the implementation makes use of mutable variables. Moreover, each operation called within the body generates the corresponding adjoint needs to support the `Adjoint` functor itself. 7 | 8 | Even though one cannot easily undo measurements in the multi-qubit case, it is possible to combine measurements so that the applied transformation is unitary. In this case, it means that, even though the body implementation contains measurements that on their own don't support the `Adjoint` functor, the body in its entirety is adjointable. Nonetheless, auto-generating the adjoint implementation will fail in this case. For this reason, it is possible to manually specify the implementation. 9 | The compiler automatically generates optimized implementations for common patterns such as [conjugations](https://github.com/microsoft/qsharp-language/blob/main/Specifications/Language/3_Expressions/Conjugations.md#conjugations). 10 | Nonetheless, an explicit specialization may be desirable to define a more optimized implementation by hand. It is possible to specify any one implementation and any number of implementations explicitly. 11 | 12 | > [!NOTE] 13 | > The correctness of such a manually specified implementation is not verified by the compiler. 14 | 15 | In the following example, the declaration for an operation `SWAP`, which exchanges the state of two qubits `q1` and `q2`, declares an explicit specialization for its adjoint version and its controlled version. While the implementations for `Adjoint SWAP` and `Controlled SWAP` are thus user-defined, the compiler still needs to generate the implementation for the combination of both functors (`Controlled Adjoint SWAP`, which is the same as `Adjoint Controlled SWAP`). 16 | 17 | ```qsharp 18 | operation SWAP (q1 : Qubit, q2 : Qubit) : Unit 19 | is Adj + Ctl { 20 | 21 | body ... { 22 | CNOT(q1, q2); 23 | CNOT(q2, q1); 24 | CNOT(q1, q2); 25 | } 26 | 27 | adjoint ... { 28 | SWAP(q1, q2); 29 | } 30 | 31 | controlled (cs, ...) { 32 | CNOT(q1, q2); 33 | Controlled CNOT(cs, (q2, q1)); 34 | CNOT(q1, q2); 35 | } 36 | } 37 | 38 | ``` 39 | 40 | ## Auto-generation directives 41 | 42 | When determining how to generate a particular specialization, the compiler prioritizes user-defined implementations. This means that if an adjoint specialization is user-defined and a controlled specialization is auto-generated, then the controlled adjoint specialization is generated based on the user-defined adjoint and vice versa. In this case, both specializations are user-defined. 43 | As the auto-generation of an adjoint implementation is subject to more limitation, the controlled adjoint specialization defaults to generating the controlled specialization of the explicitly defined implementation of the adjoint specialization. 44 | 45 | In the case of the `SWAP` implementation, the better option is to adjoint the controlled specialization to avoid unnecessarily conditioning the execution of the first and the last `CNOT` on the state of the control qubits. 46 | Adding an explicit declaration for the controlled adjoint version that specifies a suitable *generation directive* forces the compiler to generate the controlled adjoint specialization based on the manually specified implementation of the controlled version instead. Such an explicit declaration of a specialization that is to be generated by the compiler takes the form 47 | 48 | ```qsharp 49 | controlled adjoint invert; 50 | ``` 51 | 52 | and is inserted inside the declaration of `SWAP`. 53 | On the other hand, inserting the line 54 | 55 | ```qsharp 56 | controlled adjoint distribute; 57 | ``` 58 | 59 | forces the compiler to generate the specialization based on the defined (or generated) adjoint specialization. See this [partial specialization inference](https://github.com/microsoft/qsharp-language/blob/main/Implemented/partial-specialization-inference.md) proposal for more details. 60 | 61 | For the operation `SWAP`, there is a better option. `SWAP` is *self-adjoint*, that is, it is its own inverse; the -defined implementation of the adjoint merely calls the body of `SWAP`. You express this with the directive 62 | 63 | ```qsharp 64 | adjoint self; 65 | ``` 66 | 67 | Declaring the adjoint specialization in this manner ensures that the controlled adjoint specialization that is automatically inserted by the compiler merely invokes the controlled specialization. 68 | 69 | The following generation directives exist and are valid: 70 | 71 | | Specialization | Directive(s) | 72 | |---|---| 73 | | `body` specialization: | - | 74 | | `adjoint` specialization: | `self`, `invert` | 75 | | `controlled` specialization: | `distribute` | 76 | | `controlled adjoint` specialization: | `self`, `invert`, `distribute` | 77 | 78 | That all generation directives are valid for a controlled adjoint specialization is not a coincidence; as long as functors commute, the set of valid generation directives for implementing the specialization for a combination of functors is always the union of the set of valid generators for each one. 79 | 80 | In addition to the previously listed directives, the directive `auto` is valid for all specializations except `body`; it indicates that the compiler should automatically pick a suitable generation directive. 81 | The declaration 82 | 83 | ```qsharp 84 | operation DoNothing() : Unit { 85 | body ... { } 86 | adjoint auto; 87 | controlled auto; 88 | controlled adjoint auto; 89 | } 90 | ``` 91 | 92 | is equivalent to 93 | 94 | ```qsharp 95 | operation DoNothing() : Unit 96 | is Adj + Ctl { } 97 | ``` 98 | 99 | The annotation `is Adj + Ctl` in this example specifies the [*operation characteristics*](https://github.com/microsoft/qsharp-language/blob/main/Specifications/Language/4_TypeSystem/OperationsAndFunctions.md#operation-characteristics), which contain the information about what functors a particular operation supports. 100 | 101 | While for readability's sake, it is recommended that you annotate each operation with a complete description of its characteristics, the compiler automatically inserts or completes the annotation based on explicitly declared specializations. Conversely, the compiler also generates specializations that haven't been declared explicitly but need to exist based on the annotated characteristics. We say the given annotation has *implicitly declared* these specializations. The compiler automatically generates the necessary specializations if it can, picking a suitable directive. 102 | Q# thus supports inference of both operation characteristics and existing specializations based on (partial) annotations and explicitly defined specializations. 103 | 104 | In a sense, specializations are similar to individual overloads for the same callable, with the caveat that certain restrictions apply to which overloads you can declare. 105 | 106 | ← [Back to Index](https://github.com/microsoft/qsharp-language/tree/main/Specifications/Language#index) 107 | -------------------------------------------------------------------------------- /Specifications/Language/README.md: -------------------------------------------------------------------------------- 1 | # Q# Language 2 | 3 | Q# is part of Microsoft's [Quantum Development Kit](https://www.microsoft.com/quantum) and provides rich IDE support and tools for program visualization and analysis. 4 | Our goal is to support the development of future large-scale applications while supporting user's first efforts in that direction on current quantum hardware. 5 | 6 | The type system permits Q# programs to safely interleave and naturally represent the composition of classical and quantum computations. A Q# program may express arbitrary classical computations based on quantum measurements that execute while qubits remain live, meaning they are not released and maintain their state. Even though the full complexity of such computations requires further hardware development, Q# programs can be targeted to run on various quantum hardware backends in [Azure Quantum](https://azure.microsoft.com/services/quantum/). 7 | 8 | Q# is a stand-alone language offering a high level of abstraction. There is no notion of a quantum state or a circuit; instead, Q# implements programs in terms of statements and expressions, much like classical programming languages. Distinct quantum capabilities (such as support for functors and control-flow constructs) facilitate expressing, for example, phase estimation and quantum chemistry algorithms. 9 | 10 | ## Index 11 | 12 | 1. [Program Structure](https://github.com/microsoft/qsharp-language/tree/main/Specifications/Language/1_ProgramStructure#program-execution) 13 | 1. [Namespaces](https://github.com/microsoft/qsharp-language/blob/main/Specifications/Language/1_ProgramStructure/1_Namespaces.md#namespaces) 14 | 1. [Type Declarations](https://github.com/microsoft/qsharp-language/blob/main/Specifications/Language/1_ProgramStructure/2_TypeDeclarations.md#type-declarations) 15 | 1. [Callable Declarations](https://github.com/microsoft/qsharp-language/blob/main/Specifications/Language/1_ProgramStructure/3_CallableDeclarations.md#callable-declarations) 16 | 1. [Specialization Declarations](https://github.com/microsoft/qsharp-language/blob/main/Specifications/Language/1_ProgramStructure/4_SpecializationDeclarations.md#specialization-declarations) 17 | 1. [Attributes](https://github.com/microsoft/qsharp-language/blob/main/Specifications/Language/1_ProgramStructure/5_Attributes.md#attributes) 18 | 1. [Access Modifiers](https://github.com/microsoft/qsharp-language/blob/main/Specifications/Language/1_ProgramStructure/6_AccessModifiers.md#access-modifiers) 19 | 1. [Comments & Documentation](https://github.com/microsoft/qsharp-language/blob/main/Specifications/Language/1_ProgramStructure/7_Comments.md#comments) 20 | 21 | 1. [Statements](https://github.com/microsoft/qsharp-language/tree/main/Specifications/Language/2_Statements#statements) 22 | 1. [Quantum Memory Management](https://github.com/microsoft/qsharp-language/blob/main/Specifications/Language/2_Statements/QuantumMemoryManagement.md#quantum-memory-management) 23 | 1. [Variable Declaration \& Reassignment](https://github.com/microsoft/qsharp-language/blob/main/Specifications/Language/2_Statements/VariableDeclarationsAndReassignments.md#variable-declarations-and-reassignments) 24 | 1. [Visibility of Local Variables](https://github.com/microsoft/qsharp-language/blob/main/Specifications/Language/2_Statements/BindingScopes.md#visibility-of-local-variables) 25 | 26 | 1. [Expressions](https://github.com/microsoft/qsharp-language/tree/main/Specifications/Language/3_Expressions#expressions) 27 | 1. [Precedence \& Associativity](https://github.com/microsoft/qsharp-language/blob/main/Specifications/Language/3_Expressions/PrecedenceAndAssociativity.md#precedence-and-associativity) 28 | 1. [Operators](https://github.com/microsoft/qsharp-language/blob/main/Specifications/Language/3_Expressions/PrecedenceAndAssociativity.md#operators) 29 | 1. [Copy-and-Update Expressions](https://github.com/microsoft/qsharp-language/blob/main/Specifications/Language/3_Expressions/CopyAndUpdateExpressions.md#copy-and-update-expressions) 30 | 1. [Conditional Expressions](https://github.com/microsoft/qsharp-language/blob/main/Specifications/Language/3_Expressions/ConditionalExpressions.md#conditional-expressions) 31 | 1. [Comparative Expressions](https://github.com/microsoft/qsharp-language/blob/main/Specifications/Language/3_Expressions/ComparativeExpressions.md#equality-comparison) 32 | 1. [Logical Expressions](https://github.com/microsoft/qsharp-language/blob/main/Specifications/Language/3_Expressions/LogicalExpressions.md#logical-expressions) 33 | 1. [Bitwise Expressions](https://github.com/microsoft/qsharp-language/blob/main/Specifications/Language/3_Expressions/BitwiseExpressions.md#bitwise-expressions) 34 | 1. [Arithmetic Expressions](https://github.com/microsoft/qsharp-language/blob/main/Specifications/Language/3_Expressions/ArithmeticExpressions.md#arithmetic-expressions) 35 | 1. [Concatenations](https://github.com/microsoft/qsharp-language/blob/main/Specifications/Language/3_Expressions/Concatentation.md#concatenation) 36 | 1. [Modifiers \& Combinators](https://github.com/microsoft/qsharp-language/blob/main/Specifications/Language/3_Expressions/PrecedenceAndAssociativity.md#modifiers-and-combinators) 37 | 1. [Functor Application](https://github.com/microsoft/qsharp-language/blob/main/Specifications/Language/3_Expressions/FunctorApplication.md#functor-application) 38 | 1. [Item Access Expressions](https://github.com/microsoft/qsharp-language/blob/main/Specifications/Language/3_Expressions/ItemAccessExpressions.md#item-access) 39 | 1. [Call Expressions](https://github.com/microsoft/qsharp-language/blob/main/Specifications/Language/3_Expressions/CallExpressions.md#call-expressions) 40 | 1. [Conditional Branching](https://github.com/microsoft/qsharp-language/blob/main/Specifications/Language/3_Expressions/ConditionalBranching.md#conditional-branching) 41 | 1. [Conditional Loops](https://github.com/microsoft/qsharp-language/blob/main/Specifications/Language/3_Expressions/ConditionalLoops.md#conditional-loops) 42 | 1. [Conjugations](https://github.com/microsoft/qsharp-language/blob/main/Specifications/Language/3_Expressions/Conjugations.md#conjugations) 43 | 1. [Iterations](https://github.com/microsoft/qsharp-language/blob/main/Specifications/Language/3_Expressions/Iterations.md#iterations) 44 | 1. [Returns and Termination](https://github.com/microsoft/qsharp-language/blob/main/Specifications/Language/3_Expressions/ReturnsAndTermination.md#returns-and-termination) 45 | 1. [Contextual Expressions](https://github.com/microsoft/qsharp-language/blob/main/Specifications/Language/3_Expressions/ContextualExpressions.md#contextual-and-omitted-expressions) 46 | 1. [Value Literals](https://github.com/microsoft/qsharp-language/blob/main/Specifications/Language/3_Expressions/ValueLiterals.md#literals) \& [Default Values](https://github.com/microsoft/qsharp-language/blob/main/Specifications/Language/3_Expressions/ValueLiterals.md#default-values) 47 | 1. [Closures](https://github.com/microsoft/qsharp-language/blob/main/Specifications/Language/3_Expressions/Closures.md) 48 | 1. [Identifiers](https://github.com/microsoft/qsharp-language/blob/main/Specifications/Language/3_Expressions/Identifiers.md#identifiers) 49 | 50 | 1. [Type System](https://github.com/microsoft/qsharp-language/tree/main/Specifications/Language/4_TypeSystem#type-system) 51 | 1. [Operations \& Functions](https://github.com/microsoft/qsharp-language/blob/main/Specifications/Language/4_TypeSystem/OperationsAndFunctions.md#operations-and-functions) 52 | 1. [Quantum Data Types](https://github.com/microsoft/qsharp-language/blob/main/Specifications/Language/4_TypeSystem/QuantumDataTypes.md#quantum-specific-data-types) 53 | 1. [Immutability](https://github.com/microsoft/qsharp-language/blob/main/Specifications/Language/4_TypeSystem/Immutability.md#immutability) 54 | 1. [Singleton Tuple Equivalence](https://github.com/microsoft/qsharp-language/blob/main/Specifications/Language/4_TypeSystem/SingletonTupleEquivalence.md#singleton-tuple-equivalence) 55 | 1. [Subtyping and Variance](https://github.com/microsoft/qsharp-language/blob/main/Specifications/Language/4_TypeSystem/SubtypingAndVariance.md#subtyping-and-variance) 56 | 1. [Type Parameterizations](https://github.com/microsoft/qsharp-language/blob/main/Specifications/Language/4_TypeSystem/TypeParameterizations.md#type-parameterizations) 57 | 1. [Type Inference](https://github.com/microsoft/qsharp-language/blob/main/Specifications/Language/4_TypeSystem/TypeInference.md#type-inference) 58 | 59 | 1. [Grammar](https://github.com/microsoft/qsharp-language/tree/main/Specifications/Language/5_Grammar#grammar) 60 | -------------------------------------------------------------------------------- /Specifications/Language/5_Grammar/QSharpParser.g4: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. 2 | // Licensed under the MIT License. 3 | 4 | parser grammar QSharpParser; 5 | 6 | options { 7 | language = CSharp; 8 | tokenVocab = QSharpLexer; 9 | } 10 | 11 | document : namespace* EOF; 12 | 13 | // Namespace 14 | 15 | namespace : 'namespace' qualifiedName BraceLeft namespaceElement* BraceRight; 16 | 17 | qualifiedName : Identifier ('.' Identifier)*; 18 | 19 | namespaceElement 20 | : openDirective # OpenElement 21 | | typeDeclaration # TypeElement 22 | | callableDeclaration # CallableElement 23 | ; 24 | 25 | // Open Directive 26 | 27 | openDirective : 'open' name=qualifiedName ('as' alias=qualifiedName)? ';'; 28 | 29 | // Declaration 30 | 31 | attribute : '@' expression; 32 | 33 | access : 'internal'; 34 | 35 | declarationPrefix : attribute* access?; 36 | 37 | // Type Declaration 38 | 39 | typeDeclaration : declarationPrefix 'newtype' Identifier '=' underlyingType ';'; 40 | 41 | underlyingType 42 | : typeDeclarationTuple # TupleUnderlyingType 43 | | type # UnnamedTypeItem 44 | ; 45 | 46 | typeDeclarationTuple : '(' (typeTupleItem (',' typeTupleItem)*)? ')'; 47 | 48 | typeTupleItem 49 | : namedItem # NamedTypeItem 50 | | underlyingType # UnderlyingTypeItem 51 | ; 52 | 53 | namedItem : Identifier ':' type; 54 | 55 | // Callable Declaration 56 | 57 | callableDeclaration 58 | : declarationPrefix keyword=('function' | 'operation') 59 | Identifier typeParameterBinding? parameterTuple 60 | ':' returnType=type characteristics? 61 | callableBody 62 | ; 63 | 64 | typeParameterBinding : '<' (TypeParameter (',' TypeParameter)*)? '>'; 65 | 66 | parameterTuple : '(' (parameter (',' parameter)*)? ')'; 67 | 68 | parameter 69 | : namedItem # NamedParameter 70 | | parameterTuple # TupledParameter 71 | ; 72 | 73 | characteristics : 'is' characteristicsExpression; 74 | 75 | characteristicsExpression 76 | : 'Adj' # AdjointCharacteristics 77 | | 'Ctl' # ControlledCharacteristics 78 | | '(' characteristicsExpression ')' # CharacteristicGroup 79 | | left=characteristicsExpression '*' right=characteristicsExpression # IntersectCharacteristics 80 | | left=characteristicsExpression '+' right=characteristicsExpression # UnionCharacteristics 81 | ; 82 | 83 | callableBody 84 | : scope # CallableStatements 85 | | BraceLeft specialization* BraceRight # CallableSpecializations 86 | ; 87 | 88 | specialization : specializationName+ specializationGenerator; 89 | 90 | specializationName : 'body' | 'adjoint' | 'controlled'; 91 | 92 | specializationGenerator 93 | : 'auto' ';' # AutoGenerator 94 | | 'self' ';' # SelfGenerator 95 | | 'invert' ';' # InvertGenerator 96 | | 'distribute' ';' # DistributeGenerator 97 | | 'intrinsic' ';' # IntrinsicGenerator 98 | | providedSpecialization # ProvidedGenerator 99 | ; 100 | 101 | providedSpecialization : specializationParameterTuple? scope; 102 | 103 | specializationParameterTuple : '(' (specializationParameter (',' specializationParameter)*)? ')'; 104 | 105 | specializationParameter : Identifier | '...'; 106 | 107 | // Type 108 | 109 | type 110 | : '_' # MissingType 111 | | '(' (type (',' type)* ','?)? ')' # TupleType 112 | | TypeParameter # TypeParameter 113 | | type '[' ']' # ArrayType 114 | | from=type arrow=('->' | '=>') to=type characteristics? # CallableType 115 | | 'BigInt' # BigIntType 116 | | 'Bool' # BoolType 117 | | 'Double' # DoubleType 118 | | 'Int' # IntType 119 | | 'Pauli' # PauliType 120 | | 'Qubit' # QubitType 121 | | 'Range' # RangeType 122 | | 'Result' # ResultType 123 | | 'String' # StringType 124 | | 'Unit' # UnitType 125 | | qualifiedName # UserDefinedType 126 | ; 127 | 128 | // Statement 129 | 130 | statement 131 | : expression ';' # ExpressionStatement 132 | | 'return' expression ';' # ReturnStatement 133 | | 'fail' expression ';' # FailStatement 134 | | 'let' symbolBinding '=' expression ';' # LetStatement 135 | | 'mutable' symbolBinding '=' expression ';' # MutableStatement 136 | | 'set' symbolBinding '=' expression ';' # SetStatement 137 | | 'set' Identifier updateOperator expression ';' # UpdateStatement 138 | | 'set' Identifier 'w/=' index=expression '<-' value=expression ';' # UpdateWithStatement 139 | | 'if' expression scope # IfStatement 140 | | 'elif' expression scope # ElifStatement 141 | | 'else' scope # ElseStatement 142 | | 'for' (forBinding | '(' forBinding ')') scope # ForStatement 143 | | 'while' expression scope # WhileStatement 144 | | 'repeat' scope # RepeatStatement 145 | | 'until' expression (';' | 'fixup' scope) # UntilStatement 146 | | 'within' scope # WithinStatement 147 | | 'apply' scope # ApplyStatement 148 | | keyword=('use' | 'using' | 'borrow' | 'borrowing') (qubitBinding | '(' qubitBinding ')') (scope | ';') # QubitDeclaration 149 | ; 150 | 151 | scope : BraceLeft statement* BraceRight; 152 | 153 | symbolBinding 154 | : '_' # DiscardSymbol 155 | | Identifier # SymbolName 156 | | '(' (symbolBinding (',' symbolBinding)* ','?)? ')' # SymbolTuple 157 | ; 158 | 159 | updateOperator 160 | : '^=' 161 | | '*=' 162 | | '/=' 163 | | '%=' 164 | | '+=' 165 | | '-=' 166 | | '>>>=' 167 | | '<<<=' 168 | | '&&&=' 169 | | '^^^=' 170 | | '|||=' 171 | | 'and=' 172 | | 'or=' 173 | ; 174 | 175 | forBinding : symbolBinding 'in' expression; 176 | 177 | qubitBinding : symbolBinding '=' qubitInitializer; 178 | 179 | qubitInitializer 180 | : 'Qubit' '(' ')' # SingleQubit 181 | | 'Qubit' '[' length=expression ']' # QubitArray 182 | | '(' (qubitInitializer (',' qubitInitializer)* ','?)? ')' # QubitTuple 183 | ; 184 | 185 | // Expression 186 | 187 | expression 188 | : '_' # MissingExpression 189 | | qualifiedName typeTuple? # IdentifierExpression 190 | | IntegerLiteral # IntegerExpression 191 | | BigIntegerLiteral # BigIntegerExpression 192 | | DoubleLiteral # DoubleExpression 193 | | DoubleQuote stringContent* StringDoubleQuote # StringExpression 194 | | DollarQuote interpStringContent* InterpDoubleQuote # InterpStringExpression 195 | | boolLiteral # BoolExpression 196 | | resultLiteral # ResultExpression 197 | | pauliLiteral # PauliExpression 198 | | '(' (expression (',' expression)* ','?)? ')' # TupleExpression 199 | | '[' (expression (',' expression)* ','?)? ']' # ArrayExpression 200 | | '[' value=expression ',' size '=' length=expression ']' # SizedArrayExpression 201 | | 'new' type '[' length=expression ']' # NewArrayExpression 202 | | expression '::' Identifier # NamedItemAccessExpression 203 | | array=expression '[' index=expression ']' # ArrayAccessExpression 204 | | expression '!' # UnwrapExpression 205 | | 'Controlled' expression # ControlledExpression 206 | | 'Adjoint' expression # AdjointExpression 207 | | callable=expression '(' (args+=expression (',' args+=expression)* ','?)? ')' # CallExpression 208 | | op=('!' | '+' | '-' | 'not' | '~~~') expression # PrefixOpExpression 209 | | left=expression '^' right=expression # ExponentExpression 210 | | left=expression op=('*' | '/' | '%') right=expression # MultiplyExpression 211 | | left=expression op=('+' | '-') right=expression # AddExpression 212 | | left=expression op=('>>>' | '<<<') right=expression # ShiftExpression 213 | | left=expression op=('>' | '<' | '>=' | '<=') right=expression # CompareExpression 214 | | left=expression op=('==' | '!=') right=expression # EqualsExpression 215 | | left=expression '&&&' right=expression # BitwiseAndExpression 216 | | left=expression '^^^' right=expression # BitwiseXorExpression 217 | | left=expression '|||' right=expression # BitwiseOrExpression 218 | | left=expression op=('&&' | 'and') right=expression # AndExpression 219 | | left=expression op=('||' | 'or') right=expression # OrExpression 220 | | cond=expression '?' then=expression '|' else=expression # ConditionalExpression 221 | | left=expression '..' right=expression # RangeExpression 222 | | expression '...' # RightOpenRangeExpression 223 | | '...' expression # LeftOpenRangeExpression 224 | | '...' # OpenRangeExpression 225 | | record=expression 'w/' index=expression '<-' value=expression # UpdateExpression 226 | | symbolBinding arrow=('->' | '=>') expression # LambdaExpression 227 | ; 228 | 229 | size : Identifier { _localctx.Identifier().Symbol.Text == "size" }?; 230 | 231 | typeTuple : '<' (type (',' type)* ','?)? '>'; 232 | 233 | boolLiteral : 'false' | 'true'; 234 | resultLiteral : 'Zero' | 'One'; 235 | pauliLiteral : 'PauliI' | 'PauliX' | 'PauliY' | 'PauliZ'; 236 | 237 | stringContent : StringEscape | StringText; 238 | 239 | interpStringContent 240 | : InterpStringEscape # InterpStringEscapeContent 241 | | InterpBraceLeft expression BraceRight # InterpExpressionContent 242 | | InterpStringText # InterpTextContent 243 | ; 244 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | ## DEPRECATION NOTICE 2 | 3 | **This repository is deprecated.** 4 | 5 | For the Modern QDK repository, please visit [Microsoft/qsharp](http://github.com/microsoft/qsharp). 6 | 7 | You can also try out the Modern QDK in VS Code for Web at [vscode.dev/quantum](https://vscode.dev/quantum). 8 | 9 | For more information about the Modern QDK and Azure Quantum, visit [https://aka.ms/AQ/Documentation](https://aka.ms/AQ/Documentation). 10 | 11 | ## Contributing 12 | 13 | Suggestions for features and adaptions are filed and tracked in the form of [issues](https://github.com/microsoft/qsharp-language/issues) on this repository. 14 | We greatly appreciate your feedback and contribution to the discussion in the form of comments and votes on open issues. Better understanding the needs of the community will help us make better decisions. 15 | 16 | If you have a suggestion for a feature and would like to share your thoughts, we encourage you to file an issue following our [suggestion template](https://github.com/microsoft/qsharp-language/issues/new?template=suggestion.md). The [following section](#process-and-implementation) describes the process and workflow in more detail. For a suggestion to be adopted it needs to align with the general vision for Q# and the Q# language [design principles](#design-principles). We do not generally revisit design decisions that have been made unless there is new information to consider, e.g. due to scientific or technical breakthroughs. 17 | 18 | We also highly welcome contributions to help implement new features. Please take a look at the section on [implementation](#implementation) for information regarding how to engage. 19 | We refer to [this document](https://github.com/microsoft/qsharp-language/blob/main/CODE_OF_CONDUCT.md) regarding contributing and the [Microsoft Open Source Code of Conduct](https://opensource.microsoft.com/codeofconduct/). 20 | 21 | # Design Principles 22 | 23 | A multitude of aspects ultimately factor into the decision to pursue a certain design direction. Given the early stages of quantum computing and the uncertainty around the architecture of future quantum hardware, designing a high-level language is challenging. Nonetheless, we believe it is worth the effort. 24 | The following list may give some insight into the principles guiding the Q# language design: 25 | 26 | 1. **Q# is hardware agnostic.** 27 | We strive to design a language that provides the means to express and leverage powerful quantum computing concepts independent on how hardware evolves in the future. 28 | 29 | 2. **Q# is designed to scale to the full range of quantum applications.** 30 | To be useable across a wide range of applications, Q# allows to build reusable components and layers of abstractions. To achieve performance with growing quantum hardware size we need automation. We want to ensure the scalability of both applications and development effort. 31 | 32 | 3. **Q# is meant to make quantum solutions accessible and shareable across disciplines.** 33 | We are designing Q# to enable people to collaborate across disciplines, to make it easy to build on knowledge and share ideas, independent of background or education. 34 | 35 | 4. **Q# is focused on expressing information to optimize execution.** 36 | Our goal is to ensure an efficient execution of quantum components, independent of the context within which they are invoked. Q# allows the developer to communicate their knowledge about a computation so that the compiler can make an informed decision regarding how to translate it into instructions, leveraging information about the end-to-end application that is not available to the developer. 37 | 38 | 5. **Q# is a living body of work that will grow and evolve over time.** 39 | We share a vision of how quantum devices will revolutionize computing in the future. We also believe the quantum stack of the future will go beyond our current imagination. Correspondingly, our vision for Q# will adapt and change as the technology advances. 40 | 41 | In addition to these principles, we try to adhere to a general set of good practices, and there are other aspects to consider that factor into a decision whether to pursue a certain feature. Please take a look at other [considerations](https://github.com/microsoft/qsharp-language/blob/main/Guidelines.md) that factor into our decision as well as our [FAQs](https://github.com/microsoft/qsharp-language/blob/main/FAQ.md) and [API design principles](https://docs.microsoft.com/azure/quantum/contributing-api-design-principles) for further questions. 42 | 43 | 44 | ## Process and Implementation 45 | 46 | The development of a language feature consists of the following stages: 47 | 48 | ### *Suggestion:* 49 | An addition or modification to the Q# language starts with a suggestion. A suggestion is filed as issue on this repository following the [suggestion template](https://github.com/microsoft/qsharp-language/issues/new?template=suggestion.md). 50 | Once a suggestion has been filed, it will be discussed on the issue, resulting in a first conclusion regarding whether to further pursue it. It will be labeled either with `UnderReview` or `Declined` by the Language Design Team depending on the outcome. 51 | This stage should be fairly quick and will take a couple of weeks to a month or two. If a conclusion can't be reached at this time, e.g. because it is not clear that it can be supported by hardware or it depends on other features that are currently under development, it will be labeled with `OnHold`. 52 | 53 | ### *Review:* 54 | Once a feature is labeled as `UnderReview`, the next step is to work out a more detailed proposal for how the feature should look like. Such a proposal is made by filling out the [proposal template](https://github.com/microsoft/qsharp-language/blob/main/Templates/proposal.md). For the purpose of discussion and collaboration when working out the details, and for us to give early feedback, we encourage to make a draft PR early on even when the template is not yet fully filled in. Once the template is sufficiently filled in, the PR is published and will be reviewed. 55 | Based on full proposal, the issue with the suggestion will either be labeled with `ApprovedInPrinciple` and the proposal is merged into the [Approved](https://github.com/microsoft/qsharp-language/tree/main/Approved) folder, or it will be labeled with `Declined` and the PR is merged into the [Declined](https://github.com/microsoft/qsharp-language/tree/main/Declined) folder for archiving purposes. The issue itself will be closed. 56 | How long it takes to work out the full proposal can vary a lot depending on the functionality. 57 | 58 | ### *Implementation:* 59 | All proposals that have been approved in principle and are ready to be implemented can be found in the [Approved]((https://github.com/microsoft/qsharp-language/tree/main/Approved)) folder. When implementation starts, a new issue is created using the implementation template to track the progress. These issues are labeled with `Implementation`. The readme in the [Approved](https://github.com/microsoft/qsharp-language/tree/main/Approved) folder also contains a list of all proposals and a link to the corresponding issue if development has already started. 60 | If you would like to contribute to an ongoing implementation, please indicate your interest and offer your help on the corresponding issue. If you would like to start the implementation of a proposal that is not actively being developed, please create a new issue following the implementation template. We will respond on the issue for an initial discussion on how to go about implementing it. 61 | Any revisions to the original proposal based on insights gained during implementation will be raised and discussed via comments on the issue. 62 | 63 | ### *Release:* 64 | Once the implementation is complete, the proposal that reflects the implemented functionality is moved from the [Approved](https://github.com/microsoft/qsharp-language/tree/main/Approved) folder into the [Implemented](https://github.com/microsoft/qsharp-language/tree/main/Implemented) folder. As a last step before closing the corresponding issue, a PR to update the Q# language specification needs to be create and merged. The PR will only be merged once the functionality has been released as part of the QDK. We release a new QDK version at the end of each month and implemented features can be incorporated into any such release. At that time the corresponding issue will be labeled as `Released` and closed. 65 | 66 | 67 | ## Repository Content 68 | 69 | - Specification of the [Q# language](https://github.com/microsoft/qsharp-language/tree/main/Specifications/Language) shipped with the latest [QDK](https://www.microsoft.com/quantum/development-kit) version 70 | - Active proposals that are [under review](https://github.com/microsoft/qsharp-language/issues?q=is%3Aopen+is%3Aissue+label%3AUnderReview) 71 | - Proposals that have been [approved in principle](https://github.com/microsoft/qsharp-language/tree/main/Approved) but are not yet implemented 72 | - Features for which the implementation has [started](https://github.com/microsoft/qsharp-language/issues?q=is%3Aopen+is%3Aissue+label%3AImplementation) 73 | - Proposals for features that are [implemented](https://github.com/microsoft/qsharp-language/tree/main/Implemented) in the latest Q# version 74 | - Archived proposals for features that have been [declined](https://github.com/microsoft/qsharp-language/tree/main/Declined) 75 | - Suggestions that are currently [on hold](https://github.com/microsoft/qsharp-language/issues?q=is%3Aopen+is%3Aissue+label%3AOnHold) and need to be evaluated once more information is available 76 | - Suggestions that have been reviewed in the past, i.e. all [closed suggestions](https://github.com/microsoft/qsharp-language/issues?q=is%3Aissue+is%3Aclosed+label%3AApprovedInPrinciple+label%3ADeclined) for which a conclusion has been reached 77 | - [Templates](https://github.com/microsoft/qsharp-language/tree/main/Templates) for suggestions and proposals 78 | -------------------------------------------------------------------------------- /Specifications/Language/3_Expressions/ValueLiterals.md: -------------------------------------------------------------------------------- 1 | # Literals 2 | 3 | ## Unit literal 4 | 5 | The only existing literal for the [`Unit` type](https://github.com/microsoft/qsharp-language/tree/main/Specifications/Language/4_TypeSystem#available-types) is the value `()`. 6 | 7 | The `Unit` value is commonly used as an argument to callables, either because no other arguments need to be passed or to delay execution. It is also used as return value when no other value needs to be returned, which is the case for unitary operations, that is, operations that support the `Adjoint` and/or the `Controlled` functor. 8 | 9 | ## Int literals 10 | 11 | Value literals for the [`Int` type](https://github.com/microsoft/qsharp-language/tree/main/Specifications/Language/4_TypeSystem#available-types) can be expressed in binary, octal, decimal, or hexadecimal representation. Literals expressed in binary are prefixed with `0b`, with `0o` for octal, and with `0x` for hexadecimal. There is no prefix for the commonly used decimal representation. 12 | 13 | | Representation | Value Literal | 14 | | --- | --- | 15 | | Binary | `0b101010` | 16 | | Octal | `0o52` | 17 | | Decimal | `42` | 18 | | Hexadecimal | `0x2a` | 19 | 20 | ## BigInt literals 21 | 22 | Value literals for the [`BigInt` type](https://github.com/microsoft/qsharp-language/tree/main/Specifications/Language/4_TypeSystem#available-types) are always postfixed with `L` and can be expressed in binary, octal, decimal, or hexadecimal representation. Literals expressed in binary are prefixed with `0b`, with `0o` for octal, and with `0x` for hexadecimal. There is no prefix for the commonly used decimal representation. 23 | 24 | | Representation | Value Literal | 25 | | --- | --- | 26 | | Binary | `0b101010L` | 27 | | Octal | `0o52L` | 28 | | Decimal | `42L` | 29 | | Hexadecimal | `0x2aL` | 30 | 31 | ## Double literals 32 | 33 | Value literals for the [`Double` type](https://github.com/microsoft/qsharp-language/tree/main/Specifications/Language/4_TypeSystem#available-types) can be expressed in standard or scientific notation. 34 | 35 | | Representation | Value Literal | 36 | | --- | --- | 37 | | Standard | `0.1973269804` | 38 | | Scientific | `1.973269804e-1` | 39 | 40 | If nothing follows after the decimal point, then the digit after the decimal point may be omitted. For example, `1.` is a valid `Double` literal and the same as `1.0`. 41 | 42 | ## Bool literals 43 | 44 | Existing literals for the [`Bool` type](https://github.com/microsoft/qsharp-language/tree/main/Specifications/Language/4_TypeSystem#available-types) are `true` and `false`. 45 | 46 | ## String literals 47 | 48 | A value literal for the [`String` type](https://github.com/microsoft/qsharp-language/tree/main/Specifications/Language/4_TypeSystem#available-types) is an arbitrary length sequence of Unicode characters enclosed in double quotes. 49 | Inside of a string, the back-slash character `\` may be used to escape 50 | a double quote character, and to insert a new-line as `\n`, a carriage 51 | return as `\r`, and a tab as `\t`. 52 | 53 | The following are examples for valid string literals: 54 | 55 | ```qsharp 56 | "This is a simple string." 57 | "\"This is a more complex string.\", she said.\n" 58 | ``` 59 | 60 | Q# also supports *interpolated strings*. 61 | An interpolated string is a string literal that may contain any number of interpolation expressions. These expressions can be of arbitrary types. 62 | Upon construction, the expressions are evaluated and their `String` representation is inserted at the corresponding location within the defined literal. Interpolation is enabled by prepending the special character `$` directly before the initial quote, with no white space between them. 63 | 64 | For instance, if `res` is an expression that evaluates to `1`, then the second sentence in the following `String` literal displays "The result was 1.": 65 | 66 | ```qsharp 67 | $"This is an interpolated string. The result was {res}." 68 | ``` 69 | 70 | ## Qubit literals 71 | 72 | No literals for the [`Qubit` type](https://github.com/microsoft/qsharp-language/tree/main/Specifications/Language/4_TypeSystem#available-types) exist, since quantum memory is managed by the runtime. Values of type `Qubit` can hence only be obtained via [allocation](https://github.com/microsoft/qsharp-language/blob/main/Specifications/Language/2_Statements/QuantumMemoryManagement.md#quantum-memory-management). 73 | 74 | Values of type `Qubit` represent an opaque identifier by which a quantum bit, or *qubit*, can be addressed. The only operator they support is [equality comparison](https://github.com/microsoft/qsharp-language/blob/main/Specifications/Language/3_Expressions/ComparativeExpressions.md#equality-comparison). For more information on the `Qubit` data type, See [Qubits](https://github.com/microsoft/qsharp-language/blob/main/Specifications/Language/4_TypeSystem/QuantumDataTypes.md#qubits). 75 | 76 | ## Result literals 77 | 78 | Existing literals for the [`Result` type](https://github.com/microsoft/qsharp-language/tree/main/Specifications/Language/4_TypeSystem#available-types) are `Zero` and `One`. 79 | 80 | Values of type `Result` represent the result of a binary quantum measurement. 81 | `Zero` indicates a projection onto the +1 eigenspace, `One` indicates a projection onto the -1 eigenspace. 82 | 83 | ## Pauli literals 84 | 85 | Existing literals for the [`Pauli` type](https://github.com/microsoft/qsharp-language/tree/main/Specifications/Language/4_TypeSystem#available-types) are `PauliI`, `PauliX`, `PauliY`, and `PauliZ`. 86 | 87 | Values of type `Pauli` represent one of the four single-qubit [Pauli matrices](https://en.wikipedia.org/wiki/Pauli_matrices), with `PauliI` representing the identity. 88 | Values of type `Pauli` are commonly used to denote the axis for rotations and to specify with respect to which basis to measure. 89 | 90 | ## Range literals 91 | 92 | Value literals for the [`Range` type](https://github.com/microsoft/qsharp-language/tree/main/Specifications/Language/4_TypeSystem#available-types) are expressions of the form `start..step..stop`, where `start`, `step`, and `end` are expressions of type `Int`. If the step size is one, it may be omitted. For example, `start..stop` is a valid `Range` literal and the same as `start..1..stop`. 93 | 94 | Values of type `Range` represent a sequence of integers, where the first element in the sequence is `start`, and subsequent elements are obtained by adding `step` to the previous one, until `stop` is passed. 95 | `Range` values are inclusive at both ends, that is, the last element of the range is `stop` if the difference between `start` and `stop` is a multiple of `step`. 96 | A range may be empty if, for instance, `step` is positive and `stop < start`. 97 | 98 | The following are examples for valid `Range` literals: 99 | 100 | - `1..3` is the range 1, 2, 3. 101 | - `2..2..5` is the range 2, 4. 102 | - `2..2..6` is the range 2, 4, 6. 103 | - `6..-2..2` is the range 6, 4, 2. 104 | - `2..-2..1` is the range 2. 105 | - `2..1` is the empty range. 106 | 107 | For more information, see [Contextual expressions](https://github.com/microsoft/qsharp-language/blob/main/Specifications/Language/3_Expressions/ContextualExpressions.md#contextual-and-omitted-expressions). 108 | 109 | ## Array literals 110 | 111 | An [array](https://github.com/microsoft/qsharp-language/tree/main/Specifications/Language/4_TypeSystem#available-types) literal is a sequence of zero or more expressions, separated by commas and enclosed in brackets `[` and `]`; for example, `[1,2,3]`. 112 | All expressions must have a [common base type](https://github.com/microsoft/qsharp-language/blob/main/Specifications/Language/4_TypeSystem/SubtypingAndVariance.md#subtyping-and-variance), which is the item type of the array. If an empty array is specified with `[]`, a type annotation may be needed for the compiler to determine the appropriate type of the expression. 113 | 114 | Arrays of arbitrary length may be created using a sized-array expression. 115 | Such an expression is of the form `[expr, size = s]`, where `s` can be any expression of type `Int` and `expr` is evaluated to a value that will be the items of the array repeated `s` times. For example, `[1.2, size = 3]` creates the same array as `[1.2, 1.2, 1.2]`. 116 | 117 | ## Tuple literals 118 | 119 | A [tuple](https://github.com/microsoft/qsharp-language/tree/main/Specifications/Language/4_TypeSystem#available-types) literal is a sequence of one or more expressions of any type, separated by commas and enclosed in parentheses `(` and `)`. The type of the tuple includes the information about each item type. 120 | 121 | | Value Literal | Type | 122 | | --- | --- | 123 | | `("Id", 0, 1.)` | `(String, Int, Double)` | 124 | | `(PauliX,(3,1))` | `(Pauli, (Int, Int))` | 125 | 126 | Tuples containing a single item are treated as identical to the item itself, both in type and value, which is called [singleton tuple equivalence](https://github.com/microsoft/qsharp-language/blob/main/Specifications/Language/4_TypeSystem/SingletonTupleEquivalence.md#singleton-tuple-equivalence). 127 | 128 | Tuples are used to bundle values together into a single value, making it easier to pass them around. This makes it possible for every callable to take exactly one input and return exactly one output. 129 | 130 | ## Literals for user-defined types 131 | 132 | Values of a [user-defined type](https://github.com/microsoft/qsharp-language/tree/main/Specifications/Language/4_TypeSystem#available-types) are constructed by invoking their constructor. A default constructor is automatically generated when [declaring the type](https://github.com/microsoft/qsharp-language/blob/main/Specifications/Language/1_ProgramStructure/2_TypeDeclarations.md#type-declarations). It is currently not possible to define custom constructors. 133 | 134 | For instance, if `IntPair` has two items of type `Int`, then `IntPair(2, 3)` creates a new instance by invoking the default constructor. 135 | 136 | ## Operation and function literals 137 | 138 | Anonymous operations and functions can be created using a [lambda expression](https://github.com/microsoft/qsharp-language/blob/main/Specifications/Language/3_Expressions/Closures.md#lambda-expressions). 139 | 140 | ← [Back to Index](https://github.com/microsoft/qsharp-language/tree/main/Specifications/Language#index) 141 | -------------------------------------------------------------------------------- /Specifications/Language/3_Expressions/PrecedenceAndAssociativity.md: -------------------------------------------------------------------------------- 1 | # Precedence and associativity 2 | 3 | Precedence and associativity define the order in which operators are applied. Operators with higher precedence are bound to their arguments (operands) first, while operators with the same precedence bind in the direction of their associativity. 4 | For example, the expression `1+2*3` according to the precedence for addition and multiplication is equivalent to `1+(2*3)`, and `2^3^4` equals `2^(3^4)` since exponentiation is right-associative. 5 | 6 | ## Operators 7 | 8 | The following table lists the available operators in Q#, as well as their precedence and associativity. 9 | Additional [modifiers and combinators](#modifiers-and-combinators) are also listed, and bind tighter than any of these operators. 10 | 11 | | Description | Syntax | Operator | Associativity | Precedence | 12 | | --- | --- | --- | --- | --- | 13 | | [copy-and-update operator](https://github.com/microsoft/qsharp-language/blob/main/Specifications/Language/3_Expressions/CopyAndUpdateExpressions.md#copy-and-update-expressions) | `w/` `<-` | ternary | left | 1 | 14 | | [range operator](https://github.com/microsoft/qsharp-language/blob/main/Specifications/Language/3_Expressions/ValueLiterals.md#range-literals) | `..` | infix | left | 2 | 15 | | [conditional operator](https://github.com/microsoft/qsharp-language/blob/main/Specifications/Language/3_Expressions/ConditionalExpressions.md#conditional-expressions) | `? \|` | ternary | right | 3 | 16 | | [logical OR](https://github.com/microsoft/qsharp-language/blob/main/Specifications/Language/3_Expressions/LogicalExpressions.md#logical-expressions) | `or` | infix | left | 4 | 17 | | [logical AND](https://github.com/microsoft/qsharp-language/blob/main/Specifications/Language/3_Expressions/LogicalExpressions.md#logical-expressions) | `and` | infix | left | 5 | 18 | | [bitwise OR](https://github.com/microsoft/qsharp-language/blob/main/Specifications/Language/3_Expressions/BitwiseExpressions.md#bitwise-expressions) | `\|\|\|` | infix | left | 6 | 19 | | [bitwise XOR](https://github.com/microsoft/qsharp-language/blob/main/Specifications/Language/3_Expressions/BitwiseExpressions.md#bitwise-expressions) | `^^^` | infix | left | 7 | 20 | | [bitwise AND](https://github.com/microsoft/qsharp-language/blob/main/Specifications/Language/3_Expressions/BitwiseExpressions.md#bitwise-expressions) | `&&&` | infix | left | 8 | 21 | | [equality](https://github.com/microsoft/qsharp-language/blob/main/Specifications/Language/3_Expressions/ComparativeExpressions.md#equality-comparison) | `==` | infix | left | 9 | 22 | | [inequality](https://github.com/microsoft/qsharp-language/blob/main/Specifications/Language/3_Expressions/ComparativeExpressions.md#equality-comparison) | `!=` | infix | left | 9 | 23 | | [less-than-or-equal](https://github.com/microsoft/qsharp-language/blob/main/Specifications/Language/3_Expressions/ComparativeExpressions.md#quantitative-comparison) | `<=` | infix | left | 10 | 24 | | [less-than](https://github.com/microsoft/qsharp-language/blob/main/Specifications/Language/3_Expressions/ComparativeExpressions.md#quantitative-comparison) | `<` | infix | left | 11 | 25 | | [greater-than-or-equal](https://github.com/microsoft/qsharp-language/blob/main/Specifications/Language/3_Expressions/ComparativeExpressions.md#quantitative-comparison) | `>=` | infix | left | 11 | 26 | | [greater-than](https://github.com/microsoft/qsharp-language/blob/main/Specifications/Language/3_Expressions/ComparativeExpressions.md#quantitative-comparison) | `>` | infix | left | 11 | 27 | | [right shift](https://github.com/microsoft/qsharp-language/blob/main/Specifications/Language/3_Expressions/BitwiseExpressions.md#bitwise-expressions) | `>>>` | infix | left | 12 | 28 | | [left shift](https://github.com/microsoft/qsharp-language/blob/main/Specifications/Language/3_Expressions/BitwiseExpressions.md#bitwise-expressions) | `<<<` | infix | left | 12 | 29 | | [addition](https://github.com/microsoft/qsharp-language/blob/main/Specifications/Language/3_Expressions/ArithmeticExpressions.md#arithmetic-expressions) or [concatenation](https://github.com/microsoft/qsharp-language/blob/main/Specifications/Language/3_Expressions/Concatentation.md#concatenation) | `+` | infix | left | 13 | 30 | | [subtraction](https://github.com/microsoft/qsharp-language/blob/main/Specifications/Language/3_Expressions/ArithmeticExpressions.md#arithmetic-expressions) | `-` | infix | left | 13 | 31 | | [multiplication](https://github.com/microsoft/qsharp-language/blob/main/Specifications/Language/3_Expressions/ArithmeticExpressions.md#arithmetic-expressions) | `*` | infix | left | 14 | 32 | | [division](https://github.com/microsoft/qsharp-language/blob/main/Specifications/Language/3_Expressions/ArithmeticExpressions.md#arithmetic-expressions) | `/` | infix | left | 14 | 33 | | [modulus](https://github.com/microsoft/qsharp-language/blob/main/Specifications/Language/3_Expressions/ArithmeticExpressions.md#arithmetic-expressions) | `%` | infix | left | 14 | 34 | | [exponentiation](https://github.com/microsoft/qsharp-language/blob/main/Specifications/Language/3_Expressions/ArithmeticExpressions.md#arithmetic-expressions) | `^` | infix | right | 15 | 35 | | [bitwise NOT](https://github.com/microsoft/qsharp-language/blob/main/Specifications/Language/3_Expressions/BitwiseExpressions.md#bitwise-expressions) | `~~~` | prefix | right | 16 | 36 | | [logical NOT](https://github.com/microsoft/qsharp-language/blob/main/Specifications/Language/3_Expressions/LogicalExpressions.md#logical-expressions) | `not` | prefix | right | 16 | 37 | | [negative](https://github.com/microsoft/qsharp-language/blob/main/Specifications/Language/3_Expressions/ArithmeticExpressions.md#arithmetic-expressions) | `-` | prefix | right | 16 | 38 | 39 | Copy-and-update expressions necessarily need to have the lowest precedence to ensure a consistent behavior of the corresponding [evaluate-and-reassign statement](https://github.com/microsoft/qsharp-language/blob/main/Specifications/Language/2_Statements/VariableDeclarationsAndReassignments.md#evaluate-and-reassign-statements). 40 | Similar considerations hold for the range operator to ensure a consistent behavior of the corresponding [contextual expression](https://github.com/microsoft/qsharp-language/blob/main/Specifications/Language/3_Expressions/ContextualExpressions.md#contextual-and-omitted-expressions). 41 | 42 | ## Modifiers and combinators 43 | 44 | Modifiers can be seen as special operators that can be applied to certain expressions only. They can be assigned an artificial precedence to capture their behavior. 45 | 46 | For more information, see [Expressions](https://github.com/microsoft/qsharp-language/tree/main/Specifications/Language/3_Expressions#expressions). 47 | 48 | This artificial precedence is listed in the following table, along with how the precedence of operators and modifiers relates to how tightly item access combinators (`[`,`]` and `::` respectively) and call combinators (`(`, `)`) bind. 49 | 50 | | Description | Syntax | Operator | Associativity | Precedence | 51 | | --- | --- | --- | --- | --- | 52 | | [Call combinator](https://github.com/microsoft/qsharp-language/blob/main/Specifications/Language/3_Expressions/CallExpressions.md#call-expressions) | `(` `)` | n/a | left | 17 | 53 | | [Adjoint functor](https://github.com/microsoft/qsharp-language/blob/main/Specifications/Language/3_Expressions/CallExpressions.md#call-expressions) | `Adjoint` | prefix | right | 18 | 54 | | [Controlled functor](https://github.com/microsoft/qsharp-language/blob/main/Specifications/Language/3_Expressions/CallExpressions.md#call-expressions) | `Controlled` | prefix | right | 18 | 55 | | [Unwrap application](https://github.com/microsoft/qsharp-language/blob/main/Specifications/Language/3_Expressions/ItemAccessExpressions.md#item-access-for-user-defined-types) | `!` | postfix | left | 19 | 56 | | [Named item access](https://github.com/microsoft/qsharp-language/blob/main/Specifications/Language/3_Expressions/ItemAccessExpressions.md#item-access-for-user-defined-types) | `::` | n/a | left | 20 | 57 | | [Array item access](https://github.com/microsoft/qsharp-language/blob/main/Specifications/Language/3_Expressions/ItemAccessExpressions.md#array-item-access-and-array-slicing) | `[` `]` | n/a | left | 20 | 58 | | [Function lambda](https://github.com/microsoft/qsharp-language/blob/main/Specifications/Language/3_Expressions/Closures.md#lambda-expressions) | `->` | n/a | right | 21 | 59 | | [Operation lambda](https://github.com/microsoft/qsharp-language/blob/main/Specifications/Language/3_Expressions/Closures.md#lambda-expressions) | `=>` | n/a | right | 21 | 60 | 61 | To illustrate the implications of the assigned precedences, suppose you have a unitary operation `DoNothing` (as defined in [Specialization declarations](https://github.com/microsoft/qsharp-language/blob/main/Specifications/Language/1_ProgramStructure/4_SpecializationDeclarations.md#specialization-declarations)), a callable `GetStatePrep` that returns a unitary operation, and an array `algorithms` that contains items of type `Algorithm` defined as follows 62 | 63 | ```qsharp 64 | newtype Algorithm = ( 65 | Register : LittleEndian, 66 | Initialize : Transformation, 67 | Apply : Transformation 68 | ); 69 | 70 | newtype Transformation = 71 | LittleEndian => Unit is Adj + Ctl; 72 | ``` 73 | 74 | where `LittleEndian` is defined in [Type declarations](https://github.com/microsoft/qsharp-language/blob/main/Specifications/Language/1_ProgramStructure/2_TypeDeclarations.md#type-declarations). 75 | 76 | The following expressions, then, are all valid: 77 | 78 | ```qsharp 79 | GetStatePrep()(arg) 80 | (Transformation(GetStatePrep()))!(arg) 81 | Adjoint DoNothing() 82 | Controlled Adjoint DoNothing(cs, ()) 83 | Controlled algorithms[0]::Apply!(cs, _) 84 | algorithms[0]::Register![i] 85 | ``` 86 | 87 | Looking at the precedences defined in the table above, you can see that the parentheses around `(Transformation(GetStatePrep()))` are necessary for the subsequent unwrap operator to be applied to the `Transformation` value rather than the returned operation. 88 | However, parentheses are not required in `GetStatePrep()(arg)`; functions are applied left-to-right, so this expression is equivalent to `(GetStatePrep())(arg)`. 89 | Functor applications also don't require parentheses around them in order to invoke the corresponding specialization, nor do array or named item access expressions. Thus, the expression `arr2D[i][j]` is perfectly valid, as is `algorithms[0]::Register![i]`. 90 | 91 | ← [Back to Index](https://github.com/microsoft/qsharp-language/tree/main/Specifications/Language#index) 92 | --------------------------------------------------------------------------------