# Index from end and ranges

> C#'s index from the end (^n) and ranges (a..b) inside an indexer. ^1 is the last element of a string, an array or a list; a range slices a string into a substring and an array into a new array, end exclusive.

<!-- id: function-index-and-range · area: function · stability: stable · html: https://osysharp.com/reference/function/index-and-range/ -->

## Summary        {#summary}
`^n` is the position `n` elements before the end, so `xs[^1]` is the last element — on a string, an array and a
list. `a..b` is the range from `a` up to (not including) `b`; either end may be left out, and either may be written
from the end: `s[1..3]`, `s[2..]`, `arr[..2]`, `s[^3..]`. A string's range is a substring, an array's is a new array.

## Signature      {#signature}
```osy syntax
xs[^<int n>]                 // the element n before the end — xs[xs.Length - n] (Count on a list)
s[<start>..<end>]            // string → string, end exclusive; either bound may be ^n or omitted
arr[<start>..<end>]          // T[] → a new T[]
```

## Description    {#description}
- **The same answers as C#.** `^1` is the last element and `^0` is one past it (reading it faults, as in C#).
  `s[a..b]` is `s.Substring(a, b - a)` — an out-of-range bound faults the way `Substring` does.
- **Where they are read.** Inside an indexer. C# also lets `^1` and `1..3` be stored as `Index`/`Range` values;
  Osy# has no such value, so outside `[ ]` they are refused by name with the indexer to write instead.
- **A list takes `^n` but not a range** — as in C#, `List<T>` has no range indexer; copy a slice with
  `xs.GetRange(start, count)`.
- **The value is read once per use.** The indexed value and each bound must be something that can be read again —
  a variable, a field, a literal — because the lowering reads the length and then the element. Anything else (a call)
  is refused with the fix: bind it to a local first.
- **Precedence is C#'s:** `..` binds tighter than arithmetic, so a computed bound is parenthesised — `s[1..(n - 1)]`.

## Examples       {#examples}
```osy title="the last, a middle slice, the tail" test app=function-index-range
string Last(string s) => $"{s[^1]}";                        // "o" for "hello"
string Middle(string s) => s[1..^1];                        // "ell"
int[] Head(int[] xs) => xs[..2];                            // { 1, 2 } of { 1, 2, 3 }
int LastOf(List<int> xs) => xs[^1];
```

## See also       {#see-also}
- [List indexer](https://osysharp.com/reference/function/list-indexer/) — `list[i]`, read and write
- [Array literals](https://osysharp.com/reference/function/collection-literals/) — building the arrays and lists a range slices
