Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Ocaml "in" keyword and usage

I'm reading some notes and came across this code which looks quite clean for me:

# let sigma f m =
  let rec sum (i, z) =
  if i = m then z else sum(i+1, z+.f i)
  in sum(0, 0.0);;
val sigma : (int -> float) -> int -> float = <fun>
# sigma (function k -> float (k*k)) 10;;
- : float = 285.

I understand every bit except the part where there's in sum(0, 0.0). Well the problem is not actually about the in keyword but this: sum(0, 0.0). What is that supposed to mean and why is it useful for this function to work? I did some googling and got something on the in keyword from the Ocaml site but this makes no sense to me. This is what I found:

class-expr  ::= class-path  
    ∣     [ typexpr  {, typexpr} ]  class-path  
    ∣     ( class-expr )  
    ∣     ( class-expr :  class-type )  
    ∣     class-expr  {argument}+  
    ∣     fun {parameter}+ ->  class-expr  
    ∣     let [rec] let-binding  {and let-binding} in  class-expr  
    ∣     object class-body end  

I don't need an explanation of the actual function. What I need help with is that tiny in sum(0, 0.0).

like image 399
emi Avatar asked Oct 27 '13 20:10

emi


1 Answers

It is let bindings in body ; your inis related to let rec sum

so the internal

let rec sum (i, z) =
if i = m then z else sum(i+1, z+.f i)
in sum(0, 0.0);;

is an internal tail recursive function to make a loop, the result of sum(0,0.0) (with that internal sumdefinition) is the result of sigma function.

The sum(0,0.0) is the starting point of the tail recursion.

I suggest you to use Ocaml's debugger, or at least to add a

 Printf.printf "sum i=%d z=%f\n";

line just after the let rec sum(i,z) = line.

BTW, you should code instead a sum with two arguments, not with a single argument happenning to be a couple:

let rec sum i  z =
if i = m then z else sum(i+1) (z+.f i)
in sum 0 0.0;;

BTW, I would loop with decreasing i and code instead

let sigma f m = 
  let rec sumloop i s = 
     (* Printf.printf "sumloop i=%d s=%f\n" i s ; *)
     if (i <= 0) then s
     else sumloop (i-1) (s+.f i)
  in sumloop m 0.0 ;;

I agree that my sigma function is slightly different (in particular if the argument f is an impure function with side-effects). I named the internal tail-recursive function sumloop (not just sum) to emphasize that it is a loop.

Your z formal to sum and my s formal to sumloop is an accumulating partial sum.

like image 127
Basile Starynkevitch Avatar answered Nov 13 '22 18:11

Basile Starynkevitch