# 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
```prolog
% 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.
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 context for a word clause, then copies the
% stored row so variables in primitive effects stay fresh for each
% use.
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.
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).
```