Some programming languages, especially C, have header files with function declarations. These headers come before the code and are required for situations with mutual recursion. When function headers are placed in the header file, they also help link situations where multiple C files are compiled together.
My understanding of function headers in a C file is that they help with compilation, because they determine the function input if it is called before it is defined. If this is not so, I would be happy if I were corrected and better informed, but this is my understanding.
So I don’t understand why other languages - in this case I highlight OCaml - do not have function headers. There are modules with signatures in OCaml, but the signature does not allow your function instances to be mutually recursive, even if specified. To have mutual recursion in OCaml, you need to use either the "and" keyword or define one function locally inside another function (as far as I know).
(* version 1 *) let rec firstfun = function | 0 -> 1 | x -> secondfun (x - 1) and secondfun = function | 0 -> 1 | x -> firstfun x (* version 2 *) let rec firstfun = function | 0 -> 1 | x -> let rec secondfun = function |0 -> 1 | x -> firstfun x in secondfun (x - 1)
So why is that so? Is this related to polymorphism? Is there a compilation bottleneck that I am not considering?
, , . , , . , C , , , C .
, , , , C, (, , - ), , .
OCaml, , C- C- . , .
? , , . - ( ) (.. ), OCecl typechecker . , typechecker . , , OCaml, , typechecker .
, , OCaml, . , , , Obj external. , . , , C.
external
, , , , (.. ), .
-, , , , C . . C /. OCaml C.
: . ( .) - . , OCaml. :
(* version 1 *) let rec firstfun = function 0 -> 1 | x -> secondfun (x - 1) and secondfun = function 0 -> 1 | x -> firstfun x
, , ( , First_module ):
First_module
module First_module = struct let rec firstfun secondfun = function 0 -> 1 | x -> secondfun (x - 1) end module Second_module = struct let rec secondfun = function 0 -> 1 | x -> First_module.firstfun secondfun x end
, First_module.firstfun int -> int, , (int -> int) -> int -> int. , secondfun. , ( ) ( ( , .)).
First_module.firstfun
int -> int
(int -> int) -> int -> int
secondfun
( : rec firstfun . .)
rec
firstfun
EDIT:
:
, , OCaml let-and notation , , .
, (: 4.02 .) :
module rec All : sig val firstfun : int -> int val secondfun : int -> int end = struct let firstfun = function 0 -> 1 | x -> All.secondfun (x - 1) let secondfun = function 0 -> 1 | x -> All.firstfun x end include All
, , : C OCaml - . -.
Ocaml .mli, .h C ++. §2.5. Ocaml. .cmi . ( C GCC ).
.mli
.h
.cmi
, ++ - . ++ (, <map>) . Linux- GCC6 , #include <vector>, ( , ++ ).
<map>
#include <vector>
++ , . , , , . Clang Modules.
- (Ada, Go, D,...)
C ( C ) ++.
Ocaml ( ) let rec ,
let rec
let rec foo x y = (* many lines *) ..... and bar z t = (* many lines *) .... and freezbee u v w = (* many lines *) .... (**** the above let rec definition can span many thousand lines *)
- Ocaml, , , -, :
let refoo = ref (fun (x : int) -> failwith "refun unitialized");;
!refoo y ( foo y....), , refoo . IIRC Ocaml.
!refoo y
foo y
refoo