# Prepitch: Character integer literals

**URL:** <https://forums.swift.org/t/prepitch-character-integer-literals/10442>\
**Category:** Pitches\
**Created:** [February 28, 2018, 11:08pm UTC](https://forums.swift.org/t/prepitch-character-integer-literals/10442 "2018-02-28T23:08:40Z")\
**Posts on this page:** 20\
**Page:** 1

<div class="post-metadata">

**Author:** ![taylorswift](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/taylorswift/32/43413_2.png) [@taylorswift](https://forums.swift.org/u/taylorswift)\
**Post date:** [February 28, 2018, 11:08pm UTC](https://forums.swift.org/t/prepitch-character-integer-literals/10442/1 "2018-02-28T23:08:40Z")

</div>

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.

```nohighlight
static char const hexcodes[16] = 
{
    '0', '1', '2', '3', '4' ,'5', '6', '7', '8', '9', 
    'a', 'b', 'c', 'd', 'e', 'f'
};

```

```swift
let hexcodes:[UInt8] = 
    [48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 97, 98, 99, 100, 101, 102] 
    // what do these numbers mean???

```

i propose we use single quotes (`'`) as an alternate spelling of integer literals, where the value is the unicode scalar value of the character. This is a logical and useful extension of the C model, in Swift we would now have `'”' == 912`, and so we could use char literals for larger integer types as well.

---

<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:** [February 28, 2018, 11:26pm UTC](https://forums.swift.org/t/prepitch-character-integer-literals/10442/2 "2018-02-28T23:26:09Z")

</div>

My first thoughts are that this seems like a niche use case which probably isn't worth reserving single quotes for (there's still a lot of design work around `String` for the future which could probably use them), and that it might be confusing that it doesn't match the Swift definition of a `Character`. Could this be handled with a slightly less awkward spelling that isn't as concise, like an instance method with an appropriate name? Or a macro-like `#` prefixed function that took a string and converted it into an array of `[UInt8]` or similar?

---

<div class="post-metadata">

**Author:** ![Nevin](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/nevin/32/617_2.png) [@Nevin](https://forums.swift.org/u/Nevin)\
**Post date:** [February 28, 2018, 11:35pm UTC](https://forums.swift.org/t/prepitch-character-integer-literals/10442/3 "2018-02-28T23:35:27Z")

</div>

Is there a reason you can’t just extend whatever type your project uses to be `ExpressibleByStringLiteral`?

---

<div class="post-metadata">

**Author:** ![taylorswift](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/taylorswift/32/43413_2.png) [@taylorswift](https://forums.swift.org/u/taylorswift)\
**Post date:** [March 1, 2018, 12:02am UTC](https://forums.swift.org/t/prepitch-character-integer-literals/10442/4 "2018-03-01T00:02:10Z")

</div>

that’s what i thought at first but I found myself looking up ASCII tables so often that i’ve come to believe this is something that deserves to have syntax in the language. as for reserving single quotes, i’ve heard this excuse so many times, but _no one has ever proposed or even has an idea of what single quotes would even be used for in such a context_, whereas integer char literals have precedent in C, C++, and Java. i can’t think of a more appropriate

also # macros,,, _eww_

---

<div class="post-metadata">

**Author:** ![taylorswift](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/taylorswift/32/43413_2.png) [@taylorswift](https://forums.swift.org/u/taylorswift)\
**Post date:** [March 1, 2018, 12:04am UTC](https://forums.swift.org/t/prepitch-character-integer-literals/10442/5 "2018-03-01T00:04:04Z")

</div>

in my opinion, extending an external type to conform to an external protocol is a horrible idea

---

<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:** [March 1, 2018, 12:28am UTC](https://forums.swift.org/t/prepitch-character-integer-literals/10442/6 "2018-03-01T00:28:05Z")

</div>

I think your particular project, whatever it is, is probably not representative of the general population if you're using ASCII integer codes that frequently. There have been multiple discussions about the use of single quotes on the mailing list, e.g. controlling escaping behaviour. While you're correct that many C-adjacent languages use single quotes for this, it's far from universal. Some examples, from a quick search of relatively popular languages (forgive any errors):

- Ruby, PHP: Single quotes disable string interpolation and most escaping.
- Python, Javascript: No significant difference between single and double quotes (except which one needs to be escaped within the string).

---

<div class="post-metadata">

**Author:** ![Chris\_Lattner3](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/chris_lattner3/32/348_2.png) [@Chris\_Lattner3](https://forums.swift.org/u/Chris_Lattner3)\
**Post date:** [March 1, 2018, 12:43am UTC](https://forums.swift.org/t/prepitch-character-integer-literals/10442/7 "2018-03-01T00:43:42Z")

</div>

I'm not arguing this is great, but FYI, you can spell this as UInt8(ascii: "a") today.

---

<div class="post-metadata">

**Author:** ![taylorswift](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/taylorswift/32/43413_2.png) [@taylorswift](https://forums.swift.org/u/taylorswift)\
**Post date:** [March 1, 2018, 1:21am UTC](https://forums.swift.org/t/prepitch-character-integer-literals/10442/8 "2018-03-01T01:21:02Z")

</div>

the thing is half the time you want to use these things as the right hand side of a comparison, and having an expression on the right hand side just isn’t a good look

```swift
if u == '@' 
{
    ...
} 
else if u == '#'
{
    ...
} 
...

```

vs

```swift
if u == UInt8(ascii: "@") // what is going on here? 
// does the compiler even know this is a constant?
{
    ...
}
else if u == UInt8(ascii: "#")
{
    ...
} 
...

```

---

<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:** [March 1, 2018, 1:27am UTC](https://forums.swift.org/t/prepitch-character-integer-literals/10442/9 "2018-03-01T01:27:53Z")

</div>

> [@taylorswift](#):
>
> // does the compiler even know this is a constant?

Yes, it does.

---

<div class="post-metadata">

**Author:** ![tim1724](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/tim1724/32/450_2.png) [@tim1724](https://forums.swift.org/u/tim1724)\
**Post date:** [March 1, 2018, 1:34am UTC](https://forums.swift.org/t/prepitch-character-integer-literals/10442/10 "2018-03-01T01:34:19Z")

</div>

If I were doing a lot of work where ASCII constants would be useful I'd probably do something like this:

```swift
enum ASCII {
	static let NUL = 0
	static let SOH = 1
	static let STX = 2
	// …
	static let _0 = 48
	static let _1 = 49
	// …
	static let at = 64
	static let A = 65
	static let B = 66
	// …
	static let a = 97
	// …
}

```

and use `let foo = [ASCII.F, ASCII.o, ASCII.o]`

Well, actually I'd probably just define `enum A` to save some typing: `let foo = [A.F, A.o, A.o]`

But really I'd want to re-think why I was using so many ASCII constants in my code to begin with. If I had so many that I need to shorten them like this I probably just want to read in an external data file instead.

---

<div class="post-metadata">

**Author:** ![taylorswift](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/taylorswift/32/43413_2.png) [@taylorswift](https://forums.swift.org/u/taylorswift)\
**Post date:** [March 1, 2018, 1:38am UTC](https://forums.swift.org/t/prepitch-character-integer-literals/10442/11 "2018-03-01T01:38:56Z")

</div>

yes it _probably_ does, but as many people have found recently, the answer to the general question “does the compiler know this is a constant” is “we really don’t know for sure”

---

<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:** [March 1, 2018, 1:44am UTC](https://forums.swift.org/t/prepitch-character-integer-literals/10442/12 "2018-03-01T01:44:37Z")

</div>

> [@taylorswift](#):
>
> yes it probably does, but as many people have found recently, the answer to the general question “does the compiler know this is a constant” is “we really don’t know for sure”

I'm not sure what you mean. The answer is yes, it does.

Source:

```swift
let x = UInt8(ascii: "@")

```

Assembly output (`-O`):

```swift
main:
  push rbp
  mov rbp, rsp
  mov byte ptr [rip + output.x : Swift.UInt8], 64
  xor eax, eax
  pop rbp
  ret

output.x : Swift.UInt8:

```

---

<div class="post-metadata">

**Author:** ![taylorswift](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/taylorswift/32/43413_2.png) [@taylorswift](https://forums.swift.org/u/taylorswift)\
**Post date:** [March 1, 2018, 2:09am UTC](https://forums.swift.org/t/prepitch-character-integer-literals/10442/13 "2018-03-01T02:09:11Z")

</div>

running `--emit-assembly` and counting the `mov`s is a learning exercise, _not_ a workflow.

---

<div class="post-metadata">

**Author:** ![allevato](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/allevato/32/385_2.png) [@allevato](https://forums.swift.org/u/allevato)\
**Post date:** [March 1, 2018, 2:11am UTC](https://forums.swift.org/t/prepitch-character-integer-literals/10442/14 "2018-03-01T02:11:04Z")

</div>

Swift already has precedent for treating untyped double-quoted string literals as different types via the `ExpressibleBy{String,Character,UnicodeScalar}Literal` protocols, instead of introducing different quotes.

So, if we want to pursue this, the consistent way would be to define a new compiler-known protocol, `ExpressibleByASCIICodeUnitLiteral`, have `UInt8` conform to it, and then update the handling of string literals in the compiler to make them type-check correctly, detecting errors at compile-time instead of runtime:

```swift
func foo(_ x: UInt8) { ... }

foo("a") // works
foo("È") // error: U+00C9 is not a valid ASCII code unit
foo("ab") // error: the literal has more than one code unit

```

---

<div class="post-metadata">

**Author:** ![taylorswift](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/taylorswift/32/43413_2.png) [@taylorswift](https://forums.swift.org/u/taylorswift)\
**Post date:** [March 1, 2018, 2:22am UTC](https://forums.swift.org/t/prepitch-character-integer-literals/10442/15 "2018-03-01T02:22:41Z")

</div>

this is pretty close to what i’m proposing i only use single quotes because i think double quotes are a little overloaded in the language currently

---

<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:** [March 1, 2018, 2:23am UTC](https://forums.swift.org/t/prepitch-character-integer-literals/10442/16 "2018-03-01T02:23:45Z")

</div>

> [@taylorswift](#):
>
> running --emit-assembly and counting the movs is a learning exercise, not a workflow.

Still not sure what you're getting at. You asked a yes-or-no question and I answered it; I believe my answer is correct, and I showed my work.

---

<div class="post-metadata">

**Author:** ![taylorswift](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/taylorswift/32/43413_2.png) [@taylorswift](https://forums.swift.org/u/taylorswift)\
**Post date:** [March 1, 2018, 2:32am UTC](https://forums.swift.org/t/prepitch-character-integer-literals/10442/17 "2018-03-01T02:32:26Z")

</div>

yes and you’ve convinced _me_ that the compiler knows that in this case (at least for now barring a regression) but anyone else not reading this thread would have to repeat the experiment for themselves to figure this out. and you haven’t convinced me that will happen in any context, since the compiler’s thought process is pretty much opaque to anyone who’s not a swift compiler dev and we’re all too familiar with the compiler making strange and nonobvious decisions

either way we’re really making a mountain out of what was originally a small aside as this prepitch is really more about ergonomics

---

<div class="post-metadata">

**Author:** ![Chris\_Lattner3](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/chris_lattner3/32/348_2.png) [@Chris\_Lattner3](https://forums.swift.org/u/Chris_Lattner3)\
**Post date:** [March 1, 2018, 5:14am UTC](https://forums.swift.org/t/prepitch-character-integer-literals/10442/18 "2018-03-01T05:14:33Z")

</div>

> [@allevato](#):
>
> So, if we want to pursue this, the consistent way would be to define a new compiler-known protocol, ExpressibleByASCIICodeUnitLiteral, have UInt8 conform to it, and then update the handling of string literals in the compiler to make them type-check correctly, detecting errors at compile-time instead of runtime

This can be made to work, but the logical endpoint of this is that UInt16 would allow code points that fit into a UTF16 size and UInt32 would allow any code point. Is that desirable? I could see how this could be confusing to some:

```swift
let x : Int = "f"

```

One nice thing about the C approach with single quotes is that it makes it clear what is going on, and it would allow defining a new default type for:

```swift
 let x = 'x'

```

which would clearly be Character.

-Chris

---

<div class="post-metadata">

**Author:** ![allevato](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/allevato/32/385_2.png) [@allevato](https://forums.swift.org/u/allevato)\
**Post date:** [March 1, 2018, 5:57am UTC](https://forums.swift.org/t/prepitch-character-integer-literals/10442/19 "2018-03-01T05:57:53Z")

</div>

> [@Chris\_Lattner3](#):
>
> This can be made to work, but the logical endpoint of this is that UInt16 would allow code points that fit into a UTF16 size and UInt32 would allow any code point. Is that desirable?

I think the argument could be made that we want to provide APIs that satisfy the most common needs of users without worrying about taking things to their logical end. Unscientifically, my gut tells me that processing ASCII text that arrives in the form of `[UInt8]` or `Data` probably qualifies as more valuable to have as shorthand than UTF-16 or UTF-32.

Another option would be to introduce a unique `ASCIICodeUnit` type that is essentially a 7-bit unsigned integer instead of extending `UInt8` directly, but that might make interop with `UInt8`s more verbose elsewhere.

> [@Chris\_Lattner3](#):
>
> I could see how this could be confusing to some:
> 
> ```swift
> let x : Int = "f"
> 
> ```

I wouldn't expect that to be supported; for clarity, we'd probably only want to support specific-size integers, if support for more than `UInt8` was up for debate. But that's just my opinion and attempt at drawing the line somewhere.

> [@Chris\_Lattner3](#):
>
> One nice thing about the C approach with single quotes is that it makes it clear what is going on, and it would allow defining a new default type for:
> 
> ```swift
> let x = 'x'
> 
> ```
> 
> which would clearly be Character.

By itself, a new quoting scheme specifically for `Character` feels like a separate issue than the one in the OP about making it cleaner to write ASCII literals that can be inferred as `UInt8`. Unless, are you suggesting that the scheme could be stretched such single quotes would default to `Character` but also be inferred as other types representing "singular" text entities (ASCII `UInt8`, `Unicode.Scalar`) and double quotes would only be inferred as sequences of those entities (`String`, `StaticString`)?

---

<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:** [March 1, 2018, 6:12am UTC](https://forums.swift.org/t/prepitch-character-integer-literals/10442/20 "2018-03-01T06:12:57Z")

</div>

> [@allevato](#):
>
> Another option would be to introduce a unique ASCIICodeUnit type that is essentially a 7-bit unsigned integer instead of extending UInt8 directly, but that might make interop with UInt8s more verbose elsewhere.

If we're going to enable uses like

```swift
func foo(_ x: UInt8) { ... }
foo("a") // works

```

then I think that'd be the way to go.

It looks very confusing that you can supply what looks like a string literal to a function that takes a numeric argument. Unless I'm mistaken, the Swift compiler can already work with builtin types such as `Int7` internally, and the LLVM intrinsics are there to support casting without issue. With such a type, your hypothetical function would be self-documenting:

```swift
func foo(_ x: ASCII.CodeUnit) { ... }
foo("a") // of course this works

```

[Next page](https://forums.swift.org/t/prepitch-character-integer-literals/10442.md?page=2)
