0

The following factorial function is well and good...

Poly/ML 5.8.3 Development (Git version v5.8.2-297-g8185978a)
> fun fact 0 = 1
# | fact n = n * fact(n-1);
val fact = fn: int -> int
> fact 2;
val it = 2: int
>

But the following takes the Poly REPL into infinite loop.

Poly/ML 5.8.3 Development (Git version v5.8.2-297-g8185978a)
> fun fact 0 = 1
# | fact n = n * fact n-1;
val fact = fn: int -> int
> fact 2;

Wondering what could be causing this??

Nalin Ranjan
  • 1,728
  • 2
  • 9
  • 10

2 Answers2

3

n * fact n-1 is the same as n * (fact n) - 1 - thus, n is never decreased, and your code ends up calling fact 2 over and over and over again.

ForceBru
  • 43,482
  • 10
  • 63
  • 98
  • 1
    To elaborate, function application has a higher precedence than other operators. This is often useful. Consider writing a condition `if fact 2 < face 5 then ...`. This is much nicer than `if (fact 2) < (fact 5) then ...`. But it does mean a few extra parentheses in your case to make sure the subtraction happens before the function application. – Chris Jul 02 '21 at 21:12
  • Apologies... Not sure how I overlooked comments from you guys.. – Nalin Ranjan Jul 03 '21 at 07:02
  • 1
    It happens. Just means A. you figured it out, and B. you got a nice confirmation. Good work. – Chris Jul 03 '21 at 19:08
2

Since ForceBru already gave an adequate answer, for completion, here is an example of evaluating this by hand that should reveal the infinite recursion:

fact 2 ~> 2 * fact 2-1
       ~> 2 * (2 * fact 2-1)-1
       ~> 2 * (2 * (2 * fact 2-1)-1)-1
       ~> 2 * (2 * (2 * (2 * fact 2-1)-1)-1)-1
       ~> ...
sshine
  • 15,635
  • 1
  • 41
  • 66