# Lesson VI
The drop shows its form; the brush sets it down.
## Try
```prolog
?- run([push(int(2)), push(int(3)), add], [], Stack).
Stack = [int(5)].
?- infer([push(int(2)), push(int(3)), add], In, Out).
In = [],
Out = [int].
?- run([push(int(foo))], [], Stack).
false.
```
## Learn
Until now an object-language integer has been the same bare Prolog integer used by arithmetic. Remove that shortcut: stack values become explicit, such as `int(N)`, and value introduction is routed through `push` and `lit`. The old identity `pack/3` and `unpack/3` clauses are changed because they blurred a design boundary: primitives compute with host payloads, but the stack stores language values.
> [!info]- Change
> ```diff
> - infer([Word|Words], Stack0, Stack) :-
> - word(Word, InPattern -- OutPattern, _Goal),
> - types(InPattern, Stack0),
> - types(OutPattern, Stack1),
> - infer(Words, Stack1, Stack).
> -
> - unpack(int, Value, Value) :-
> - integer(Value).
> -
> - pack(int, Payload, Payload) :-
> - integer(Payload).
> ```
`push/1` validates a literal and puts it on the runtime stack unchanged.
```prolog
apply(push(Value), Stack, [Value|Stack]) :-
lit(Value, _Type).
```
`push/1` contributes the literal's type to the static stack.
```prolog
infer([Word|Words], Stack0, Stack) :-
infer1(Word, Stack0, Stack1),
infer(Words, Stack1, Stack).
infer1(push(Value), Stack, [Type|Stack]) :-
!,
lit(Value, Type).
infer1(Word, Stack0, Stack) :-
word(Word, InPattern -- OutPattern, _Goal),
types(InPattern, Stack0),
types(OutPattern, Stack).
```
`lit/2` is the only way a literal enters runtime or inference.
```prolog
unpack(int, int(Int), Int) :-
integer(Int).
pack(int, Payload, int(Payload)) :-
integer(Payload).
lit(int(Int), int) :-
integer(Int).
```
[[05_lesson|Prev]] | [[07_lesson|Next]]