"let rec" not needed for recursion in toplevel?

Hi all,

I’m learning OCaml, and was doing some code golfing for practice (link). I was working in utop, and I noticed that it didn’t require “let rec” for recursive function definitions:

utop # let d a b=if a mod b=0 then 1+d(a/b)b else 0
let r s i=if i=0 then""else s^(r s(i-1))
let f n=String.concat"\n"(List.init n(fun x->let y=x+1 in if(y mod 3)*(y mod 5)>0 then string_of_int y else(r"Fizz"(d y 3))^(r"Buzz"(d y 5))));;
val d : int -> int -> int = <fun>
val r : string -> int -> string = <fun>
val f : int -> string = <fun>

But when I tried the same code in a file, it didn’t work:

File "./test.ml", line 1, characters 30-31:
1 | let d a b=if a mod b=0 then 1+d(a/b)b else 0
                                  ^
Error: Unbound value d
Hint: If this is a recursive definition,
you should add the 'rec' keyword on line 1

I was wondering why the rec is necessary in the file, but not in utop? I couldn’t find any information online.
Thanks!

Just figured it out. It worked because I was redefining the functions in the repl, not defining them from scratch, so it was just using previous definitions. Not recursive.