Skip to content

Commit

Permalink
Merge pull request #39 from onflow/sainati/inclusive-range-docs
Browse files Browse the repository at this point in the history
Create documentation for InclusiveRange
  • Loading branch information
dsainati1 committed Jan 16, 2024
2 parents 513b5f0 + 535394d commit d21d4c0
Show file tree
Hide file tree
Showing 2 changed files with 188 additions and 0 deletions.
59 changes: 59 additions & 0 deletions versioned_docs/version-1.0/language/control-flow.md
Original file line number Diff line number Diff line change
Expand Up @@ -358,6 +358,65 @@ dictionary.forEachKey(fun (key: String): Bool {
})
```

### Ranges in Loops

An [`InclusiveRange` value](#../values-and-types/InclusiveRange) can be used in a for-in statement in place of an array or dictionary. In this case,
the loop will iterate over all the values contained in the range, beginning with `range.start` and ending with `range.end`. E.g.

```cadence
let range: InclusiveRange<UInt> = InclusiveRange(1, 100, step: 2)
var elements : [UInt] = []
for element in range {
elements.append(element)
}
// after this loop, `elements` contains all the odd integers from 1 to 99
```

Note that in this example, even though `100` is the end of the `range`, it is not included in the loop because it cannot be reached with the given `start` and `step`.

The above loop is equivalent to:

```cadence
let range: InclusiveRange<UInt> = InclusiveRange(1, 100, step: 2)
var elements : [UInt] = []
var index = range.start
while index <= range.end {
elements.append(element)
index = index + range.step
}
// after this loop, `elements` contains all the odd integers from 1 to 99
```

In general, a for-in loop over an increasing range (a positive `step`) is equivalent to:

```cadence
var index = range.start
while index <= range.end {
// loop body
index = index + range.step
}
```

While a for-in loop over a decreasing range (a negative `step`) is equivalent to:

```cadence
var index = range.start
while index >= range.end {
// loop body
index = index + range.step // `range.step` here is negative, so this decreases `index`
}
```

Both can be equivalently rewritten to:

```cadence
var index = range.start
while range.contains(index) {
// loop body
index = index + range.step
}
```

### `continue` and `break`

In for-loops and while-loops, the `continue` statement can be used to stop
Expand Down
129 changes: 129 additions & 0 deletions versioned_docs/version-1.0/language/values-and-types.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -1916,3 +1916,132 @@ Dictionary keys must be hashable and equatable.

Most of the built-in types, like booleans and integers,
are hashable and equatable, so can be used as keys in dictionaries.

## InclusiveRange

An `InclusiveRange<T: Integer>` value represents a range of numerical values between two integers,
with the start and end numbers included in the range as suggested by the name.

A range value has a `start`, `end` and a `step`, which represents the interval at which the range's values are separated from `start` to `end`.

A range can be created using the `InclusiveRange` constructor, which can take two or three arguments.

In the case where the range is constructed with two arguments, the first argument is the `start` and the second is the `end`.
The `step` is inferred to be either `1` (when `end >= start`) or `-1` (when `end < start`). E.g.

```cadence
// start is 1, end is 100, step is 1
let range: InclusiveRange<UInt> = InclusiveRange(1, 100)
```

Optionally a third, labeled, non-zero `step` argument can be provided to specify a step other than `1`. E.g., the following range contains
all odd numbers from 1 to 100:

```cadence
// start is 1, end is 100, step is 2
let range: InclusiveRange<UInt> = InclusiveRange(1, 100, step: 2)
```

Note that in this example, even though the specified "end" of the range is 100, the last actual value the range can attain is 99.

If the specified `step` argument would progress the range away from the `end`, the creation will fail. E.g.

```cadence
// Throws an error because a step of -2 cannot progress from 1 to 100
let range: InclusiveRange<Int> = InclusiveRange(1, 100, step: -2)
```

A range requires a type annotation when created.

### `InclusiveRange<T>` fields and functions

A value of type `InclusiveRange<T>`, where `T` is a number type, has the following fields and functions:

-
```cadence
let start: T
```

The start of the range.

```cadence
// Declare a range of `Int`s
let range = let r: InclusiveRange<Int> = InclusiveRange(3, 9)
// Get the start of the range
let start = range.start
// `start` is `3`
```

-
```cadence
let end: T
```

The end of the range.

```cadence
// Declare a range of `Int`s
let range: InclusiveRange<Int> = InclusiveRange(3, 9)
// Get the end of the range
let end = range.end
// `end` is `9`
```

-
```cadence
let step: T
```

The step of the range.

```cadence
// Declare a range of `Int`s with a `step` of 2
let rangeWithStep: InclusiveRange<Int> = InclusiveRange(3, 9, step: 2)
// Get the step of the range
var step = range.step
// `step` is `2`
// Declare a range of `Int`s without an explicit `step`
let rangeWithStep: InclusiveRange<Int> = InclusiveRange(3, 9)
/ Get the step of the range
step = rangeWithStep.step
// `step` is implicitly `1`
```

-
```cadence
access(all)
view fun contains(_ element: T): Bool
```

Returns `true` if the given integer is in the `InclusiveRange` sequence, and `false` otherwise.

Specifically, for some `InclusiveRange` `r` defined with `start`, `step` and `end`, `r.contains(x)` returns true if either:
* `start <= end` and there exists some integer `i >= 0` such that `start + i * step = x` and `x <= end`
* `start > end` and there exists some integer `i >= 0` such that `start - i * step = x` and `x >= end`

```cadence
// Declare a range of `Int`s with a `step` of 2
let rangeWithStep: InclusiveRange<Int> = InclusiveRange(3, 9, step: 2)
// `contains` is `true`
var contains = range.contains(5)
// `contains` is `true`
var contains = range.contains(9)
// `contains` is `false`
contains = range.contains(6)
// `contains` is `false`
contains = range.contains(11)
```

0 comments on commit d21d4c0

Please sign in to comment.