# 02 · Values, Bindings, and Collections

English narration · HHY 1.7.0

Build a user record, update a counter, and distinguish reusable collections from ranges.

## 00:00:00.000 — Represent a small user record

This lesson turns a few pieces of information into a small, readable data model. We will keep a user record, count a visit, extend a list, and inspect a range. Before executing each example, predict the result. HHY chooses value types at runtime, but clear names and simple checks still matter. A record named user tells the reader more than a variable named data, especially once a script grows beyond a few lines.

```
let user = { name: "Ada", active: true }
let mut visits = 0
visits = visits + 1
print(user.name)
print(visits)
```

## 00:00:31.570 — Bindings and reassignment

Let introduces a binding. Add mut when the binding needs reassignment, as our visit counter does. The update reads the old counter, adds one, and stores the new value. A plain let binding communicates that the name will keep its assigned value. Start with the simplest binding that matches your intention. Mutability of a binding and the behavior of collection operations are separate ideas; we will inspect collection results explicitly instead of assuming in place updates.

```
let name = "Ada"
let mut visits = 0
visits = visits + 1
print(name)
print(visits)
```

## 00:01:07.280 — Recognize basic values

Here are a Boolean, an integer, a floating point number, and null. Null represents absence; it is different from the text null and different from zero. The type function helps inspect a value, while is type checks a named type and returns a Boolean. These functions are useful when learning or handling external data. Prefer an explicit check when a later operation depends on a value being a particular kind.

```
let enabled = true
let count = 42
let ratio = 0.75
let missing = null
print(type(count))
print(is_type("HHY", "String"))
```

## 00:01:36.400 — Keep a reusable list

A list stores values in order and can be kept for reuse. Append returns an extended list, so assign that result to a name. Printing both names demonstrates the distinction: original still contains two entries, while extended has three. Length tells us how many entries are present. This is a helpful habit for unfamiliar APIs: keep the input, capture the output, and observe both before building more logic on top of them.

```
let original = ["Flow", "System"]
let extended = append(original, "Pipe")
print(original)
print(extended)
print(length(extended))
```

## 00:02:09.440 — Read and update maps

A map associates keys with values. This example uses named fields so the source reads like a compact record. Dot access reads the known name field. Get is useful when the key is chosen as a string, and a missing key returns null. Put produces an updated map; capture that result as we did with append. Do not treat a missing key as proof that a numeric field contains zero. Decide how your application handles absence.

```
let user = { name: "Ada", active: true }
let updated = put(user, "visits", 1)
print(user.name)
print(get(updated, "visits"))
print(get(user, "missing"))
```

## 00:02:40.930 — Ranges describe a sequence

A range describes a sequence of numbers without spelling each number in a list. Run this example and inspect its endpoint behavior: zero, one, and two are printed, while three is the exclusive end. This distinction prevents off by one mistakes. A for loop can visit the range directly. In a later lesson we will convert ranges into streams when we want the lazy transformation operators rather than an explicit loop.

```
let indexes = 0..3
for index in indexes {
    print(index)
}
```

## 00:03:12.220 — Use units intentionally

HHY also has literal forms for quantities such as duration, size, and percentage. They express intent more clearly than unexplained numbers. In the tested runtime, five seconds prints as five billion nanoseconds, and ten mebibytes prints as ten million four hundred eighty five thousand seven hundred sixty bytes. The displayed unit can differ from the source spelling. These literals will become useful for timeouts and size filters; do not replace them blindly with plain integers.

```
print(5s)
print(10mib)
print(80%)
```

## 00:03:48.760 — A deliberate binding error

This deliberately broken example reassigns a binding that was not declared mutable. Run the separate error file to see the diagnostic, then compare it with the working counter. The repair is to declare the counter with let mut when repeated updates are part of the design. Do not change every binding to mutable just to silence one error. Keep the lesson small: identify the name being reassigned and explain why that name needs to change.

```
let visits = 0
visits = visits + 1
# Fix: declare let mut visits = 0
```

## 00:04:21.270 — Practice a second user

For practice, create another user, add a visit count, and print selected fields rather than depending on the display order of map keys. Then create a list of two user maps and check its length. You now have the basic shapes needed for real scripts: single values, stable and mutable bindings, ordered lists, keyed maps, and ranges. Next we will put decisions and repeated work around those values using functions and control flow.

```
let user = { name: "Grace", active: false }
let updated = put(user, "visits", 2)
print(updated.name)
print(get(updated, "visits"))
```

