Skip to content
This repository was archived by the owner on Jan 12, 2024. It is now read-only.
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions Specifications/Language/2_Statements/CallStatements.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,8 @@ call statements in a sense are the generic way of supporting patterns that aren'

```qsharp
operation ApplyWithInputTransformation<'TArg, 'TIn>(
fn : ('TIn -> 'TArg),
op : ('TArg => Unit),
fn : 'TIn -> 'TArg,
op : 'TArg => Unit,
input : 'TIn
) : Unit {

Expand Down
12 changes: 6 additions & 6 deletions Specifications/Language/3_Expressions/ConditionalExpressions.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,15 +11,15 @@ For instance, in an expression `a == b ? C(qs) | D(qs)`, if `a` equals `b` then
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 of the two ultimately yields the value to which the expression evaluates, its type will always match the determined base type.

For example, if
- `Op1` is of type `(Qubit[] => Unit is Adj)`
- `Op2` is of type `(Qubit[] => Unit is Ctl)`
- `Op3` is of type `(Qubit[] => Unit is Adj + Ctl)`
- `Op1` is of type `Qubit[] => Unit is Adj`
- `Op2` is of type `Qubit[] => Unit is Ctl`
- `Op3` is of type `Qubit[] => Unit is Adj + Ctl`

then

- `cond ? Op1 | Op2` is of type `(Qubit[] => Unit)`
- `cond ? Op1 | Op3` is of type `(Qubit[] => Unit is Adj)`
- `cond ? Op2 | Op3` is of type `(Qubit[] => Unit is Ctl)`
- `cond ? Op1 | Op2` is of type `Qubit[] => Unit`
- `cond ? Op1 | Op3` is of type `Qubit[] => Unit is Adj`
- `cond ? Op2 | Op3` is of type `Qubit[] => Unit is Ctl`

See the section on [subtyping](https://github.com/microsoft/qsharp-language/blob/main/Specifications/Language/4_TypeSystem/SubtypingAndVariance.md#subtyping-and-variance) for more detail.

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ This artificial precedence is listed in the table below, which also shows how th

| Description | Syntax | Operator | Associativity | Precedence |
| --- | --- | --- | --- | --- |
| [Call combinator](https://github.com/microsoft/qsharp-language/blob/main/Specifications/Language/2_Statements/CallStatements.md#call-statements) | `(` `)` | n/a | right | 900 |
| [Call combinator](https://github.com/microsoft/qsharp-language/blob/main/Specifications/Language/2_Statements/CallStatements.md#call-statements) | `(` `)` | n/a | left | 900 |
| [Adjoint functor](https://github.com/microsoft/qsharp-language/blob/main/Specifications/Language/2_Statements/CallStatements.md#call-statements) | `Adjoint` | prefix | right | 950 |
| [Controlled functor](https://github.com/microsoft/qsharp-language/blob/main/Specifications/Language/2_Statements/CallStatements.md#call-statements) | `Controlled` | prefix | right | 950 |
| [Unwrap application](https://github.com/microsoft/qsharp-language/blob/main/Specifications/Language/3_Expressions/ItemAccessExpressions.md#item-access-for-user-defined-types) | `!` | postfix | left | 1000 |
Expand All @@ -64,24 +64,23 @@ To illustrate the implications of the assigned precedences, suppose we have a un
Apply : Transformation
);

newtype Transformation = (
LittleEndian => Unit is Adj + Ctl
);
newtype Transformation =
LittleEndian => Unit is Adj + Ctl;
```

where `LittleEndian` is defined in [this section](https://github.com/microsoft/qsharp-language/blob/main/Specifications/Language/1_ProgramStructure/2_TypeDeclarations.md#type-declarations).
Then the following expressions are all valid:
```qsharp
(GetStatePrep())(arg)
GetStatePrep()(arg)
(Transformation(GetStatePrep()))!(arg)
Adjoint DoNothing()
Controlled Adjoint DoNothing(cs, ())
Controlled algorithms[0]::Apply!(cs, _)
algorithms[0]::Register![i]
```
Looking at the precedences defined in the table above, we 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.
Similarly, the syntax `GetStatePrep()(arg)` doesn't lead to a valid expression; parenthesis are required around the `GetStatePrep` call in order to invoke the returned callable.
Functor applications on the other hand don't require parentheses around them in order to invoke the corresponding specialization. Neither do array or named item access expressions, such that an expression `arr2D[i][j]` is perfectly valid, just like `algorithms[0]::Register![i]` is.
However, parentheses are not required in `GetStatePrep()(arg)`; functions are applied left-to-right, so this expression is equivalent to `(GetStatePrep())(arg)`.
Functor applications also don't require parentheses around them in order to invoke the corresponding specialization. Neither do array or named item access expressions, such that an expression `arr2D[i][j]` is perfectly valid, just like `algorithms[0]::Register![i]` is.


← [Back to Index](https://github.com/microsoft/qsharp-language/tree/main/Specifications/Language#index)
10 changes: 5 additions & 5 deletions Specifications/Language/4_TypeSystem/OperationsAndFunctions.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,13 +4,13 @@ As elaborated in more detail in the description of the [qubits](https://github.c

Q# allows 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, but cannot call any operations. Additionally, native instructions that are not deterministic, e.g., because they impact the quantum state are represented as operations. With these two restrictions, function 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.

Q# therefore distinguishes between two types of callables: operations and functions. All callables take a single (potentially tuple-valued) argument as input and produce a single value (tuple) as output. Syntactically, the operation type is expressed as `(<TIn> => <TOut> is <Char>)`, where `<TIn>` is to be replaced by the argument type, `<TOut>` is to be replaced by the return type, and `<Char>` is to be replaced by the [operation characteristics](#operation-characteristics). If no characteristics need to be specified, the syntax simplifies to `(<TIn> => <TOut>)`. Similarly, function types are expressed as `(<TIn> -> <TOut>)`.
Q# therefore distinguishes between two types of callables: operations and functions. All callables take a single (potentially tuple-valued) argument as input and produce a single value (tuple) as output. Syntactically, the operation type is expressed as `<TIn> => <TOut> is <Char>`, where `<TIn>` is to be replaced by the argument type, `<TOut>` is to be replaced by the return type, and `<Char>` is to be replaced by the [operation characteristics](#operation-characteristics). If no characteristics need to be specified, the syntax simplifies to `<TIn> => <TOut>`. Similarly, function types are expressed as `<TIn> -> <TOut>`.

There is little difference between operations and functions beside this determinism guarantee. Both are first-class values that can be passed around freely; they can be used as return values or arguments to other callables, as illustrated by the example below.
```qsharp
function Pow<`T>(op:(`T => Unit, pow : Int) : (`T => Unit){
return PowImpl(op, pow, _);
}
function Pow<'T>(op : 'T => Unit, pow : Int) : 'T => Unit {
return PowImpl(op, pow, _);
}
```

They can be instantiated based on a type parametrized definition such as, e.g., 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/PartialApplication.md#partial-application) as done in Line 2 in the example.
Expand All @@ -36,7 +36,7 @@ In EBNF,
| "(", characteristics, ")"
| characteristics ("+"|"*") characteristics;
```
As one would expect, `*` has higher precedence than `+` and both are left-associative. The type of a unitary operation for example is expressed as `(<TIn> => <TOut> is Adj + Ctl)` where `<TIn>` should be replace with the type of the operation argument, and `<TOut>` with the type of the returned value.
As one would expect, `*` has higher precedence than `+` and both are left-associative. The type of a unitary operation for example is expressed as `<TIn> => <TOut> is Adj + Ctl` where `<TIn>` should be replaced with the type of the operation argument, and `<TOut>` with the type of the returned value.

### *Discussion*
>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 permits to support parameterizations over operation characteristics in the future.
Expand Down
8 changes: 4 additions & 4 deletions Specifications/Language/4_TypeSystem/TypeParameterizations.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ A type parametrized callable needs to be concretized — i.e. provided with the

```qsharp
function Mapped<'T1, 'T2> (
mapper : ('T1 -> 'T2),
mapper : 'T1 -> 'T2,
array : 'T1[]
) : 'T2[] {

Expand All @@ -31,11 +31,11 @@ A type parametrized callable needs to be concretized — i.e. provided with the
}
```

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`.
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`.

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.

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 it is done for `CControlled` in the same line. The explicit concretization `CControlled<'T3>` is necessary when the type arguments cannot be inferred.
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 it is done for `CControlled` in the same line. The explicit concretization `CControlled<'T3>` is necessary when the type arguments cannot be inferred.

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 know, 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*.

Expand All @@ -46,7 +46,7 @@ A couple of restrictions are needed to ensure that this can indeed be done at co
>
>```qsharp
> operation Foo<'TArg> (
> op : ('TArg => Unit),
> op : 'TArg => Unit,
> arg : 'TArg
> ) : Unit {
>
Expand Down
11 changes: 3 additions & 8 deletions Specifications/Language/5_Grammar/QSharpParser.g4
Original file line number Diff line number Diff line change
Expand Up @@ -111,7 +111,10 @@ specializationParameter

type
: '_'
| '(' (type (',' type)* ','?)? ')'
| TypeParameter
| type '[' ']'
| type ('->' | '=>') type characteristics?
| 'BigInt'
| 'Bool'
| 'Double'
Expand All @@ -123,14 +126,6 @@ type
| 'String'
| 'Unit'
| qualifiedName
| '(' (type (',' type)* ','?)? ')'
| '(' arrowType characteristics? ')'
| type '[' ']'
;

arrowType
: '(' type ('->' | '=>') type ')'
| type ('->' | '=>') type
;

// Statement
Expand Down