Skip to content

Values And Types

Nilakan has runtime values for numbers, booleans, strings, lists, tuples, sets, dicts, and recoverable error values.

n = 3
ok = True
name = "Nilakan"
xs = [1, 2, 3]
pair = ("left", 1)
unique = {1, 2, 3}
mapping = {"a": 1, "b": 2}
empty_dict = {}
empty_set = set()
failure: err = err("MyError", "bad input", "APP0001")

Literal shapes:

| Syntax | Value | | -------------- | ------------------------ | | () | empty tuple | | (x,) | one-item tuple | | (x, y) | tuple | | (expr) | grouped expression | | [x,] | list with trailing comma | | {} | empty dict | | {x} | non-empty set | | set() | empty set | | {key: value} | dict |

Numbers are finite IEEE-754 binary64 values (the JavaScript number representation). This has visible consequences:

  • most decimal fractions are approximate, so 0.1 + 0.2 == 0.3 is False
  • integers are exact only through 9007199254740991 (2^53 - 1)
  • an integer-looking value above that boundary may round to a neighboring value
  • division and arithmetic that produce Infinity or NaN are rejected; neither can become a Nilakan value

Operations that require an integer—indexes, slice bounds, widths, repetition counts, Unicode code points, and CLI numeric limits—check that the runtime value has no fractional part. They do not make unsafe large integers exact. Keep identity-sensitive counters and indexes within the safe-integer range. A literal outside the finite range and non-finite arithmetic are fatal unless the exact operation contract registers a recoverable value failure; Nilakan does not blanket-convert runtime diagnostics into errors. Booleans are True and False. Strings are Unicode strings.

print(0.1 + 0.2 == 0.3) # False
print(9007199254740992 + 1) # 9007199254740992

String length, indexing, slicing, method bounds and returned positions, alignment widths, and ordering all use Unicode code points rather than UTF-16 code units. For example, len("a😀b") is 3, and "a😀b".find("b") is 2.

Lists preserve order and can contain mixed values. Tuples preserve order and are fixed-size values. Sets hold unique hashable values in insertion order. Dicts map hashable keys to values in insertion order. This order is part of Nilakan behavior, not an implementation accident: iteration-like methods, conversion to a list or tuple, pop, and printed output observe it.

Error values have a name, message, diagnostic code, and structured creation origin. They print as err(name, message, code) and are handled with catch or propagated with try. See Error Handling.

Duplicate set elements collapse to one element. Duplicate dict keys replace the value at the original key position.

Adding an existing set element or setting an existing dict key preserves its position. Removing an element or key removes that position; adding it again appends it at the end. Set algebra keeps surviving left-hand elements in their existing order and appends newly introduced right-hand elements in right-hand order. Equality remains order-insensitive for sets and dicts.

Hashable values are numbers, booleans, strings, and tuples containing hashable values. Lists, sets, dicts, and error values are not hashable.

| Value | Hashable | | ------- | ------------------------------ | | num | yes | | bool | yes | | str | yes | | tuple | yes, if every item is hashable | | list | no | | set | no | | dict | no | | err | no |

Structural equality is implemented for error-free containers. Lists and tuples compare items in order. Sets compare by membership. Dicts compare by keys and values, not insertion order. Traversal that reaches an error is rejected; errors are never structurally compared.

print(...) uses Nilakan value formatting: strings are quoted, booleans print as True or False, one-item tuples include a trailing comma, empty sets print as set(), dict entries print as key: value, and errors print as err(name, message, code). See the CLI reference for quote-style control.

Set elements and dict keys must be hashable. Dict and set membership uses hashable lookup. List and tuple membership uses structural equality.

Ordering comparisons are implemented for numbers, strings, and sets. Set ordering means subset and superset comparison. Lists, tuples, and dicts do not support ordering comparisons.

Direct or contained errors cannot participate in equality, inequality, membership comparison, collection search, count, index, or remove. Known cases are rejected statically; unknown shapes are rejected at runtime.

xs = [1, 2, 3]
ys = xs.append(4)
print(ys)
seen = {"a", "b"}
print("a" in seen)
counts = {"a": 1}
print(counts["a"])