Re: Factor

Factor: the language, the theory, and the practice.

Stack Effects

Thursday, November 16, 2023

#syntax

Factor word definitions have required stack effects. These are used by the stack checker to verify that word definitions are consistent with their stack effects, have internal branches that have similar stack effects, and other validness checks.

Long ago, these stack effects were optional – words might have looked something like this:

: add2 2 + ;

At some point over a decade ago, we made stack effects required, and now it looks like this:

: add2 ( m -- n ) 2 + ;

That change has been generally positive for the Factor standard library – helping readability, improving natural word documentation, and improving the locality of stack checker errors. Every once in awhile, I think fondly back to those simpler days.

Well, it’s still possible to have the good ol’ days back – check this out!

The stack-checker has an infer word to apply the stack checker algorithm to a quotation, returning the inferred stack effect. You can try it in the Listener using the Ctrl-I shortcut or calling it directly:

IN: scratchpad [ 2 + ] infer .
( x -- x )

IN: scratchpad [ [ + ] with map ] infer .
( x x -- x )

We can use this to make new syntax that defines a word with the stack effect that was inferred:

USING: effects.parser kernel parser stack-checker words ;

SYNTAX: INFER:
    [ scan-new-word parse-definition ] with-definition
    dup infer define-declared ;

And now we can just write our words without bothering to write their stack effects:

INFER: add2 2 + ;

And then use it:

IN: scratchpad 1 add2 .
3

Pretty neat!