Variables and Types in Carbon
Learn about variable declarations, data types, type inference, and constants in Carbon with practical Docker-ready examples
Carbon is a statically typed language with partial type inference, designed to feel familiar to C++ developers while offering a cleaner, more modern syntax. Understanding Carbon’s type system is foundational because the language was designed with explicit, verifiable types at its core—unlike C++’s template system, where types are often checked only at instantiation.
Carbon uses var for mutable variable declarations and let for immutable bindings. This distinction is built directly into the language syntax, making mutability intent explicit at every declaration. The type system is nominative and static—the compiler knows every type at compile time and checks type safety rigorously.
In this tutorial you will declare variables of Carbon’s primitive types, use type inference with :! and auto, define constants, and see how Carbon’s integer and boolean types compare to their C++ equivalents.
Variable Declarations: var and let
Carbon separates mutable and immutable bindings at the syntax level. The var keyword declares a mutable variable; let declares an immutable binding. Both require (or infer) a type.
Create a file named variables_basic.carbon:
import Core library "io";
fn Run() {
// Mutable variable: var <name>: <type> = <value>;
var x: i32 = 42;
var y: f64 = 3.14;
var greeting: String = "Carbon";
var flag: bool = true;
Core.Print(x);
Core.PrintStr("\n");
Core.PrintStr(greeting);
Core.PrintStr("\n");
}
Key points from this example:
vardeclares a mutable variable that can be reassigned later- Types are written after the name, separated by
:— this is Carbon’s postfix type syntax i32is a 32-bit signed integer;f64is a 64-bit floating-point numberStringis Carbon’s built-in string typeboolholdstrueorfalse
Immutable Bindings with let
Create a file named variables_let.carbon:
import Core library "io";
fn Run() {
// Immutable binding: let <name>: <type> = <value>;
let max_retries: i32 = 5;
let pi: f64 = 3.14159;
let language_name: String = "Carbon";
Core.PrintStr("Language: ");
Core.PrintStr(language_name);
Core.PrintStr("\n");
Core.PrintStr("Max retries: ");
Core.Print(max_retries);
Core.PrintStr("\n");
}
let bindings cannot be reassigned after initialization. This is analogous to const in C++ or Rust’s default bindings. Prefer let whenever a value does not need to change — the compiler enforces it.
Integer and Floating-Point Types
Carbon provides explicit-width numeric types, similar to C++’s <cstdint> types but as first-class language types rather than typedefs.
Create a file named variables_numeric.carbon:
import Core library "io";
fn Run() {
// Signed integers
var a: i8 = 127;
var b: i16 = 32767;
var c: i32 = 2147483647;
var d: i64 = 9223372036854775807;
// Unsigned integers
var ua: u8 = 255;
var ub: u16 = 65535;
var uc: u32 = 4294967295;
// Floating point
var f: f32 = 3.14;
var g: f64 = 2.718281828;
Core.PrintStr("i32 max: ");
Core.Print(c);
Core.PrintStr("\n");
Core.PrintStr("u8 max: ");
Core.Print(ua as i32);
Core.PrintStr("\n");
}
Carbon’s numeric types:
| Type | Description | Range |
|---|---|---|
i8 | 8-bit signed integer | -128 to 127 |
i16 | 16-bit signed integer | -32,768 to 32,767 |
i32 | 32-bit signed integer | -2,147,483,648 to 2,147,483,647 |
i64 | 64-bit signed integer | -9.2×10¹⁸ to 9.2×10¹⁸ |
u8 | 8-bit unsigned integer | 0 to 255 |
u16 | 16-bit unsigned integer | 0 to 65,535 |
u32 | 32-bit unsigned integer | 0 to 4,294,967,295 |
u64 | 64-bit unsigned integer | 0 to 1.8×10¹⁹ |
f32 | 32-bit IEEE 754 float | ~±3.4×10³⁸, 7 decimal digits |
f64 | 64-bit IEEE 754 float | ~±1.8×10³⁰⁸, 15 decimal digits |
Reassigning Mutable Variables
var variables can be reassigned after declaration. The type is fixed at declaration — Carbon is statically typed, so you cannot change a variable’s type through reassignment.
Create a file named variables_mutate.carbon:
import Core library "io";
fn Run() {
var count: i32 = 0;
Core.PrintStr("Initial count: ");
Core.Print(count);
Core.PrintStr("\n");
count = 10;
Core.PrintStr("Updated count: ");
Core.Print(count);
Core.PrintStr("\n");
count = count + 5;
Core.PrintStr("Final count: ");
Core.Print(count);
Core.PrintStr("\n");
}
Running with Docker
Carbon’s nightly toolchain runs on Linux. Use the Ubuntu Docker image to compile and run any of these examples.
| |
To run the mutation example:
| |
Note: The first run downloads approximately 200 MB for the toolchain. Subsequent runs reuse the cached Ubuntu image.
Expected Output
For variables_basic.carbon:
42
Carbon
For variables_let.carbon:
Language: Carbon
Max retries: 5
For variables_numeric.carbon:
i32 max: 2147483647
u8 max: 255
For variables_mutate.carbon:
Initial count: 0
Updated count: 10
Final count: 15
Key Concepts
varvslet—vardeclares a mutable variable;letdeclares an immutable binding. Preferletwhen the value will not change; the compiler enforces it.- Postfix type syntax — Types appear after the name with a colon (
var x: i32), not before as in C++ (int x). This is more readable with complex types. - Static, nominative typing — Every variable has a fixed type known at compile time. Carbon does not allow implicit type coercion between numeric types.
- Explicit-width integers — Carbon uses
i8,i16,i32,i64,u8,u16,u32,u64rather than platform-dependentintorlong. This eliminates a common class of portability bugs from C++. f32andf64— Floating-point types use explicit sizes matching IEEE 754 single and double precision.boolfor booleans — Carbon uses lowercaseboolwith literalstrueandfalse, unlike C++ wheretrue/falseare also available butintis often used for booleans in legacy code.- No implicit narrowing — Carbon does not silently truncate integers when assigning between different-width types. Explicit conversion is required, preventing a widespread C++ bug class.
- Experimental language — Carbon is pre-0.1; some type features (e.g., richer
autoinference, user-defined type aliases) are still under active development. The concepts shown here reflect the current nightly toolchain.
Comments
Loading comments...
Leave a Comment