# Single Quoted Character Literals (Why yes, again)

**URL:** <https://forums.swift.org/t/single-quoted-character-literals-why-yes-again/61898>\
**Category:** Pitches\
**Created:** [December 7, 2022, 5:32pm UTC](https://forums.swift.org/t/single-quoted-character-literals-why-yes-again/61898 "2022-12-07T17:32:22Z")\
**Posts on this page:** 1\
**Showing post:** 85

<div class="post-metadata">

**Author:** ![johnno1962](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/johnno1962/32/6805_2.png) [@johnno1962](https://forums.swift.org/u/johnno1962)\
**Post date:** [January 22, 2024, 3:39pm UTC](https://forums.swift.org/t/single-quoted-character-literals-why-yes-again/61898/85 "2024-01-22T15:39:22Z")

</div>

Unfortunately this pitch wandered into a legislative labyrinth that I don't have the wit to find the way out of, nor the wisdom to know when to give up. So.. I've started casting about for alternatives and found an extension and a new Array initialiser that I believe solve the bulk of what I was looking to achieve.

First, looking at the "awkward code" @beccadax mentioned:

> [@beccadax](#):
>
> That has led to [some awkward code that a feature like this could potentially improve](https://github.com/apple/swift-syntax/blob/f58faae4d9fe447336071240adab62500e14dbdb/Sources/SwiftParser/Lexer.swift#L254-L276).

If you define just this one simple extension: (Edited)

```swift
extension FixedWidthInteger {
    /// Basic equality operators
    @_transparent
    public static func == (i: Self, s: Unicode.Scalar) -> Bool {
        return i == s.value
    }
    @_transparent
    public static func != (i: Self, s: Unicode.Scalar) -> Bool {
        return i != s.value
    }
    /// Used in switch statements
    @_transparent
    public static func ~= (s: Unicode.Scalar, i: Self) -> Bool {
        return i == s.value
    }
    /// Maybe useful now and then
    @_transparent
    public static func - (i: Self, s: Unicode.Scalar) -> Self {
        return i - Self(s.value)
    }
}

```

The code could be transformed from:

```swift
    switch self.previous {
    case UInt8(ascii: " "), UInt8(ascii: "\r"), UInt8(ascii: "\n"), UInt8(ascii: "\t"), // whitespace
      UInt8(ascii: "("), UInt8(ascii: "["), UInt8(ascii: "{"), // opening delimiters
      UInt8(ascii: ","), UInt8(ascii: ";"), UInt8(ascii: ":"), // expression separators
      0: // whitespace / last char in file
      return false

```

to

```swift
    switch self.previous {
    case " ", "\r", "\n", "\t", "(", "[", "{", ",", ";", ":", // expression separators
      0: // whitespace / last char in file
      return false

```

This would be a candidate for inclusion in the standard library IMHO as it is an additive change that shouldn't involve collateral damage to the language it is so finely targeted. The compiler tests run through and there are only 12 failures where the diagnostic changed in some tests for invalid code. I have further tested 1000 or so Swift packages from the Swift Package Index and didn't see problems.

Coming full circle on how these pitches started out:

> [@Prepitch: Character integer literals](https://forums.swift.org/t/prepitch-character-integer-literals/10442):
>
> In C, 'a', is a char literal, equivalent to 97. Swift has no such equivalent, requiring awkward spellings like ("a" as Unicode.Scalar).value, which may or may not need additional casts to convert it to the right integer type. Or worse, spelling out the values in hex or decimal directly. This harms readability of code. static char const hexcodes[16] = { '0', '1', '2', '3', '4' ,'5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f' }; let hexcodes:[UInt8] = [48, 49, 50, 51, 52, 53…

It may be better to simply introduce a new initialiser on `Array`s of `FixedWidthInteger`s; something along the lines of:

```swift
extension Array where Element: FixedWidthInteger {
    /// Initialise an Integer array of "characters"
    @inline(__always)
    public init(unicode: String, default: UInt32 = 0) {
        self.init(unicode.map {
            let scalars = $0.unicodeScalars
            if scalars.count == 1,
                let v = scalars.first?.value,
                v <= Element.max {
                return Element(v)
            }
            return Element(`default`)
        })
    }
}

```

So the code above would become:

```swift
let hexcodes = [UInt8](unicode: "0123456789abcdef")

```

Between these two suggestions I believe the majority of use cases I felt were poorly served by current Swift find a solution. I've put together a small Swift Package so you can try these ideas out but would hope we could find a path for these to find their way into the stdlib:

> <https://github.com/johnno1962/Character/blob/main/Sources/Character/Character.swift>

---

_[View the full topic](https://forums.swift.org/t/single-quoted-character-literals-why-yes-again/61898)._
