6.5 Evaluation

nip2 calculates the value of an expression by using the definitions you entered to successively reduce the expression until it becomes one of the base types. Sometimes there is a choice as to which part of the expression will be reduced next — nip2 will always choose to reduce the leftmost, outermost part of the expression first.

For example, consider this definition:

factorial n  
  = n ⋆ factorial (n - 1), n > 1  
  = 1

And here’s how nip2 will evaluate the expression factorial 3:

factorial 3 -->  
  3 > 1 -->  
  true  
3 ⋆ factorial (3 - 1) -->  
  (3 - 1) > 1 -->  
  2 > 1 -->  
  true  
3 ⋆ (2 ⋆ factorial (2 - 1)) -->  
  (2 - 1) > 1 -->  
  1 > 1 -->  
  false  
3 ⋆ (2 ⋆ 1) -->  
3 ⋆ 2 -->  
6

Note how nip2 delays evaluating parameters to functions until they are needed, but still shares the result. 3 - 1 is only evaluated once, for example, even though the result is used three times. nip2 has a trace window: click on Debug / Trace in the program window and check the View / Operators menu item.

The advantage of this style of computation over conventional imperative programming languages is that you can reason about your program mathematically1 .

This isn’t the best way to write a factorial function. A function with lots of recursive calls can be hard to understand — it’s much better to use one of the higher order functions from the standard environment to encapsulate the type of recursion you want to use.

The clearest definition for factorial is probably:

factorial n = product [1..n]

See §6.6.5 for an explanation of the list syntax.