# SE-0221 – Character Properties

**URL:** <https://forums.swift.org/t/se-0221-character-properties/14686>\
**Category:** Proposal Reviews\
**Created:** [July 23, 2018, 5:22pm UTC](https://forums.swift.org/t/se-0221-character-properties/14686 "2018-07-23T17:22:30Z")\
**Posts on this page:** 20\
**Page:** 1

<div class="post-metadata">

**Author:** ![ben-cohen](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/ben-cohen/32/296_2.png) [@ben-cohen](https://forums.swift.org/u/ben-cohen)\
**Post date:** [July 23, 2018, 5:22pm UTC](https://forums.swift.org/t/se-0221-character-properties/14686/1 "2018-07-23T17:22:31Z")

</div>

The review of [SE-0221 — Character Properties](https://github.com/apple/swift-evolution/blob/master/proposals/0221-character-properties.md) begins now and runs through July 29, 2018.

Reviews are an important part of the Swift evolution process. All review feedback should be either on this forum thread or, if you would like to keep your feedback private, directly to the review manager (via [email](mailto:ben_cohen@apple.com) or direct message in the Swift forums).

## What goes into a review of a proposal?

The goal of the review process is to improve the proposal under review through constructive criticism and, eventually, determine the direction of Swift.

When reviewing a proposal, here are some questions to consider:

- What is your evaluation of the proposal?

- Is the problem being addressed significant enough to warrant a change to Swift?

- Does this proposal fit well with the feel and direction of Swift?

- If you have used other languages or libraries with a similar feature, how do you feel that this proposal compares to those?

- How much effort did you put into your review? A glance, a quick reading, or an in-depth study?

Thanks,  
Ben Cohen  
Review Manager

---

<div class="post-metadata">

**Author:** ![masters3d](https://avatars.discourse-cdn.com/v4/letter/m/c4cdca/32.png) [@masters3d](https://forums.swift.org/u/masters3d)\
**Post date:** [July 23, 2018, 6:10pm UTC](https://forums.swift.org/t/se-0221-character-properties/14686/2 "2018-07-23T18:10:57Z")

</div>

- What is your evaluation of the proposal?

I am for the proposal but I really dislike all the properties being added. I would much rather the notion of versioned sets of Unicode classification. As in, I want to know if a character is an emoji in 2012 version of Unicode. If I always want swift to pick the latest version of Unicode then pick current.

Unicode.current.emojiSet.contains(myChar)

Unicode.version(someOlderVersion).emojiSet.contains(myNewChar)

I think it would be surprising if Unicode changes in the future make it hard to change all the Character properties. I much rather see this functionality outside of the Character type.

With the current design, I will that one version of swift would resolve some properties as true while a new version could update them as false. Could that happen?

- Is the problem being addressed significant enough to warrant a change to Swift?

Yes

- Does this proposal fit well with the feel and direction of Swift?

Yes

- If you have used other languages or libraries with a similar feature, how do you feel that this proposal compares to those?

No

- How much effort did you put into your review? A glance, a quick reading, or an in-depth study?

Read the proposal.

---

<div class="post-metadata">

**Author:** ![Michael\_Ilseman](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/michael_ilseman/32/44640_2.png) [@Michael\_Ilseman](https://forums.swift.org/u/Michael_Ilseman)\
**Post date:** [July 23, 2018, 6:24pm UTC](https://forums.swift.org/t/se-0221-character-properties/14686/3 "2018-07-23T18:24:42Z")

</div>

> [@masters3d](#):
>
> - I am for the proposal but I really dislike all the properties being added. I would much rather the notion of versioned sets of Unicode classification. As in, I want to know if a character is an emoji in 2012 version of Unicode. If I always want swift to pick the latest version of Unicode then pick current.
> 
> Unicode.current.emojiSet.contains(myChar)
> 
> Unicode.version(someOlderVersion).emojiSet.contains(myNewChar)
> 
> I think it would be surprising if Unicode changes in the future make it hard to change all the book properties. I much rather see this functionality outside of the Char type.
> 
> With the current design, I will that one version of swift would resolve some properties as true while a new version could update them as false. Could that happen?

I feel like there’s two separable aspects you brought up here:

One is a request is to continue adding APIs for Unicode-savvy users, ala Unicode Scalar Properties and the recently pitched [String case folding and normalization APIs](https://forums.swift.org/t/string-case-folding-and-normalization-apis/14663). Specifically, the ability to request version-specific information.

It sounds like you want something akin to versioned Unicode Scalar Properties, but I feel it would be out of place for the standard library proper as currently designed. It would require shipping all versions of Unicode data files, reconciling availability (so all properties might end up being optional), etc. I think it would make a very interesting SPM package today, and in the future could have a place in a form of “extended” libraries or package catalogue for Unicode experts/enthusiasts.

The other is a concern about the stability of answers to this query. Many String APIs suffer from this, including `String.count` and `String.lowercased()`, which varies version-to-version of Unicode. Do you see something particularly troubling for Character Properties that doesn’t already apply to String?

---

<div class="post-metadata">

**Author:** ![masters3d](https://avatars.discourse-cdn.com/v4/letter/m/c4cdca/32.png) [@masters3d](https://forums.swift.org/u/masters3d)\
**Post date:** [July 23, 2018, 6:46pm UTC](https://forums.swift.org/t/se-0221-character-properties/14686/4 "2018-07-23T18:46:55Z")

</div>

> [@Michael\_Ilseman](#):
>
> Do you see something particularly troubling for Character Properties that doesn’t already apply to String?

yes. .isWhitespace comes mind. All of the sudden all character properties are a breaking change if a character is classified as non whitespace anymore. Maybe in that case they should all be methods and not properties.

---

<div class="post-metadata">

**Author:** ![xwu](https://avatars.discourse-cdn.com/v4/letter/x/b487fb/32.png) [@xwu](https://forums.swift.org/u/xwu)\
**Post date:** [July 23, 2018, 6:51pm UTC](https://forums.swift.org/t/se-0221-character-properties/14686/5 "2018-07-23T18:51:51Z")

</div>

> [@masters3d](#):
>
> yes. .isWhitespace comes mind. All of the sudden all character properties are a breaking change if a character is classified as non whitespace anymore. Maybe in that case they should all be methods and not properties.

Unicode provides stability guarantees around whitespace, if I'm not mistaken. Swift could (and probably should) explicitly provide the same guarantees: i.e., no whitespace character will ever be classified as not a whitespace character in a future version of Swift. The same goes for newlines.

---

<div class="post-metadata">

**Author:** ![jawbroken](https://avatars.discourse-cdn.com/v4/letter/j/cc9497/32.png) [@jawbroken](https://forums.swift.org/u/jawbroken)\
**Post date:** [July 24, 2018, 1:31am UTC](https://forums.swift.org/t/se-0221-character-properties/14686/6 "2018-07-24T01:31:27Z")

</div>

Small documentation error, I think you need to swap lowercase and uppercase at the end:

```swift
  /// Lowercase Characters vary under case-conversion to lowercase, but not when
  /// converted to uppercase.

```

If I recall correctly, your opinion here:

> We recommend that the precise semantics of `isWhitespace` and `isNewline` be unspecified regarding graphemes consisting of leading whitespace/newlines followed by combining scalars.

has changed since the earlier threat discussing this issue. I think leaving this unspecified is fine, since it's unlikely to be an issue in practice, and it fits with some of the other `String` edge cases (e.g. `Collection` conformance).

There is a “lessor”/“lesser” typo somewhere.

Generally I think this is a nice pragmatic proposal, and I think it does a great job of presenting the complexity of the space and the reasoning behind the choices made. I don't think it's worthwhile handling the Unicode versioning issues at this level, because the problems there are more general (e.g. `String` character counts have already changed with Swift versions).

---

<div class="post-metadata">

**Author:** ![KeithTsui](https://avatars.discourse-cdn.com/v4/letter/k/a87d85/32.png) [@KeithTsui](https://forums.swift.org/u/KeithTsui)\
**Post date:** [July 24, 2018, 11:46am UTC](https://forums.swift.org/t/se-0221-character-properties/14686/7 "2018-07-24T11:46:25Z")

</div>

What is your evaluation of the proposal?  
I think adding those properties to Character looks too verbose for Swift Standard Library.  
Moreover, those properties look related to put a character into different character set. Therefore, why not enrich CharacterSet to achieve the same functionalities.

Is the problem being addressed significant enough to warrant a change to Swift?  
No.

Does this proposal fit well with the feel and direction of Swift?  
Yes, but not necessarily be implemented in Standard Library.

If you have used other languages or libraries with a similar feature, how do you feel that this proposal compares to those?  
I think it would be handy to use, but I prefer to use CharacterSet to classify Character instead with Character itself.

How much effort did you put into your review? A glance, a quick reading, or an in-depth study?  
Quick reading.

---

<div class="post-metadata">

**Author:** ![pvieito](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/pvieito/32/33613_2.png) [@pvieito](https://forums.swift.org/u/pvieito)\
**Post date:** [July 24, 2018, 8:00pm UTC](https://forums.swift.org/t/se-0221-character-properties/14686/8 "2018-07-24T20:00:55Z")

</div>

**What is your evaluation of the proposal?**

- +1 to the added properties to `Character`.
- Strong opposition to renaming `FixedWidthInteger.init?<S: StringProtocol>(S, radix: Int = 10)` to `FixedWidthInteger.init?<S: StringProtocol>(ascii: S, radix: Int = 10)`.

**Is the problem being addressed significant enough to warrant a change to Swift?**

- The added Character properties seem really useful.
- The renaming change is superfluous.

**Does this proposal fit well with the feel and direction of Swift?**

- Yes for the Character properties.
- No for the renaming change. I think changing something as common, simple and extended as `Int(31)` to `Int(ascii: 31)` is not a _Swifty_ change.

**If you have used other languages or libraries with a similar feature, how do you feel that this proposal compares to those?**

- No.
- Casting a string to an integer is something very common, and all popular language use syntax very similar to the current `Int(31)` initializer.

**How much effort did you put into your review? A glance, a quick reading, or an in-depth study?**

Reading the review.

---

<div class="post-metadata">

**Author:** ![Karl](https://avatars.discourse-cdn.com/v4/letter/k/34f0e0/32.png) [@Karl](https://forums.swift.org/u/Karl)\
**Post date:** [July 25, 2018, 4:37pm UTC](https://forums.swift.org/t/se-0221-character-properties/14686/9 "2018-07-25T16:37:41Z")

</div>

> [@pvieito](#):
>
> No for the renaming change. I think changing something as common, simple and extended as `Int(31)` to `Int(ascii: 31)` is not a _Swifty_ change.

The thing about this is that Swift allows full-unicode type and variable names. Maybe your code is all in Chinese, and maybe you'd expect something like `Int("三")` to work as well as `Int("3")`, especially since other String operations are unicode-aware by default.

EDIT: That said, the Swift compiler itself doesn't recognise non-ASCII integer literals. `let _ = 三` doesn't compile. So maybe there is no such expectation.

---

<div class="post-metadata">

**Author:** ![xwu](https://avatars.discourse-cdn.com/v4/letter/x/b487fb/32.png) [@xwu](https://forums.swift.org/u/xwu)\
**Post date:** [July 26, 2018, 2:47am UTC](https://forums.swift.org/t/se-0221-character-properties/14686/10 "2018-07-26T02:47:39Z")

</div>

> [@pvieito](#):
>
> **What is your evaluation of the proposal?**
> 
> - +1 to the added properties to `Character` .
> - Strong opposition to renaming `FixedWidthInteger.init?<S: StringProtocol>(S, radix: Int = 10)` to `FixedWidthInteger.init?<S: StringProtocol>(ascii: S, radix: Int = 10)` .
> 
> **Is the problem being addressed significant enough to warrant a change to Swift?**
> 
> - The added Character properties seem really useful.
> - The renaming change is superfluous.
> 
> **Does this proposal fit well with the feel and direction of Swift?**
> 
> - Yes for the Character properties.
> - No for the renaming change. I think changing something as common, simple and extended as `Int(31)` to `Int(ascii: 31)` is not a _Swifty_ change.

No such change is proposed. `Int` will continue to conform to `LosslessStringConvertible`, which requires `init?(String)`.

---

<div class="post-metadata">

**Author:** ![griotspeak](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/griotspeak/32/1966_2.png) [@griotspeak](https://forums.swift.org/u/griotspeak)\
**Post date:** [July 26, 2018, 5:47am UTC](https://forums.swift.org/t/se-0221-character-properties/14686/11 "2018-07-26T05:47:42Z")

</div>

+1

I've followed the conversation and provided some feedback. I've given the proposal a quick read.

---

<div class="post-metadata">

**Author:** ![Michael\_Ilseman](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/michael_ilseman/32/44640_2.png) [@Michael\_Ilseman](https://forums.swift.org/u/Michael_Ilseman)\
**Post date:** [July 26, 2018, 8:44pm UTC](https://forums.swift.org/t/se-0221-character-properties/14686/12 "2018-07-26T20:44:15Z")

</div>

@pvieito

This source break is severable and if it's not worth it, we can drop it from the proposal.

However, as @xwu alluded to, this is not as drastic in practice as it seems. As proposed:

```swift
let x = Int("7") // Optional(7)
let y = Float("2") // Optional(2.0)
let z = Int(ascii: "z", radix: 36) // Optional(35)

```

---

<div class="post-metadata">

**Author:** ![Michael\_Ilseman](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/michael_ilseman/32/44640_2.png) [@Michael\_Ilseman](https://forums.swift.org/u/Michael_Ilseman)\
**Post date:** [July 26, 2018, 9:09pm UTC](https://forums.swift.org/t/se-0221-character-properties/14686/13 "2018-07-26T21:09:26Z")

</div>

As alluded to in “Alternatives Considered”

> We are also considering relaxing isEmoji to return true for default-textual Characters without an explicit text presentation selector. For example, U+2708 (AIRPLANE) by default is rendered as `✈` and not `✈️`. As proposed, Character(“\u{U+2708}”).isEmoji would return false, but we are considering having it return true because it _could_ be rendered as emoji.

We’re changing our minds such that `isEmoji` returns true for emoji-presentable Characters with a default textual presentation. `isEmoji` will still return false for emoji-presentable Characters containing an explicit `U+FE0E` (text presentation selector).

Would anyone find it useful to specifically distinguish emoji-presentable Characters with a default textual presentation? Would one additional property such as (strawman name) `isEmojiWithDefaultTextualPresentation: Bool` be useful? Suggestions for a less awful name?

---

<div class="post-metadata">

**Author:** ![xwu](https://avatars.discourse-cdn.com/v4/letter/x/b487fb/32.png) [@xwu](https://forums.swift.org/u/xwu)\
**Post date:** [July 26, 2018, 9:26pm UTC](https://forums.swift.org/t/se-0221-character-properties/14686/14 "2018-07-26T21:26:16Z")

</div>

> [@Michael\_Ilseman](#):
>
> We’re changing our minds such that `isEmoji` returns true for emoji-presentable Characters with a default textual presentation. `isEmoji` will still return false for emoji-presentable Characters containing an explicit `U+FE0E` (text presentation selector).

I highly doubt that this will behave as the vast majority of users would expect. By that definition:

```swift
("1" as Character).isEmoji // true

```

I think the original definition hews much closer to user expectations.

---

<div class="post-metadata">

**Author:** ![Michael\_Ilseman](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/michael_ilseman/32/44640_2.png) [@Michael\_Ilseman](https://forums.swift.org/u/Michael_Ilseman)\
**Post date:** [July 26, 2018, 9:31pm UTC](https://forums.swift.org/t/se-0221-character-properties/14686/15 "2018-07-26T21:31:30Z")

</div>

No, `Character("1").isEmoji` should return false. Character cannot not just check the emoji property on the leading scalar, as that includes emoji components without an emoji presentation. We will have to analyze portions of the grapheme in these situations. Similarly, an isolated regional indicator would also return false.

---

<div class="post-metadata">

**Author:** ![pvieito](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/pvieito/32/33613_2.png) [@pvieito](https://forums.swift.org/u/pvieito)\
**Post date:** [July 26, 2018, 9:34pm UTC](https://forums.swift.org/t/se-0221-character-properties/14686/16 "2018-07-26T21:34:27Z")

</div>

@xwu @Michael_Ilseman Thanks for the clarification! In any case I would oppose to this change.

This change would also raise the question of why `LosslessStringConvertible` does not include the `ascii` keyword while the `FixedWidthInteger` does as they both only accept ASCII based input strings.

Also, `Float("1,44")` does not work but I don't think changing it to `Float(dotSeparator: "1.44")` is nor desirable nor required.

---

<div class="post-metadata">

**Author:** ![xwu](https://avatars.discourse-cdn.com/v4/letter/x/b487fb/32.png) [@xwu](https://forums.swift.org/u/xwu)\
**Post date:** [July 26, 2018, 9:35pm UTC](https://forums.swift.org/t/se-0221-character-properties/14686/17 "2018-07-26T21:35:02Z")

</div>

> [@Michael\_Ilseman](#):
>
> No, `Character("1").isEmoji` should return false. Character cannot not just check the emoji property on the leading scalar, as that includes emoji components without an emoji presentation. We will have to analyze portions of the grapheme in these situations. Similarly, an isolated regional indicator would also return false.

I'm afraid I don't understand how "1" can be `false` while "✈" can be `true` for this property. Unlike isolated regional indicators, both of these are standalone extended grapheme clusters with a non-default emoji representation (I am not referring to the keycap 1 but the [emoji variant](https://emojipedia.org/digit-one/) not supported by Apple's font). Can you explain?

---

<div class="post-metadata">

**Author:** ![jrose](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/jrose/32/408_2.png) [@jrose](https://forums.swift.org/u/jrose)\
**Post date:** [July 26, 2018, 10:01pm UTC](https://forums.swift.org/t/se-0221-character-properties/14686/18 "2018-07-26T22:01:24Z")

</div>

To @xwu's point: [Unicode Utilities: UnicodeSet](https://unicode.org/cldr/utility/list-unicodeset.jsp?a=%5B:Emoji=Yes:%5D)

EDIT: For comparison, [Unicode Utilities: UnicodeSet](https://unicode.org/cldr/utility/list-unicodeset.jsp?a=%5B:Emoji_Presentation=Yes:%5D) contains neither "1" nor "✈".

---

<div class="post-metadata">

**Author:** ![Michael\_Ilseman](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/michael_ilseman/32/44640_2.png) [@Michael\_Ilseman](https://forums.swift.org/u/Michael_Ilseman)\
**Post date:** [July 26, 2018, 11:00pm UTC](https://forums.swift.org/t/se-0221-character-properties/14686/19 "2018-07-26T23:00:51Z")

</div>

Sure! I haven’t fully vetted this approach and the below code would definitely fall under the realm of “implementation details”.

```swift
public var isEmoji: Bool {
  guard _firstScalarProps.isEmoji else { return false }
  if _firstScalarProps._isEmojiComponent {
    return _checkWellFormedEmoji(self)
  }
  return !unicodeScalars.contains(Unicode.Scalar._textPresentationSelector)
}

```

`_checkWellFormedEmoji ` would do the minimum necessary checking to determine if the grapheme is a well-formed emoji candidate. It would not necessarily perform full-blown validation, but rather be “permissive”. None of this would be inlinable. It would check for:

- Flags: leading pair of regional indicators
- Keycaps: leading with `[0-9#*] U+FE0F U+20E3`

￼(Note that flag tag sequences begin with U+1F3F4 (🏴), which is not a component, so they’re already handled).

An alternative approach could leverage the Extended\_Pictographic property, but I think the above approach is superior.

edit: I didn't see your example of the "1" with emoji selector at first. We could have `_checkWellFormedEmoji` permit this by detecting the explicit emoji selector.

---

<div class="post-metadata">

**Author:** ![Michael\_Ilseman](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/michael_ilseman/32/44640_2.png) [@Michael\_Ilseman](https://forums.swift.org/u/Michael_Ilseman)\
**Post date:** [July 26, 2018, 11:11pm UTC](https://forums.swift.org/t/se-0221-character-properties/14686/20 "2018-07-26T23:11:09Z")

</div>

That initializer does not take a radix, and thus isn't latin-skewed in its requirements. It happens to fail for non-ASCII, but we could extend it in the future (or as part of this proposal if you're making that argument) to support more numbers.

A radix-taking one, however, pretty much restricts it to ASCII or the Latin full-width compatibility forms. I.e. the proposed `isHexDigit` property.

[Next page](https://forums.swift.org/t/se-0221-character-properties/14686.md?page=2)
