# Types and nil safety

> Use inferred and explicit types, nullable values, numeric types, and dynamic binding.

Canonical: https://alice-lang.org/documentation/language/types/

[Documentation index](https://alice-lang.org/documentation/llms.txt) · [Complete book](https://alice-lang.org/llms-full.txt)

## Static types with inference

Alice infers local types from initializers and method results from their bodies. You can annotate parameters, locals, and return values when you want a precise contract.

```alice
def double(x : Int32) : Int32
  x * 2
end
value = double(21)
```

Untyped method parameters are specialized for the types used at call sites when possible. Calling `def length(x)` with a string and an integer array can generate separate typed methods. Return inference can follow methods declared later; an unresolved result may fall back to dynamic binding. An explicit annotation is useful at a library boundary.

## Built-in type names

| Alice                                 | .NET representation                 |
| ------------------------------------- | ----------------------------------- |
| `Int8`, `Int16`, `Int32`, `Int64`     | Signed integer types                |
| `UInt8`, `UInt16`, `UInt32`, `UInt64` | Unsigned integer types              |
| `Float32`, `Float64`                  | `float`, `double`                   |
| `Bool`, `Char`, `String`, `Void`      | Boolean, character, text, no result |
| `Array(T)`                            | `T[]`                               |
| `List(T)`                             | `List<T>`                           |
| `Hash(K, V)`                          | `Dictionary<K, V>`                  |
| `Any`                                 | Dynamic binding                     |
| `T?`                                  | Nullable `T`                        |

Other CLR types can be named directly. Import their namespace or use a qualified name. Generic type arguments use parentheses: `Dictionary(String, Int32)`.

## Nullable values

A nullable annotation allows `nil`. It also requires you to handle the absent case before dereferencing the value. Nullable-reference warnings are compilation errors.

```alice
def label(name : String?) : String
  if name.nil?
    "Guest"
  else
    name.upcase
  end
end
puts label(nil)
puts label("Alice")
```

Expected output:

```text
Guest
ALICE
```

[Edit and run in the Alice playground](https://playground.alice-lang.org/#code=u.ZGVmIGxhYmVsKG5hbWUgOiBTdHJpbmc_KSA6IFN0cmluZwogIGlmIG5hbWUubmlsPwogICAgIkd1ZXN0IgogIGVsc2UKICAgIG5hbWUudXBjYXNlCiAgZW5kCmVuZApwdXRzIGxhYmVsKG5pbCkKcHV0cyBsYWJlbCgiQWxpY2UiKQ)

Inside the `else` branch, the compiler knows `name` has a value. The initial `nil` test is a method call, `name.nil?`, and works on both nullable and nonnullable values.

```alice
name : String? = nil
# puts name.Length  # possible nil: compile error
```

A safe member call uses `&.`, for example `node&.walk(output)`. `not_nil!` asserts a value exists; prefer a checked branch when absence is expected. An assertion moves the risk to runtime if the value is nil. The Crystal-style `value.try &.member` form is not implemented.

## Numeric intent

`Int32` is the usual integer literal type, and `Float64` the usual decimal type. Integer division discards the fractional part. Use a floating operand or a conversion when a fractional result matters. Methods such as `to_i` and `to_f` convert values; conversion and overflow follow the supported numeric and CLR operations rather than arbitrary-precision Ruby arithmetic.

## Dynamic values

`Any` requests runtime member binding:

```alice
def length(x : Any)
  x.Length
end
puts length("Alice")
puts length([1, 2, 3])
```

This is useful at a dynamic boundary. A misspelled member can fail at runtime rather than during normal static checking. Use typed parameters and [generics](https://alice-lang.org/documentation/language/generics.md) for APIs whose contracts are known.

## Type errors

An annotation is a contract, not a cast. Passing an integer to a `String` parameter is an error. The [diagnostic reference](https://alice-lang.org/documentation/reference/diagnostics.md) explains type mismatches, unknown members, generic inference failures, and possible-nil errors.

## Continue reading

- Previous: [Literals and ranges](https://alice-lang.org/documentation/language/literals.md)
- Next: [Operators and expressions](https://alice-lang.org/documentation/language/operators.md)
