(* non tail recursive *)
fun sum xs =
   case xs of
       [] => 0
     | x::xs' => x + sum xs'

fun sumtailrecursive xs =
    let fun aux(xs,acc) =
        case xs of
             [] => acc
           | x::xs' => aux(xs', x + acc)
    in
        aux(xs,0)
    end

(* whenever recursive operations are commutative we can use this approach
   of defining an auxiliary function which takes an extra accumulator parameter
   e.g. for summing or multiplying because
   3 * 4 == 4 * 3
   3 + 5 == 5 + 3
*)

(* non tail recursive *)
fun reverse xs =
    case xs of
        [] => []
      | x::xs' => (reverse xs') @ [x]


(* tail recursive *)
fun reverse xs =
    let fun aux(xs, acc) = 
        case xs of
            [] => acc
          | x::xs' => aux(xs', x::acc)
    in 
        aux(xs,[])
    end