# 8. Stencils — the signature feature

A **stencil** is what makes STencil unique: a first-class, reusable **data template**
with computed fields. You define a shape once, then "stamp" it with `!` to produce
records. Think of a real stencil: a cut-out pattern you press onto material.

## Defining a stencil
```stencil
stencil User(name, age) {
    name: name,
    age: age,
    adult: age >= 18,           // computed field
    tag: name + "#" + age       // fields can use parameters
}
```
Fields are evaluated top to bottom, and a later field may use an earlier one.

## Stamping with `!`
`Name!(args)` stamps the template and returns a record (object). Read fields with `.`:
```stencil
let u = User!("Ember", 20);
print(u.name);    // Ember
print(u.adult);   // true
print(u.tag);     // Ember#20
```

## Reshaping data
A stencil whose parameter is existing data transforms it into a new shape:
```stencil
stencil Summary(u) {
    who: u.name,
    status: u.adult ? "adult" : "minor"
}
let s = Summary!(u);
print(s.who, s.status);   // Ember adult
```

## Stamping over a collection: `!*`
`Name!*list` stamps every element and returns a new list — like a built-in map:
```stencil
let people = [User!("Ada", 30), User!("Ben", 12), User!("Cem", 17)];
let summaries = Summary!*people;
for x in summaries {
    print(x.who, "=>", x.status);
}
// Ada => adult
// Ben => minor
// Cem => minor
```

## Why stencils?
- Declarative: describe the shape and derived values, not step-by-step construction.
- Reusable: one template, stamp it anywhere.
- Great for building/transforming data: API responses, records, config, game entities.

```stencil
// game entities as stencils
stencil Monster(name, hp, power) {
    name: name, hp: hp, power: power,
    label: name + " (HP:" + hp + ")"
}
let dungeon = [Monster!("Goblin", 12, 3), Monster!("Dragon", 30, 9)];
for m in dungeon { print(m.label); }
```

Next: [Error Handling](09_error_handling.md)
