3. Values and types
Korrin is dynamically typed: values carry their type, variables do not. There are ten kinds of value.
3.1 The value kinds
| Type | Literal(s) | Notes |
|---|---|---|
nil | nil | The single "no value". A function with no return yields it. |
bool | true, false | |
int | 0, 42 | Signed 64-bit (ADR 0010). |
float | 3.14, 1e9 | IEEE-754 double. |
str | "hi" | Immutable, UTF-8, indexed by character (§1.7). |
list | [1, 2, 3] | Ordered, mutable, grows with list.push. |
map | {"k": 1} | Key→value, insertion-ordered, mutable. |
function | fn definitions; builtins | First-class; type() reports "function". |
class | class definitions | Callable — calling it constructs an instance. |
instance | ClassName(...) | type() reports the class name. |
3.2 Numbers
int and float are distinct types. A literal is an int unless it has a .
or an exponent. Arithmetic between an int and a float produces a float;
/ always produces a float. Integer overflow is a runtime error, not
wraparound. See ADR 0010 and §4.3.
print(type(5))
print(type(5 / 1))
# => int
# => float
3.3 Identity and equality
== compares by value for nil, bool, int, float, str, list, and
map (structurally and recursively for the last two). 1 == 1.0 is true.
For function, class, and instance, == is identity: two values are
equal only if they are the same object.
print([1, 2] == [1, 2])
print({"a": 1} == {"a": 1})
# => true
# => true
3.4 Mutability and sharing
str is immutable. list, map, and instance are mutable and shared by
reference: assigning one to a new variable, passing it to a function, or
storing it in a collection does not copy it.
a = [1, 2, 3]
b = a
b.push(4)
print(a)
# => [1, 2, 3, 4]
3.5 Truthiness
Only nil and false are falsy. Every other value — including 0, 0.0, "",
[], and {} — is truthy (ADR 0009).
if []:
print("an empty list is truthy")
# => an empty list is truthy
3.6 Display form
print and str() render a value as:
| Type | Form |
|---|---|
nil | nil |
bool | true / false |
int | decimal digits |
float | decimal, always with a fractional part (3.0, not 3); inf, -inf, nan |
str | the characters themselves (no quotes) |
list | [e1, e2, ...] with elements in repr form |
map | {k1: v1, ...} with keys and values in repr form |
function / class | <function name> / <class Name> |
instance | <Name instance> |
Repr form is the display form except that a str is shown quoted and
escaped ("a\nb"). Collections always show their elements in repr form, so
print(["a"]) writes ["a"] but print("a") writes a.
3.7 Hashable values
Only nil, bool, int, and str may be used as map keys. Using any other
type as a key is E0311. (float is excluded to avoid
nan-key hazards; mutable types are excluded because their identity can change.)
3.8 Map keys and ==
Because keys are compared with ==, 1 and 1.0 would be the same key — but
1.0 is a float and therefore not hashable, so in practice integer keys are
distinct and unambiguous.