Forth DISCUSSION

Why does Forth write IF ... ELSE ... THEN with THEN at the end, and how does the flag work?

Started by hos Forth IF ELSE THENForth flagscompile-only wordscontrol structuresGforth
4 replies 248 views 5 participants
Latest activity · 30 Sep 2026

Why does Forth write IF ... ELSE ... THEN with THEN at the end, and how does the flag work?

hos Forth Forum
#1

I am learning Forth with Gforth and the conditional confuses me. In other languages THEN comes right after the condition, but here it closes the statement: : CHECK ( n -- ) 10 > IF ." big" ELSE ." small" THEN ;. I also cannot see where the condition goes, and typing 5 10 > IF ." yes" THEN at the prompt gives an error about a compile-only word.

How should I read this structure, what exactly does IF test, and why does it only work inside a colon definition?

Community replies 4

Re: Why does Forth write IF ... ELSE ... THEN with THEN at the end, and how does the flag work?

#2

The condition comes before IF, because everything in Forth is postfix. 10 > compares the number on the stack with 10 and leaves a flag; IF removes that flag and either continues or jumps. Read it as: compute a flag, IF true do this, ELSE do that, THEN carry on with the rest.

THEN means "after that, continue here", not "in that case". It simply marks the point where both branches rejoin. Many systems, Gforth included, provide ENDIF as a synonym if you find that easier to read.

Re: Why does Forth write IF ... ELSE ... THEN with THEN at the end, and how does the flag work?

#3

IF treats zero as false and any non-zero value as true, and it always consumes the flag. The comparison words return well-formed flags: 0 for false and -1, all bits set, for true in standard Forth. So 12 CHECK runs 12 10 >, gets -1 and prints big; 7 CHECK gets 0 and prints small.

Because the flag is consumed, keep a copy if you still need the value: DUP 0< IF NEGATE THEN is a complete absolute-value routine. The idiom ?DUP IF ... THEN duplicates the top item only when it is non-zero, which saves a DROP in the false case.

Re: Why does Forth write IF ... ELSE ... THEN with THEN at the end, and how does the flag work?

#4

It only works inside a definition because IF, ELSE and THEN are compiling words. When the compiler meets IF it lays down a conditional branch with an empty target and remembers the location; ELSE and THEN go back and fill in the jump addresses. That needs code under construction to patch. At the prompt the interpreter executes each word as soon as it is read, so there is nothing to branch over, and the standard leaves the interpretation behaviour of these words undefined.

To test something quickly, wrap it in a throwaway definition: : T 5 10 > IF ." yes" THEN ; T. For conditional compilation of source text there is a separate set: [IF], [ELSE] and [THEN].

Re: Why does Forth write IF ... ELSE ... THEN with THEN at the end, and how does the flag work?

#5

Each IF needs its own THEN, so nested tests end in a row of them: DUP 0< IF ." negative" ELSE DUP 0= IF ." zero" ELSE ." positive" THEN THEN DROP. The compiler checks the pairing and complains about an unbalanced control structure when the definition ends.

When you are selecting on one value among several, CASE ... OF ... ENDOF ... ENDCASE is cleaner than a ladder of nested tests. And check the stack effect of both branches: each path through the IF should leave the same number of items, otherwise the word's stack comment is wrong and the bug surfaces far away from its cause.

TEP COMMUNITY