mirror of
https://github.com/carbon-language/carbon-lang.git
synced 2026-10-05 21:31:24 +01:00
Primitive types (#1975)
A few changes: - Merge content from the `primitive_types.md` design doc into the overall design `README.md` since there was so much overlap and no need for two copies. - Consistently spell integer types `Carbon.Int(N)` and `Carbon.UInt(N)`, including the `Carbon.` prefix and avoiding `Unsigned(N)`. - Consistently use a comprehensive set of floating-point types. - Incorporates #2015 into the design docs.
This commit is contained in:
+69
-15
@@ -9,6 +9,8 @@ SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||
> **STATUS:** Up-to-date on 09-Aug-2022, including proposals up through
|
||||
> [#1327](https://github.com/carbon-language/carbon-lang/pull/1327).
|
||||
|
||||
> FIXME: add #2015
|
||||
|
||||
<!-- toc -->
|
||||
|
||||
## Table of contents
|
||||
@@ -409,21 +411,27 @@ Primitive types fall into the following categories:
|
||||
|
||||
These are made available through the [prelude](#name-lookup-for-common-types).
|
||||
|
||||
> References: [Primitive types](primitive_types.md)
|
||||
|
||||
### `bool`
|
||||
|
||||
The type `bool` is a boolean type with two possible values: `true` and `false`.
|
||||
The names `bool`, `true`, and `false` are keywords.
|
||||
[Comparison expressions](#expressions) produce `bool` values. The condition
|
||||
arguments in [control-flow statements](#control-flow), like [`if`](#if-and-else)
|
||||
and [`while`](#while), and
|
||||
[`if`-`then`-`else` conditional expressions](#expressions) take `bool` values.
|
||||
|
||||
> References:
|
||||
>
|
||||
> - Question-for-leads issue
|
||||
> [#750: Naming conventions for Carbon-provided features](https://github.com/carbon-language/carbon-lang/issues/750)
|
||||
> - Proposal
|
||||
> [#861: Naming conventions](https://github.com/carbon-language/carbon-lang/pull/861)
|
||||
|
||||
### Integer types
|
||||
|
||||
The signed-integer type with bit width `N` may be written `Carbon.Int(N)`. For
|
||||
convenience and brevity, the common power-of-two sizes may be written with an
|
||||
`i` followed by the size: `i8`, `i16`, `i32`, `i64`, or `i128`. Signed-integer
|
||||
The signed-integer type with bit width `N` may be written `iN` or
|
||||
`Carbon.Int(N)`, as long as `N` is a positive multiple of 8. For example, `i32`
|
||||
is equivalent to `Carbon.Int(32)`. Signed-integer
|
||||
[overflow](expressions/arithmetic.md#overflow-and-other-error-conditions) is a
|
||||
programming error:
|
||||
|
||||
@@ -437,25 +445,40 @@ programming error:
|
||||
to a mathematically incorrect result, such as a two's complement result or
|
||||
zero.
|
||||
|
||||
The unsigned-integer types are: `u8`, `u16`, `u32`, `u64`, `u128`, and
|
||||
`Carbon.UInt(N)`. Unsigned integer types wrap around on overflow, we strongly
|
||||
advise that they are not used except when those semantics are desired. These
|
||||
types are intended for bit manipulation or modular arithmetic as often found in
|
||||
[hashing](https://en.wikipedia.org/wiki/Hash_function),
|
||||
The unsigned-integer types are written `uN` or `Carbon.UInt(N)`, with `N` a
|
||||
positive multiple of 8. Unsigned integer types wrap around on overflow; we
|
||||
strongly advise that they are not used except when those semantics are desired.
|
||||
These types are intended for bit manipulation or modular arithmetic as often
|
||||
found in [hashing](https://en.wikipedia.org/wiki/Hash_function),
|
||||
[cryptography](https://en.wikipedia.org/wiki/Cryptography), and
|
||||
[PRNG](https://en.wikipedia.org/wiki/Pseudorandom_number_generator) use cases.
|
||||
Values which can never be negative, like sizes, but for which wrapping does not
|
||||
make sense
|
||||
[should use signed integer types](/proposals/p1083.md#dont-let-unsigned-arithmetic-wrap).
|
||||
|
||||
Identifiers of the form `iN` and `uN` are _type literals_, resulting in the
|
||||
corresponding type.
|
||||
|
||||
Not all operations will be supported for all bit sizes. For example, division
|
||||
may be limited to integers of at most 128 bits due to LLVM limitations.
|
||||
|
||||
> **Open question:** Bit-field ([1](https://en.wikipedia.org/wiki/Bit_field),
|
||||
> [2](https://en.cppreference.com/w/cpp/language/bit_field)) support will need
|
||||
> some way to talk about non-multiple-of-eight-bit integers, even though Carbon
|
||||
> will likely not support pointers to those types.
|
||||
|
||||
> References:
|
||||
>
|
||||
> - Question-for-leads issue
|
||||
> [#543: pick names for fixed-size integer types](https://github.com/carbon-language/carbon-lang/issues/543)
|
||||
> - Question-for-leads issue
|
||||
> [#750: Naming conventions for Carbon-provided features](https://github.com/carbon-language/carbon-lang/issues/750)
|
||||
> - Proposal
|
||||
> [#820: Implicit conversions](https://github.com/carbon-language/carbon-lang/pull/820)
|
||||
> [#861: Naming conventions](https://github.com/carbon-language/carbon-lang/pull/861)
|
||||
> - Proposal
|
||||
> [#1083: Arithmetic expressions](https://github.com/carbon-language/carbon-lang/pull/1083)
|
||||
> - Proposal
|
||||
> [#2015: Numeric type literal syntax](https://github.com/carbon-language/carbon-lang/pull/2015)
|
||||
|
||||
#### Integer literals
|
||||
|
||||
@@ -489,19 +512,38 @@ represent that value.
|
||||
|
||||
### Floating-point types
|
||||
|
||||
Floating-point types in Carbon have IEEE 754 semantics, use the round-to-nearest
|
||||
Floating-point types in Carbon have IEEE-754 semantics, use the round-to-nearest
|
||||
rounding mode, and do not set any floating-point exception state. They are named
|
||||
with an `f` and the number of bits: `f16`, `f32`, `f64`, and `f128`.
|
||||
[`BFloat16`](primitive_types.md#bfloat16) is also provided.
|
||||
with a _type literals_, consisting of `f` and the number of bits, which must be
|
||||
a multiple of 8. The type literal `fN` results in the type `Carbon.Float(N)`.
|
||||
These types will always be available:
|
||||
[`f16`](https://en.wikipedia.org/wiki/Half-precision_floating-point_format),
|
||||
[`f32`](https://en.wikipedia.org/wiki/Single-precision_floating-point_format),
|
||||
and
|
||||
[`f64`](https://en.wikipedia.org/wiki/Double-precision_floating-point_format).
|
||||
Other sizes may be available, depending on the platform, such as
|
||||
[`f80`](https://en.wikipedia.org/wiki/Extended_precision),
|
||||
[`f128`](https://en.wikipedia.org/wiki/Quadruple-precision_floating-point_format),
|
||||
or
|
||||
[`f256`](https://en.wikipedia.org/wiki/Octuple-precision_floating-point_format).
|
||||
|
||||
Carbon also supports the
|
||||
[`BFloat16`](https://en.wikipedia.org/wiki/Bfloat16_floating-point_format)
|
||||
format, a 16-bit truncation of a "binary32" IEEE-754 format floating point
|
||||
number.
|
||||
|
||||
> References:
|
||||
>
|
||||
> - Question-for-leads issue
|
||||
> [#543: pick names for fixed-size integer types](https://github.com/carbon-language/carbon-lang/issues/543)
|
||||
> - Question-for-leads issue
|
||||
> [#750: Naming conventions for Carbon-provided features](https://github.com/carbon-language/carbon-lang/issues/750)
|
||||
> - Proposal
|
||||
> [#820: Implicit conversions](https://github.com/carbon-language/carbon-lang/pull/820)
|
||||
> [#861: Naming conventions](https://github.com/carbon-language/carbon-lang/pull/861)
|
||||
> - Proposal
|
||||
> [#1083: Arithmetic expressions](https://github.com/carbon-language/carbon-lang/pull/1083)
|
||||
> - Proposal
|
||||
> [#2015: Numeric type literal syntax](https://github.com/carbon-language/carbon-lang/pull/2015)
|
||||
|
||||
#### Floating-point literals
|
||||
|
||||
@@ -546,6 +588,18 @@ There are two string types:
|
||||
- `StringView` - a read-only reference to a byte sequence treated as
|
||||
containing UTF-8 encoded text.
|
||||
|
||||
There is an [implicit conversion](expressions/implicit_conversions.md) from
|
||||
`String` to `StringView`.
|
||||
|
||||
> References:
|
||||
>
|
||||
> - Question-for-leads issue
|
||||
> [#750: Naming conventions for Carbon-provided features](https://github.com/carbon-language/carbon-lang/issues/750)
|
||||
> - Proposal
|
||||
> [#820: Implicit conversions](https://github.com/carbon-language/carbon-lang/pull/820)
|
||||
> - Proposal
|
||||
> [#861: Naming conventions](https://github.com/carbon-language/carbon-lang/pull/861)
|
||||
|
||||
#### String literals
|
||||
|
||||
String literals may be written on a single line using a double quotation mark
|
||||
|
||||
@@ -83,7 +83,7 @@ members in a derived class pointer versus in a base class pointer.
|
||||
|
||||
### Examples
|
||||
|
||||
Conversion from `i32` to `Vector(int)` by forming a vector of N zeroes is
|
||||
Conversion from `i32` to `Vector(i32)` by forming a vector of N zeroes is
|
||||
lossless but not semantics-preserving.
|
||||
|
||||
Conversion from `i32` to `f32` by rounding to the nearest representable value is
|
||||
@@ -106,12 +106,12 @@ The following implicit numeric conversions are available:
|
||||
- `fN` -> `fM` if `M` > `N`
|
||||
- `iN` or `uN` -> `fM` if every value of type `iN` or `uN` can be represented
|
||||
in `fM`:
|
||||
- `i12` or `u11` (or smaller) -> `f16`
|
||||
- `i25` or `u24` (or smaller) -> `f32`
|
||||
- `i54` or `u53` (or smaller) -> `f64`
|
||||
- `i65` or `u64` (or smaller) -> `f80` (x86 only)
|
||||
- `i114` or `u113` (or smaller) -> `f128` (if available)
|
||||
- `i238` or `u237` (or smaller) -> `f256` (if available)
|
||||
- `i8` or `u8` -> `f16`
|
||||
- `i24` or `u24` (or smaller) -> `f32`
|
||||
- `i48` or `u48` (or smaller) -> `f64`
|
||||
- `i64` or `u64` (or smaller) -> `f80` (x86 only)
|
||||
- `i112` or `u112` (or smaller) -> `f128` (if available)
|
||||
- `i232` or `u232` (or smaller) -> `f256` (if available)
|
||||
|
||||
In each case, the numerical value is the same before and after the conversion.
|
||||
An integer zero is translated into a floating-point positive zero.
|
||||
|
||||
@@ -1,104 +0,0 @@
|
||||
# Primitive types
|
||||
|
||||
<!--
|
||||
Part of the Carbon Language project, under the Apache License v2.0 with LLVM
|
||||
Exceptions. See /LICENSE for license information.
|
||||
SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||
-->
|
||||
|
||||
<!-- toc -->
|
||||
|
||||
## Table of contents
|
||||
|
||||
- [TODO](#todo)
|
||||
- [Overview](#overview)
|
||||
- [Integers](#integers)
|
||||
- [Floats](#floats)
|
||||
- [BFloat16](#bfloat16)
|
||||
- [Open questions](#open-questions)
|
||||
- [Primitive types as code vs built-in](#primitive-types-as-code-vs-built-in)
|
||||
- [String view vs owning string](#string-view-vs-owning-string)
|
||||
- [Syntax for wrapping operations](#syntax-for-wrapping-operations)
|
||||
- [Non-power-of-two sizes](#non-power-of-two-sizes)
|
||||
|
||||
<!-- tocstop -->
|
||||
|
||||
## TODO
|
||||
|
||||
This is a skeletal design, added to support [the overview](README.md). It should
|
||||
not be treated as accepted by the core team; rather, it is a placeholder until
|
||||
we have more time to examine this detail. Please feel welcome to rewrite and
|
||||
update as appropriate.
|
||||
|
||||
## Overview
|
||||
|
||||
These types are fundamental to the language as they aren't either formed from or
|
||||
modifying other types. They also have semantics that are defined from first
|
||||
principles rather than in terms of other operations. These will be made
|
||||
available through the [prelude package](README.md#name-lookup-for-common-types).
|
||||
|
||||
- `bool` - a boolean type with two possible values: `true` and `false`.
|
||||
- Signed and unsigned 64-bit integer types:
|
||||
- Standard sizes are available, both signed and unsigned, including `i8`,
|
||||
`i16`, `i32`, `i64`, and `i128`, and `u8`, `u16`, `u32`, `u64`, and
|
||||
`u128`.
|
||||
- Signed overflow in either direction is an error.
|
||||
- Floating points type with semantics based on IEEE-754.
|
||||
- Standard sizes are available, including `f16`, `f32`, and `f64`.
|
||||
- [`BFloat16`](primitive_types.md#bfloat16) is also provided.
|
||||
- `String` - a byte sequence treated as containing UTF-8 encoded text.
|
||||
- `StringView` - a read-only reference to a byte sequence treated as
|
||||
containing UTF-8 encoded text.
|
||||
|
||||
The names `bool`, `true`, and `false` are keywords, and identifiers of the form
|
||||
`i[0-9]*`, `u[0-9]*`, and `f[0-9*]` are _type literals_, resulting in the
|
||||
corresponding type.
|
||||
|
||||
### Integers
|
||||
|
||||
Integer types can be either signed or unsigned, much like in C++. Signed
|
||||
integers are represented using 2's complement and notionally modeled as
|
||||
unbounded natural numbers. Signed overflow in either direction is an error.
|
||||
Specific sizes are available, for example: `i8`, `u16`, `i32`, and `u128`.
|
||||
|
||||
There is an upper bound on the size of an integer, most likely initially set to
|
||||
128 bits due to LLVM limitations.
|
||||
|
||||
### Floats
|
||||
|
||||
Floating point types are based on the binary floating point formats provided by
|
||||
IEEE-754. `f16`, `f32`, `f64` and, if available, `f128` correspond exactly to
|
||||
those sized IEEE-754 formats, and have the semantics defined by IEEE-754.
|
||||
|
||||
### BFloat16
|
||||
|
||||
Carbon also supports the
|
||||
[`BFloat16`](https://en.wikipedia.org/wiki/Bfloat16_floating-point_format)
|
||||
format, a 16-bit truncation of a "binary32" IEEE-754 format floating point
|
||||
number.
|
||||
|
||||
## Open questions
|
||||
|
||||
### Primitive types as code vs built-in
|
||||
|
||||
There are open questions about the extent to which these types should be defined
|
||||
in Carbon code rather than special. Clearly they can't be directly implemented
|
||||
w/o help, but it might still be useful to force the programmer-observed
|
||||
interface to reside in code. However, this can cause difficulty with avoiding
|
||||
the need to import things gratuitously.
|
||||
|
||||
### String view vs owning string
|
||||
|
||||
The right model of a string view versus an owning string is still very much
|
||||
unsettled.
|
||||
|
||||
### Syntax for wrapping operations
|
||||
|
||||
Open question around allowing special syntax for wrapping operations (even on
|
||||
signed types) and/or requiring such syntax for wrapping operations on unsigned
|
||||
types.
|
||||
|
||||
### Non-power-of-two sizes
|
||||
|
||||
Supporting non-power-of-two sizes is likely needed to have a clean model for
|
||||
bitfields, but requires more details to be worked out around memory access.
|
||||
Reference in New Issue
Block a user