Skip to content

Commit

Permalink
docs: add section comments for devrel (FuelLabs#4531)
Browse files Browse the repository at this point in the history
Adds section comments to the documentation so that the devrel team can
easily pull content from this book. Also adds some missing links to the
Sway basics page.

For more context about how these comments work, see
[here](FuelLabs/fuels-ts#969 (comment)).
  • Loading branch information
sarahschwartz authored May 3, 2023
1 parent cb7651f commit 8a8e694
Show file tree
Hide file tree
Showing 24 changed files with 261 additions and 23 deletions.
13 changes: 12 additions & 1 deletion docs/book/src/basics/blockchain_types.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,10 @@ These are provided via the standard library ([`lib-std`](https://github.com/Fuel

## `Address` Type

<!-- This section should explain the `Address` type -->
<!-- address:example:start -->
The `Address` type is a type-safe wrapper around the primitive `b256` type. Unlike the EVM, an address **never** refers to a deployed smart contract (see the `ContractId` type below). An `Address` can be either the hash of a public key (effectively an [externally owned account](https://ethereum.org/en/whitepaper/#ethereum-accounts) if you're coming from the EVM) or the hash of a [predicate](../sway-program-types/predicates.md). Addresses own UTXOs.
<!-- address:example:end -->

An `Address` is implemented as follows.

Expand All @@ -26,7 +29,10 @@ let forty_two: b256 = my_address.into();

## `ContractId` Type

<!-- This section should explain the `ContractId` type -->
<!-- contract_id:example:start -->
The `ContractId` type is a type-safe wrapper around the primitive `b256` type. A contract's ID is a unique, deterministic identifier analogous to a contract's address in the EVM. Contracts cannot own UTXOs but can own assets.
<!-- contract_id:example:end -->

A `ContractId` is implemented as follows.

Expand All @@ -46,7 +52,10 @@ let forty_two: b256 = my_contract_id.into();

## `Identity` Type

<!-- This section should explain the `Identity` type -->
<!-- identity:example:start -->
The `Identity` type is an enum that allows for the handling of both `Address` and `ContractId` types. This is useful in cases where either type is accepted, e.g. receiving funds from an identified sender, but not caring if the sender is an address or a contract.
<!-- identity:example:end -->

An `Identity` is implemented as follows.

Expand All @@ -69,8 +78,10 @@ A `match` statement can be used to return to an `Address` or `ContractId` as wel
```sway
{{#include ../../../../examples/identity/src/main.sw:different_executions}}
```

<!-- This section should explain the use case for the `Identity` type -->
<!-- use_identity:example:start -->
A common use case for `Identity` is for access control. The use of `Identity` uniquely allows both `ContractId` and `Address` to have access control inclusively.
<!-- use_identity:example:end -->

```sway
{{#include ../../../../examples/identity/src/main.sw:access_control_with_identity}}
Expand Down
43 changes: 39 additions & 4 deletions docs/book/src/basics/built_in_types.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,15 @@

Every value in Sway is of a certain type. Although deep down, all values are just ones and zeroes in the underlying virtual machine, Sway needs to know what those ones and zeroes actually mean. This is accomplished with _types_.

<!-- This section should explain how Sway types are inferred -->
<!-- sway_types:example:start -->
Sway is a statically typed language. At compile time, the types of every value must be known. This does not mean you need to specify every single type: usually, the type can be reasonably inferred by the compiler.
<!-- sway_types:example:end -->

## Primitive Types

<!-- This section should list the primitive types in Sway -->
<!-- prim_types:example:start -->
Sway has the following primitive types:

1. `u8` (8-bit unsigned integer)
Expand All @@ -17,6 +22,7 @@ Sway has the following primitive types:
1. `b256` (256 bits (32 bytes), i.e. a hash)

All other types in Sway are built up of these primitive types, or references to these primitive types. You may notice that there are no signed integers&mdash;this is by design. In the blockchain domain that Sway occupies, floating-point values and negative numbers have smaller utility, so their implementation has been left up to libraries for specific use cases.
<!-- prim_types:example:end -->

## Numeric Types

Expand All @@ -33,11 +39,19 @@ Numbers can be declared with binary syntax, hexadecimal syntax, base-10 syntax,
0xfff_aaa // underscore delineated hexadecimal
```

<!-- This section should explain the default numeric type in Sway -->
<!-- default_num:example:start -->
The default numeric type is `u64`. The FuelVM's word size is 64 bits, and the cases where using a smaller numeric type saves space are minimal.
<!-- default_num:example:end -->

## Boolean Type

The boolean type (`bool`) has two potential values: `true` or `false`. Boolean values are typically used for conditional logic or validation, for example in `if` expressions. Booleans can be negated, or flipped, with the unary negation operator `!`. For example:
<!-- This section should explain the `bool` type -->
<!-- bool:example:start -->
The boolean type (`bool`) has two potential values: `true` or `false`. Boolean values are typically used for conditional logic or validation, for example in `if` expressions. Booleans can be negated, or flipped, with the unary negation operator `!`.
<!-- bool:example:end -->

For example:

```sway
fn returns_false() -> bool {
Expand All @@ -48,7 +62,12 @@ fn returns_false() -> bool {

## String Type

In Sway, static-length strings are a primitive type. This means that when you declare a string, its size is a part of its type. This is necessary for the compiler to know how much memory to give for the storage of that data. The size of the string is denoted with square brackets. Let's take a look:
<!-- This section should explain the string type in Sway -->
<!-- str:example:start -->
In Sway, static-length strings are a primitive type. This means that when you declare a string, its size is a part of its type. This is necessary for the compiler to know how much memory to give for the storage of that data. The size of the string is denoted with square brackets.
<!-- str:example:end -->

Let's take a look:

```sway
let my_string: str[4] = "fuel";
Expand All @@ -62,7 +81,12 @@ _Compound types_ are types that group multiple values into one type. In Sway, we

## Tuple Types

A tuple is a general-purpose static-length aggregation of types. In more plain terms, a tuple is a single type that consists of an aggregate of zero or more types. The internal types that make up a tuple, and the tuple's arity, define the tuple's type. Let's take a look at some examples.
<!-- This section should explain what a tuple is -->
<!-- tuple:example:start -->
A tuple is a general-purpose static-length aggregation of types. In more plain terms, a tuple is a single type that consists of an aggregate of zero or more types. The internal types that make up a tuple, and the tuple's arity, define the tuple's type.
<!-- tuple:example:end -->

Let's take a look at some examples.

```sway
let x: (u64, u64) = (0, 0);
Expand All @@ -75,7 +99,12 @@ let x: (u64, bool) = (42, true);
assert(x.1);
```

In this example, we have created a new tuple type, `(u64, bool)`, which is a composite of a `u64` and a `bool`. To access a value within a tuple, we use _tuple indexing_: `x.1` stands for the first (zero-indexed, so the `bool`) value of the tuple. Likewise, `x.0` would be the zeroth, `u64` value of the tuple. Tuple values can also be accessed via destructuring:
In this example, we have created a new tuple type, `(u64, bool)`, which is a composite of a `u64` and a `bool`.

<!-- This section should explain how to access a value in a tuple -->
<!-- tuple_val:example:start -->
To access a value within a tuple, we use _tuple indexing_: `x.1` stands for the first (zero-indexed, so the `bool`) value of the tuple. Likewise, `x.0` would be the zeroth, `u64` value of the tuple. Tuple values can also be accessed via destructuring.
<!-- tuple_val:example:end -->

```sway
struct Foo {}
Expand All @@ -94,17 +123,23 @@ let w: (u64) = (42,); // type error

## Arrays

<!-- This section should explain what an array is -->
<!-- array:example:start -->
An array is similar to a tuple, but an array's values must all be of the same type. Arrays can hold arbitrary types including non-primitive types.
<!-- array:example:end -->

An array is written as a comma-separated list inside square brackets:

```sway
let x = [1, 2, 3, 4, 5];
```

<!-- This section should explain arrays in depth -->
<!-- array_details:example:start -->
Arrays are allocated on the stack since their size is known. An array's size is _always_ static, i.e. it cannot change. An array of five elements cannot become an array of six elements.

Arrays can be iterated over, unlike tuples. An array's type is written as the type the array contains followed by the number of elements, semicolon-separated and within square brackets, e.g. `[u64; 5]`. To access an element in an array, use the _array indexing syntax_, i.e. square brackets.
<!-- array_details:example:end -->

Array elements can also be mutated if the underlying array is declared as mutable:

Expand Down
20 changes: 18 additions & 2 deletions docs/book/src/basics/comments_and_logging.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,10 @@

## Comments

<!-- This section should explain how to add comments in Sway -->
<!-- comments:example:start -->
Comments in Sway start with two slashes and continue until the end of the line. For comments that extend beyond a single line, you'll need to include `//` on each line.
<!-- comments:example:end -->

```sway
// hello world
Expand Down Expand Up @@ -35,7 +38,10 @@ fn main() {

## Logging

<!-- This section should explain logging in Sway -->
<!-- logging:example:start -->
The `logging` library provides a generic `log` function that can be imported using `use std::logging::log` and used to log variables of any type. Each call to `log` appends a `receipt` to the list of receipts. There are two types of receipts that a `log` can generate: `Log` and `LogData`.
<!-- logging:example:end -->

```sway
fn log_values(){
Expand All @@ -50,7 +56,12 @@ fn log_values(){

### `Log` Receipt

The `Log` receipt is generated for _non-reference_ types, namely `bool`, `u8`, `u16`, `u32`, and `u64`. For example, logging an integer variable `x` that holds the value `42` using `log(x)` may generate the following receipt:
<!-- This section should explain when `Log` receipts are produced -->
<!-- log_rec:example:start -->
The `Log` receipt is generated for _non-reference_ types, namely `bool`, `u8`, `u16`, `u32`, and `u64`.
<!-- log_rec:example:end -->

For example, logging an integer variable `x` that holds the value `42` using `log(x)` may generate the following receipt:

```console
"Log": {
Expand All @@ -68,7 +79,12 @@ Note that `ra` will include the value being logged. The additional registers `rc

### `LogData` Receipt

`LogData` is generated for _reference_ types which include all types except for the _non_reference_ types mentioned above. For example, logging a `b256` variable `b` that holds the value `0x1111111111111111111111111111111111111111111111111111111111111111` using `log(b)` may generate the following receipt:
<!-- This section should explain when `LogData` receipts are produced -->
<!-- log_data_rec:example:start -->
`LogData` is generated for _reference_ types which include all types except for _non_reference_ types.
<!-- log_data_rec:example:end -->

For example, logging a `b256` variable `b` that holds the value `0x1111111111111111111111111111111111111111111111111111111111111111` using `log(b)` may generate the following receipt:

```console
"LogData": {
Expand Down
16 changes: 15 additions & 1 deletion docs/book/src/basics/commonly_used_library_types.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,32 +4,46 @@ The Sway Standard Library is the foundation of portable Sway software, a set of

## `Result<T, E>`

<!-- This section should explain what the `Result` type is -->
<!-- result:example:start -->
Type `Result` is the type used for returning and propagating errors. It is an `enum` with two variants: `Ok(T)`, representing success and containing a value, and `Err(E)`, representing error and containing an error value. The `T` and `E` in this definition are type parameters, allowing `Result` to be generic and to be used with any types.
<!-- result:example:end -->

```sway
{{#include ../../../../sway-lib-std/src/result.sw:docs_result}}
```

Functions return `Result` whenever errors are expected and recoverable. Take the following example:
<!-- This section should explain when to use the `Result` type -->
<!-- use_result:example:start -->
Functions return `Result` whenever errors are expected and recoverable.
<!-- use_result:example:end -->

Take the following example:

```sway
{{#include ../../../../examples/result/src/main.sw}}
```

## `Option<T>`

<!-- This section should explain the `Option` type -->
<!-- option:example:start -->
Type `Option` represents an optional value: every `Option` is either `Some` and contains a value, or `None`, and does not. `Option` types are very common in Sway code, as they have a number of uses:

- Initial values where `None` can be used as an initializer.
- Return value for otherwise reporting simple errors, where `None` is returned on error.

The implementation of `Option` matches on the variant: if it's `Ok` it returns the inner value, if it's `None`, it [reverts](https://github.com/FuelLabs/fuel-specs/blob/master/src/vm/instruction_set.md#rvrt-revert).
<!-- option:example:end -->

```sway
{{#include ../../../../sway-lib-std/src/option.sw:docs_option}}
```

<!-- This section should explain when to use the `Option` type -->
<!-- use_option:example:start -->
`Option` is commonly paired with pattern matching to query the presence of a value and take action, allowing developers to choose how to handle the `None` case.
<!-- use_option:example:end -->

Below is an example that uses pattern matching to handle invalid divisions by 0 by returning an `Option`:

Expand Down
9 changes: 9 additions & 0 deletions docs/book/src/basics/constants.md
Original file line number Diff line number Diff line change
@@ -1,23 +1,29 @@
# Constants

<!-- This section should explain what constants are in Sway -->
<!-- constants:example:start -->
Constants are similar to variables; however, there are a few differences:

- Constants are always evaluated at compile-time
- Constants can be declared both inside of a [function](../index.md) and at global / `impl` scope.
- The `mut` keyword cannot be used with constants.
<!-- constants:example:end -->

```sway
const ID: u32 = 0;
```

## Associated Constants

<!-- This section should explain what associated constants are -->
<!-- assoc_constants:example:start -->
Associated constants are constants associated with a type and can be declared in an `impl` block or in a `trait` definition.

Associated constants declared inside a `trait` definition may omit their initializers to indicate that each implementation of the trait must specify those initializers.

The identifier is the name of the constant used in the path. The type is the type that the
definition has to implement.
<!-- assoc_constants:example:end -->

You can _define_ an associated const directly in the interface surface of a trait:

Expand Down Expand Up @@ -73,7 +79,10 @@ fn main() -> u64 {

## Configurable Constants

<!-- This section should explain what configurable constants are in Sway -->
<!-- config_constants:example:start -->
Configurable constants are special constants that behave like regular constants in the sense that they cannot change during program execution, but they can be configured _after_ the Sway program has been built. The Rust and TS SDKs allow updating the values of these constants by injecting new values for them directly in the bytecode without having to build the program again. These are useful for contract factories and behave somewhat similarly to `immutable` variables from languages like Solidity.
<!-- config_constants:example:end -->

Configurable constants are declared inside a `configurable` block and require a type ascription and an initializer as follows:

Expand Down
6 changes: 6 additions & 0 deletions docs/book/src/basics/control_flow.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,10 @@

## `if` expressions

<!-- This section should explain `if` expressions in Sway -->
<!-- if:example:start -->
Sway supports _if_, _else_, and _else if_ expressions that allow you to branch your code depending on conditions.
<!-- if:example:end -->

For example:

Expand Down Expand Up @@ -32,7 +35,10 @@ Note that all branches of the `if` expression must return a value of the same ty

### `match` expressions

<!-- This section should explain `match` expressions in Sway -->
<!-- match:example:start -->
Sway supports advanced pattern matching through exhaustive `match` expressions. Unlike an `if` statement, a `match` expression asserts **at compile** time that all possible patterns have been matched. If you don't handle all the patterns, you will get compiler error indicating that your `match` expression is non-exhaustive.
<!-- match:example:end -->

The basic syntax of a `match` statement is as follows:

Expand Down
7 changes: 6 additions & 1 deletion docs/book/src/basics/functions.md
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,12 @@ fn main() {

## Mutable Parameters

We can make a function parameter mutable by adding `ref mut` before the parameter name. This allows mutating the argument passed into the function when the function is called. For example:
<!-- This section should explain how/when to use `ref mut` -->
<!-- ref_mut:example:start -->
We can make a function parameter mutable by adding `ref mut` before the parameter name. This allows mutating the argument passed into the function when the function is called.
<!-- ref_mut:example:end -->

For example:

```sway
{{#include ../../../../examples/ref_mut_params/src/main.sw:increment}}
Expand Down
6 changes: 4 additions & 2 deletions docs/book/src/basics/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,15 @@

Sway is a programming language designed for the FuelVM. It is a statically typed, compiled language with type inference and traits. Sway aims to make smart contract development safer and more performant through the use of strong static analysis and compiler feedback.

Sway basics.
Get started with the basics of Sway:

- [Variables](./variables.md)
- [Built-in Types](./built_in_types.md)
- [Commonly Used Library Types](./commonly_used_library_types.md)
- [Blockchain Types](./blockchain_types.md)
- [Functions](./functions.md)
- [Structs, Tuples, and Enums](./structs_tuples_and_enums.md)
- [Methods and Associated Functions](./methods_and_associated_functions.md)
- [Control Flow](./control_flow.mdz)
- [Constants](./constants.md)
- [Comments and Logging](./comments_and_logging.md)
- [Control Flow](./control_flow.mdz)
13 changes: 12 additions & 1 deletion docs/book/src/basics/methods_and_associated_functions.md
Original file line number Diff line number Diff line change
@@ -1,18 +1,29 @@
# Methods and Associated Functions

<!-- This section should explain methods & associated functions in Sway -->
<!-- methods_af:example:start -->
Methods are similar to functions in that we declare them with the `fn` keyword and they have parameters and return a value. However, unlike functions, _Methods_ are defined within the context of a struct (or enum), and either refers to that type or mutates it. The first parameter of a method is always `self`, which represents the instance of the struct the method is being called on.

_Associated functions_ are very similar to _methods_, in that they are also defined in the context of a struct or enum, but they do not actually use any of the data in the struct and as a result do not take _self_ as a parameter. Associated functions could be standalone functions, but they are included in a specific type for organizational or semantic reasons.

To declare methods and associated functions for a struct or enum, use an _impl block_. Here, `impl` stands for implementation.
<!-- methods_af:example:end -->

```sway
{{#include ../../../../examples/methods_and_associated_functions/src/main.sw}}
```

<!-- This section should explain how to call a method -->
<!-- call_method:example:start -->
To call a method, simply use dot syntax: `foo.iz_baz_true()`.
<!-- call_method:example:end -->

Similarly to [free functions](functions.md), methods and associated functions may accept `ref mut` parameters. For example:
<!-- This section should explain how methods + assoc. fns can accept `ref mut` params -->
<!-- ref_mut:example:start -->
Similarly to [free functions](functions.md), methods and associated functions may accept `ref mut` parameters.
<!-- ref_mut:example:end -->

For example:

```sway
{{#include ../../../../examples/ref_mut_params/src/main.sw:move_right}}
Expand Down
Loading

0 comments on commit 8a8e694

Please sign in to comment.