1

I have this factorial function that is currently working, but the result I'm having is not the one I need.

The code is:

declare
fun {Fact N}
if N==1 then [N]
  else
    Out={Fact N-1}in
     N*Out.1|Out end
end
{Browse {Fact 4}}

The result is : [24,6,2,1] but I need that the result shows: [1,2,6,24] and I can't see where the error is.

hrbrmstr
  • 77,368
  • 11
  • 139
  • 205
Anita
  • 43
  • 5

1 Answers1

3

You want to decrement N, having no other argument than N.
But there is a problem:

  • a list [1 2 6 24] can actually be written as '|'(1 '|'(2 '|'(6 '|'(24 nil)))) in oz
    so at the first or last call, your function has to return 24|nil...
    However, your function can not know if one call is the first call or the last, as you don't have any parameter.
  • your function is not tail recursive (if you use a book to learn oz, you'll discover why, and why it's bad)

Here is the best function I can think of:

declare
fun {Fact N}
   fun{Aux N Nmax FactNminus1}
      if N>Nmax then nil
      else (FactNminus1*N)|{Aux N+1 Nmax FactNminus1*N}
      end
   end
in
   {Aux 1 N 1}
end
{Browse {Fact 4}}
  • N is increment until Nmax
  • FactNminus1 contain the {Fact N-1} so you don't have to compute it each time.
yakoudbz
  • 903
  • 1
  • 6
  • 14
  • Thanks!! your explanation was very useful to see that I was not creating a tail recursive function, and I'm taking a look to one book to learn more about oz. – Anita Apr 02 '14 at 20:55