Это может быть поучительно:
let Main() =
let f(x) =
printfn "original f: %d" x
let f(x) =
//let rec f(x) =
printfn "entered new f: %d" x
if x > 0 then
f(x-1)
else
printfn "done"
f(3)
Main()
Это печатает
entered new f: 3
original f: 2
Теперь, если мы закомментируем let
и раскомментируем let rec
, будет напечатано
entered new f: 3
entered new f: 2
entered new f: 1
entered new f: 0
done
Так что с этой точки зрения речь идет только о привязке имени; let rec
немедленно помещает идентификатор в область (в этом примере, затеняя предыдущий f
), тогда как let
помещает идентификатор в область только после определения его тела.
Мотивация правила вытекает из взаимодействия с выводом типа.