:title
3. Types

:content
Every Capy value has a type. The compiler checks types before the program runs. It usually infers the type of a local value.

## Integers

An integer literal has type `s64` when no other type is stated:

:example capy render
function RENDER()
{
	var answer := 42
	print(answer, "\n")
}

:output
42

:content
State the type on the local, or construct the value explicitly:

:example capy render
function RENDER()
{
	var signed : s64 = 8
	var inferred_signed := s64(9)
	var unsigned : u64 = 10
	var inferred_unsigned := u64(11)
	print(signed, " ", inferred_signed, " ", unsigned, " ", inferred_unsigned, "\n")
}

:content

Both forms produce the stated integer type. `var signed : s64 = s64(8)` also compiles, but the constructor repeats the annotation.

Parameters, function results, assignments, typed arrays, struct fields, and the other operand in an expression can also state the integer type. Thus, a function that accepts `u64` can receive the plain literal `8`. An unconstrained literal remains `s64`.

Arithmetic requires operands of the same type. Use a constructor when the surrounding code does not state the required type.

## Booleans and floating-point numbers

A `bool` is either `true` or `false`. Conditions require a boolean value.

:example capy render
function RENDER()
{
	var enabled := true
	var ratio := 2.5
	print(enabled, " ", ratio, "\n")
}

:content

A decimal point or exponent makes an `f64` literal.

## Strings

A `string` stores bytes:

:example capy render
function RENDER()
{
	var name := "Ada"
	var empty := ""
	print(name, empty, "\n")
}

:content

An empty string is still a string value. It is not missing data.

## Arrays and structs

An array contains values of one type:

:example capy render
function RENDER()
{
	var names := ["Ada", "Grace"]
	print(names[0], "\n")
}

:content

A struct gives names to fixed fields:

:example capy render
struct Point
{
	x : s32
	y : s32
}

function RENDER()
{
	var point := Point(3, 4)
	print(point.x, " ", point.y, "\n")
}

:content

## Copy or share

Numbers and booleans are copied: after `var b := a`, changing `b` leaves `a` alone. Strings are values too. A string never changes in place, so it makes no difference whether two names share one.

Arrays, structs, and dvals are objects. `var b := a` makes `b` a second name for the same object, and so do parameters, return values, closure captures, and member reads. A change made through one name shows through all of them. When you need a separate copy, `clone(value)` makes one.

A variable can be pointed at another object with `=`. A parameter cannot.

The collections chapter covers arrays and structs in detail, the dynamic values chapter covers `dval`.

## Numeric functions

Use the `math` functions for floating-point calculations and numeric bounds. Use the `bits` functions for integer masks, shifts, rotations, counts, and bit reinterpretation.

See the `math` function reference for floating-point operations and predicates. See the `bits` function reference for integer bit operations and floating-point bit reinterpretation.

## Dynamic values and none

A `dval` holds data whose shape is known only at run time. The `none` value represents missing dynamic data:

:example capy render
function RENDER()
{
	var profile := { name: "Ada" }
	var missing := none
	print(profile.name, " ", missing?, "\n")
}

:content

`none` is different from `""`, `false`, an empty map, and an empty list. A `dval` is also an object that variables refer to, never a copy. The dynamic-values chapter explains mutation, safe reads, and conversions.

## Type aliases and static type names

A type alias gives another name to a type. It does not create a distinct type at runtime.

Use `expression::type_name` to get the resolved static type of an expression. Capy evaluates the expression once.

:example capy render
type Count = s64

function RENDER()
{
	var total : Count = 12
	var labels := ["new", "done"]
	print(total::type_name, " ", labels::type_name, "\n")
}

:output
s64 [string]

:content

An alias reports its target type. Arrays use `[item_type]`. Structs use their declared name. Function values use their complete function type.

A `dval` expression reports `dval`, regardless of its current contents. Use `get_type_name(value)` to inspect the value stored inside a `dval`.

## Struct field inspection

Struct values have two additional reflection expressions:

| Expression | Result | Meaning |
| --- | --- | --- |
| `value::size` | `s64` | The number of declared fields. This is not a byte size. |
| `value::items` | `dval` | A new map of the current field values, keyed by field name. |

Each `items` entry contains `value` and `type_name`. Use `fields.name.value` for a fixed field. Use `fields[key]["value"]` for a dynamic field name.

`value::items` evaluates its receiver once. Changing the returned map does not change the struct. The compiler rejects `size` and `items` on non-struct values.

The struct reference defines field conversions for scalars, strings, DValues, nested structs, arrays, and function values.

## Dependent generic types

A generic function can use the concrete type of an earlier `any` parameter. Write `parameter::type` in a later parameter or the function result:

```capy
function same(first : any, second : first::type) first::type
{
	-> second
}
```

`parameter::type` is a compile-time type expression. It does not inspect a runtime value. The compiler rejects the removed `type(parameter)` spelling.

:see-group
guides

:see
capy-04-expressions-and-control-flow
capy-07-collections-and-records
capy-08-dynamic-values
type/dvalue
type/struct
get_type_name
type/bool
type/s8
type/s16
type/s32
type/s64
type/u8
type/u16
type/u32
type/u64
type/f32
type/f64
string
dval
length
sqrt
bit_and
