Home
 Introduction
 Using Holon
 Holon Tools
 Contact


 Introduction

 Holon
 Forth
 Forth&C
    main
    power
    sercout

 

Forth versus C: The function power

Here is the K&R version of the function power

power(x,n)             /* raise x to the n-th power; n > 0 */
   int x,n;
   {
      int i,p;
      p = 1;
      for (i=1; i<=n; ++i)
          p = p * x;
      return(p);
   }

In Forth it can be written as

: power   ( x n -- p )   \ raise x to the n-th power; n > 0
     1 swap 0 do over * loop nip ;  

Stack comment

The functional argument of the C function has turned into a comment in Forth. The stack comment ( x n -- p ) indicates that the word takes two values from the stack and leaves one value, the result. The comment is ignored by the compiler; it belongs to the documentation of the program.

Stack handling

The simplicity of the stack comes at a price. It is not always easy to understand what happens on the stack. An experienced Forth programmer has no problems with the above definition of power, but there may be good reasons for writing the word with explicit stack diagrams as follows.

: power   ( x n -- p )   \ raise x to the n-th power; n > 0
     1 swap              \ -- x 1 n 
     0                   \ -- x 1 n 0  
     do                  \ -- x 1
        over             \ -- x 1 x
        *                \ -- x 1*x, finally: -- x x^n
     loop 
     nip                 \ -- x^n 
     ;

Personally, I prefer the first definition. In HolonForth you can debug/test the definition step-by-step running through the source text. At every step the stack window displays the new contents of the stack, and you see whether the word performs as planned. 

There are no strict rules, this belongs to the art of Forth programming. A word definition is good, if it is clear. If a word is not clear, sometimes stack comments help. Sometimes, however, the word should be redefined (it should probably be divided into parts) until the action is evident.

No local variables

C uses local variables as arguments for the function call, both in the calling and in the called function.

In main

int i;
power(2,i)

In power :

power(x,n)        
   int x,n;

In Forth we simply push the data on the stack ( 2 i power ) and avoid extra variables. The stack acts as a notepad. We do not need local variables, in principle. But it is possible to add local variables to a Forth system. See HolonJ, where locals are supported by the Java interpreter, and make sense.

Operational notation (Postfix)

The data stack leads naturally to a operational notation, also known as postfix or Reverse Polish Notation (RPN). 

p * x    becomes   p x * 

The multiplication operator * is just another word in Forth. The word * pops two values from the stack, calculates the product and pushes the result back on the stack. Thus the Forth notation describes the actual sequence of operations that is needed to perform a multiplication: pick the arguments and apply the * operator.

Programmers, who have been used to normal arithmetic expressions since the first days in school, need a short while to grow accustomed to postfix notation. It doesn't take long, usually. 

Postfix makes programming simpler. If you write mathematical expressions in postfix, you can forget about precedence rules and parentheses. Postfix expressions do not need extra rules. Example: 

In the expression 2+3 the result is clear. But what is 2+3*4 ?  Unless we (and the compiler) know that the operator * has precedence over +, this expression is multivalent. In postfix it is either 2 3 + 4 * or  3 4 * 2 + .

The computer can handle postfix directly. If you prefer to write normal arithmetic (infix) expressions, you need a program that translates your expressions into notation that the machine understands. The C compiler does this, among other things, and some compilers convert your code into postfix.  The Forth compiler is extremely simple and clear, because it is not burdened with (in our opinion) unnecessary  tasks.

Unlimited number of return values

Forth words need no return() statement. The result is simply stored on the stack. Therefore a Forth word is not limited to one return value.

more