# Lesson X
The name does not move the brush. It keeps the hand from wandering.
## Try
```prolog
?- infer(kernel, [push(quote([dup, mul])), call], Effect).
Effect = effect([int|S], [int|S]).
?- run(kernel, [push(int(4)), push(quote([dup, mul])), call], [], Stack).
Stack = [int(16)].
```
## Lesson
We passed an environment but primitives still lived outside that context. Remove the unindexed word rows and `empty_env/1`. The kernel itself becomes the base lookup context.
That change is more than naming. `find/4` now copies rows from the selected environment, so the same call shape can later search extended environments without changing runtime or inference again.
> [!info]- Change
> ```diff
> - word(dup, [A|S] -- [A, A|S], true).
> - word(drop, [_|S] -- S, true).
> - word(swap, [A, B|S] -- [B, A|S], true).
> - word(over, [A, B|S] -- [B, A, B|S], true).
> - word(add, [A::int, B::int|S] -- [C::int|S], C is B + A).
> - word(sub, [A::int, B::int|S] -- [C::int|S], C is B - A).
> - word(mul, [A::int, B::int|S] -- [C::int|S], C is B * A).
> -
> - apply(_Env, Word, Stack0, Stack) :-
> - word(Word, InPattern -- OutPattern, Goal),
> - bind(InPattern, Stack0),
> - call(Goal),
> - build(OutPattern, Stack).
> -
> - infer1(_Env, Word, Stack0, Stack) :-
> - word(Word, InPattern -- OutPattern, _Goal),
> - types(InPattern, Stack0),
> - types(OutPattern, Stack).
> -
> - empty_env(env([])).
> ```
Primitive rows are the single source for fixed words. They describe stack shape and runtime computation for words whose meaning does not depend on a literal argument.
The base environment is the atom `kernel`. Primitive words are explicit environment-indexed clauses. The environment argument is what makes the kernel a lookup context instead of a generated list of rows.
```prolog
word(kernel, dup, [A|S] -- [A, A|S], true).
word(kernel, drop, [_|S] -- S, true).
word(kernel, swap, [A, B|S] -- [B, A|S], true).
word(kernel, over, [A, B|S] -- [B, A, B|S], true).
word(kernel, add, [A::int, B::int|S] -- [C::int|S], C is B + A).
word(kernel, sub, [A::int, B::int|S] -- [C::int|S], C is B - A).
word(kernel, mul, [A::int, B::int|S] -- [C::int|S], C is B * A).
```
Find searches the current environment for a word clause, then copies the stored row so variables in primitive effects stay fresh for each use.
```prolog
find(Env0, Word, InOut, Goal) :-
nonvar(Env0),
word(Env0, Word, StoredInOut, StoredGoal),
copy_term(word(Word, StoredInOut, StoredGoal), word(Word, InOut, Goal)).
```
Fixed words project through primitive rows.
```prolog
apply(Env, Word, Stack0, Stack) :-
find(Env, Word, InPattern -- OutPattern, Goal),
bind(InPattern, Stack0),
call(Goal),
build(OutPattern, Stack).
infer1(Env, Word, Stack0, Stack) :-
find(Env, Word, InPattern -- OutPattern, _Goal),
types(InPattern, Stack0),
types(OutPattern, Stack).
```
[[09_lesson|Prev]] | [[11_lesson|Next]]