Chapter 1. Program Structure

This chapter offers an overview of Q# program structure and the main elements that comprise it. This will help you orient yourself in the following chapters, in which we’ll dive deeper into writing Q# code.

Your first Q# program

Let’s take a look at a Q# program that prints a message to the console. While very simple, it shows the main elements of Q# code: a namespace, an open directive, an operation that contains the actual Q# statements, and comments.

Example 1-1. “Hello World” program in Q#
namespace HelloQuantumWorld {
    open Microsoft.Quantum.Intrinsic; // To use Message

    /// # Summary
    /// Prints a message to the console.
    @EntryPoint()
    operation SayHello() : Unit {
        Message("Hello quantum world!");
    }
}
Note

The code samples in Part I of this book are written as Q# standalone applications. You can follow the installation instructions to set up Microsoft Quantum Development Kit for your environment and run these samples. In Chapter 2 we’ll discuss different ways to run Q# programs and the nuances of writing Q# code for each of them.

Let’s take a closer look at the elements shown in this sample.

Namespaces

At the outermost level all Q# code is organized into namespaces. A namespace is a collection of uniquely named operations, functions (collectively referred to as callables), and user-defined types.

The namespace keyword defines a namespace for the Q# code within the following block:

namespace HelloQuantumWorld {
    // Operations, functions and user-defined
    // types within this block will belong to
    // the namespace HelloQuantumWorld.
}

The namespace name can contain letters, digits, underscores and dots.

Unlike .NET languages, Q# doesn’t have a hierarchy of nested namespaces defined by the dots in their names. Namespaces cannot be nested inside each other. Namespaces with names that contain each other can be related logically, but this relation will not be reflected on the code level.

For example, Q# libraries offer logically connected namespaces Microsoft.Quantum.MachineLearning and Microsoft.Quantum.MachineLearning.Datasets, but the operations defined in the latter are defined separately from the former.

All Q# code, except comments, must be included in a namespace. (Q# code snippets written in Jupyter Notebooks seem to be an exception from this rule, as they cannot be defined inside a namespace. However, internally Jupyter Notebooks paste the contents of Q# code cells into a temporary namespace before compiling them. We will discuss the nuances of writing Q# code in Jupyter Notebooks in more detail in Chapter 2.)

The code within a namespace can access any other code declared in the same namespace without extra qualification. To access a callable or a user-defined type declared in a different namespace, you have to use either its fully qualified name or an open directive.

A fully qualified name of a callable or a type is its namespace name, followed by a dot and its unqualified name.

// This uses the fully qualified operation name.
Microsoft.Quantum.Intrinsic.Message("Hello!");

An open directive imports all callables and types from that namespace and makes them available as if they were defined in the current namespace. Open directives must be the first element within the namespace.

// Open the namespace which defines Message.
open Microsoft.Quantum.Intrinsic;

// Use unqualified name of the operation.
Message("Hello!");

Open directives allow you to define namespace aliases, which you can use instead of full namespace names when qualifying callables or types from that namespace. This can be useful, for example, to disambiguate if operations with the same name are defined in two open namespaces. Defining an alias for a namespace doesn’t open it.

// Open the namespace which defines Message
// and give it an alias.
open Microsoft.Quantum.Intrinsic as Builtin;

// Use the alias with the operation name.
Builtin.Message("Hello!");

Operations and functions

The main element of namespaces that holds most of the Q# code in it is operations and functions - series of statements that perform certain actions. An operation declaration will use the keyword operation, followed by the operation name, the list of its input parameters and the type of its return.

operation SayHello() : Unit {
    Message("Hello quantum world!");
}

In this example we define an operation called SayHello which takes no parameters and has no return. The only thing it does is print the message to the console.

Functions are defined similarly, using the keyword function instead of operation.

Operations and functions are a fundamental concept in Q#, and there is a lot more to defining them than I mentioned here. We will discuss defining operations and functions in more detail in Chapter 5. Meanwhile, this summary should help you read the basic code samples in the following chapters.

Type declarations

Another namespace element is type declarations - declarations of user-defined types. User-defined types are tuples of named and anonymous items of other types (primitive or user-defined).

The newtype keyword declares a user-defined type.

// Declare type for pair.
newtype Pair = (First : Int, Second : Int);

We will discuss declaring user-defined types in more detail in Chapter 2.

Comments

Q# offers two types of comments - implementation comments (more often referred to as single-line comments) and documentation comments.

Implementation comments allow you to include notes on the Q# code in the code itself. They are intended for other developers working on the same code - your teammates or even your future self - and should offer additional context that might not be clear from the code itself: the design decisions made during code development, links to resources describing the techniques used, etc.

A single-line comment begins with two forward slashes (//) and ends at the end of the line:

// This is a single-line comment.
let a = 1;   // Can start mid-line.

Q# doesn’t currently support multiline (block) comments.

Documentation comments allow you to embed the external documentation for your Q# code into the code itself. Their audience is the users of your code, and should describe the purpose of the code, the meaning and the format of the input parameters, usage examples, and so forth.

A documentation comment begins with three forward slashes (///) and ends at the end of the line. Documentation comments appear in blocks preceding operations, functions or type declarations.

/// # Summary
/// Prints a message to the console.
operation SayHello() : Unit {
    Message("Hello quantum world!");
}

The Q# compiler parses documentation comments to provide quick info in IDEs that offer IntelliSense support for Q#, such as Visual Studio and Visual Studio Code. Figure 1-1 shows an example of the quick info window in VS Code.

Quick info window in Visual Studio Code
Figure 1-1. Quick info window in Visual Studio Code.

Additionally, Q# documentation generator uses documentation comments in Q# libraries’ source code to generate the API reference.

You can use use Markdown language in the documentation comments you write to enable formatting and cross-references in the generated API documentation, and LaTeX to support math formulas. Q# documentation page on comments provides more information on the structure of documentation comments.

Run your first Q# program!

Once you’ve installed Microsoft Quantum Development Kit for your preferred development environment, you can follow the instructions to run the “Hello World” program in it. You should see a console window with the text message in it:

Hello quantum world!

Conclusion

Congratulations, you’ve just ran your first Q# program!

Now that you’re familiar with the high-level structure of Q# programs and running them, you are ready to dive deeper into the Q# programming language. In the next chapter, you will learn about the data types offered by Q# and learn to create your own user-defined types.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
18.189.2.122