# Lesson XVI
A future is not made true because the hand desires it. It becomes true when sheet, ink, and moment are ready.
## Try
```prolog
?- E = kernel,
infer(E,
[push(int(3)), push(int(2)), gt,
push(quote([push(int(1))])),
push(quote([push(int(0))])),
ifte],
Scheme).
Scheme = scheme([], effect(S, [int|S])).
?- E = kernel,
run(E,
[push(int(3)), push(int(2)), gt,
push(quote([push(int(1))])),
push(quote([push(int(0))])),
ifte],
[], Stack).
Stack = [int(1)].
```
## Lesson
`ifte` introduces control flow, but the removed terms reveal a second pressure: value interpretation needs the same environment boundary as word lookup. Previously `apply`, `bind`, `build`, and `pack` clauses were hard-wired to built-in value forms.
Modify that boundary so later stages can validate, unpack, and rebuild values through `Env` while keeping the primitive row language stable.
> [!info]- Change
> ```diff
> - apply(Env, Word, Stack0, Stack) :-
> - find(Env, Word, InPattern -- OutPattern, Constraints, Goal),
> - bind(InPattern, Stack0),
> - solve(Constraints, []),
> - call(Goal),
> - build(OutPattern, Stack).
> -
> - bind(Pattern, Stack) :-
> - var(Pattern),
> - !,
> - Pattern = Stack.
> - bind([], []).
> - bind([Payload::Type|Patterns], [Value|Values]) :-
> - !,
> - unpack(Type, Value, Payload),
> - bind(Patterns, Values).
> - bind([Value|Patterns], [Value|Values]) :-
> - bind(Patterns, Values).
> -
> - build(Pattern, Stack) :-
> - var(Pattern),
> - !,
> - Stack = Pattern.
> - build([], []).
> - build([Payload::Type|Patterns], [Value|Values]) :-
> - !,
> - pack(Type, Payload, Value),
> - build(Patterns, Values).
> - build([Value|Patterns], [Value|Values]) :-
> - build(Patterns, Values).
> -
> - pack(int, Payload, int(Payload)) :-
> - integer(Payload),
> - !.
> - pack(bool, Payload, bool(Payload)) :-
> - ( Payload == true ; Payload == false ),
> - !.
> - pack(real, Payload, real(Payload)) :-
> - float(Payload),
> - !.
> ```
`ifte` consumes a computed boolean value and two branch quotations.
Runtime comparisons such as `gt`, `lt`, and `eq` leave `bool(true)` or `bool(false)` on the stack. The first conditional consumes a computed `bool` value plus two quotations. Because pushes add to the front of the list, the stack at the `ifte` call site is top-to-rest: `[quote(ElseWords), quote(ThenWords), bool(Bool)|S]`.
Runtime chooses one branch and runs it. This predicate is deliberately simple. It is represented by its `bool` result, so this word consumes only that result and the two branch quotations.
The static rule is intentionally limited. Both quotations must fit the same branch input and produce the same branch output. Branches with different result types are rejected by unification.
```prolog
apply(Env, Word, Stack0, Stack) :-
find(Env, Word, InPattern -- OutPattern, Constraints, Goal),
bind(Env, InPattern, Stack0),
solve(Constraints, []),
call(Goal),
build(Env, OutPattern, Stack).
apply(Env, ifte, [quote(ElseWords), quote(ThenWords), bool(Bool)|Rest], Stack) :-
( Bool == true -> run(Env, ThenWords, Rest, Stack)
; Bool == false -> run(Env, ElseWords, Rest, Stack)
).
bind(_Env, Pattern, Stack) :-
var(Pattern),
!,
Pattern = Stack.
bind(_Env, [], []).
bind(Env, [Payload::Type|Patterns], [Value|Values]) :-
!,
unpack(Type, Value, Payload),
bind(Env, Patterns, Values).
bind(Env, [Value|Patterns], [Value|Values]) :-
bind(Env, Patterns, Values).
build(_Env, Pattern, Stack) :-
var(Pattern),
!,
Stack = Pattern.
build(_Env, [], []).
build(Env, [Payload::Type|Patterns], [Value|Values]) :-
!,
pack(Type, Payload, Value),
build(Env, Patterns, Values).
build(Env, [Value|Patterns], [Value|Values]) :-
build(Env, Patterns, Values).
pack(int, Int, int(Int)) :-
integer(Int),
!.
pack(real, Real, real(Real)) :-
float(Real),
!.
pack(bool, Bool, bool(Bool)) :-
( Bool == true ; Bool == false ),
!.
infer1(_Env, ifte, effect([quote(ElseScheme), quote(ThenScheme), bool|Input], Out), Constraints0, Constraints) :-
!,
copy_term(ThenScheme, scheme(ThenConstraints, effect(Input, Out))),
append(ThenConstraints, Constraints1, Constraints0),
copy_term(ElseScheme, scheme(ElseConstraints, effect(Input, Out))),
append(ElseConstraints, Constraints, Constraints1).
```
[[15_lesson|Prev]] | [[17_lesson|Next]]