# Add `unicodeScalars` property to `Character`

* Proposal: [SE-NNNN](NNNN-character-unicode-view.md)
* Authors: [Ben Cohen](https://github.com/airspeedswift)
* Review Manager: TBD
* Status: **Awaiting review**

## Introduction

This proposal adds a `unicodeScalar` view to `Character`, similar to that on `String`.

## Motivation

The `Character` element type of `String` is currently a black box that provides
little functionality besides comparison, literal construction, and to be used
as an argument to `String.init`.

Many operations on `String` could be neatly/readbily implemented as operations
on each character in the string, if `Character` exposed its scalars more
directly. Many useful things can be determined by examining the scalars in a
grapheme (for example is this an ASCII character?).

For example, today you can write this:

```swift
let s = "one two three"
s.split(separator: " ")
```

But you cannot write this:

```swift
let ws = CharacterSet.whitespacesAndNewlines
s.split { $0.unicodeScalars.contains(where: ws.contains) }
```

## Proposed solution

Add a `unicodeScalars` property to `Character`, presending a lazy view of the
scalars in the character, along similar lines to the one on `String`.

Unlike the view on `String`, this will _not_ be a mutable view – it will be
read-only. The preferred method for creating and manipulating non-literal
`Character` values will be through `String`. While there may be some good
use cases to manipulating a `Character` directly, these are outweighed by the 
complexity of ensuring the invariant that it contain exactly one grapheme.

## Detailed design

Add the following nested type to `Character`:

```swift
extension Character {
  public struct UnicodeScalarView : BidirectionalCollection {
    public struct Index
    public var startIndex: Index
    public var endIndex: Index
    public func index(after i: Index) -> Index
    public func index(before i: Index)
    public subscript(i: Index) -> UnicodeScalar
  }
}
```

Additionally, this type will conform to appropriate convenience protocols such 
as `CustomStringConvertible`.

All initializers will be declared internal, as unlike the `String` equivalent,
this type will only ever be vended by `Character`.

## Source compatibility

Purely additive, so no impact.

## Effect on ABI stability

Purely additive, so no impact.

## Effect on API resilience

Purely additive, so no impact.

## Alternatives considered

Adding other views, such as `utf8` or `utf16`, was considered but not deemed useful
enough compared to using these operations on `String` instead.

In future, this feature could be used to implement convenience methods such as
`isASCII` on `Character`. This could be done additively, given this building block,
and is outside the scope of this initial proposal.

Add draft of Characters.unicodeScalars proposal
Add draft of Characters.unicodeScalars proposal
