A generator is a word that generates data to be left on the stack for subsequent words to use. The most basic example is time which generates a single integer timestamp. Generators increase the number of items on the stack.
A modifier is a word that modifies data already on the stack, leaving the data in place for subsequent words to use. A good example is trim which takes a string of text from the stack, trims whitespce from both ends, and returns the modified string to the stack. Modifiers do not change the number of items on the stack.
A consumer is a word that consumes data already on the stack. For example, print takes one item from the stack and displays it. Consumers reduce the number of items on the stack.
Certain words may fit into more than one category. For example, read is a consumer when it takes from the stack a string holding the name of a file to read, and then a generator when it returns the contents of said file on the stack as a new string.
Consider the following code:
'myfile.txt' read trim print
Using a stack mechanism to pass data between words quickly becomes very flexible resulting in easy stdin/stdout behavior analagous to piping data around within a UNIX shell. Consider that additional modifiers could be placed between trim and print providing the stack still contains something for print to eventually consume. wrap is a consumer/modifier in that to implement word wrapping, it must consume an integer to determine line length, and then modify the subject text accordingly:
'myfile.txt' read trim 72 wrap print
Stack based languages are often associated with excessive use of stack manipulation words such as dup, drop, over, swap. Such need not be the case when generator, modifier, and consumer words are used together correctly. Combine this with liberal usage of scoped variables and the resulting code can be truly elegant.